We have been building two suites of applications for the last 10 years using Spring as our dependency injection. We also use spring-batch and spring-amqp. We are now looking to move to OSGI so that our monolithic applications can be separated into bundles so that we can be more agile. The two suites are web applications and are deployed as two separate war files. We are looking to use Apache Karaf as our OSGI runtime.
Spring-DM is dead and it appears that we are going to have to convert EVERYTHING to use Blueprint for our dependency injection.
My question is how do we do this incrementally? It will be close to impossible to convert all of this over at once. It seems like one bundle should still be able to use Spring DI and have it's own application context as long as we take the responsibility to expose any services that we want to the service registry in the bundle activator, but I'm not sure if there is some kind of magic that we would lose like transaction management.
Any guidance on this would be really appreciated.
You might want to consider to make the problem appear even larger and switch to DS instead of Blueprint ... To take truly advantage of the OSGi model, DS is far superior to Blueprint in all aspects. In reality, after the first hurdle, you'll make much more progress and your gains will be higher. Though Blueprint made Spring available on OSGi, it never 'got' OSGi.
For strategy, keep your Spring app alive as a single bundle and move things out gradually. I.e. the elephant approach.
The biggest gain that OSGi provides can be summarized as follows:
Make sure modules have service APIs that ONLY handle collaboration. I.e. each service API should be a story/scenario how the actors work together, not how they come into existence and are configured.
Let Configuration Admin to the configuration work. I.e. never expose configuration APIs. In OSGi, you register instances, not things that still need to be configured.
Make sure you really understand the OSGi model with services. You might want to take a look at OSGi enRoute that leverages OSGi to the hilt.
I propose you take a look at the blueprint-maven-plugin. It allows to use a subset of CDI and JEE annoations to define injections as well as transactions and persistence. The plugin creates blueprint xml at build time which can then be executed by karaf. The big advantage is that these annotations are also supported by spring. So you can transition and in parallel release to production using spring.
I have a complete example here Annotation based blueprint and JPA.
Using this plugin I migrated a medium sized project while it was developed and released in parallel. If you need further advice while using the plugin I can surely help.
Related
My project has requirement to deploy a Java Based application as an operating system Job (and not use any container). The application need to have following capabilities:-
Scheduling
Few HTTPS based services
Ability to make JMX calls
Storage: Data for last 5 to 10 minutes of transactions (not more than 600 rows X 20 columns). Something like embedded H2 or in-memory options
Decision Tree: Something like Drools..
My manager wants to write this application as a core Java with OSGized Jetty version. I am suggesting to use Spring Boot with embedded Jetty(which will give me ready to use capabilities for Scheduling, JMX Integration and REST Services).
His bend towards core Java is emerging from the requirement that this application needs to be extremely efficient, fast and self-contained. He wants to reduce dependency on any open source. I have never worked directly on OSGI but have used products coming out of it - like eclipse.
Can somebody guide how OSGI based development might benefit over SpringBoot?
For many people, OSGi is superfluous, because they don't see the value in being modular. Not being worth the trouble.
Think about the application lifecycle, more or less being plan-develop-test-deploy.
How many developers you have? If many, OSGi helps a lot, because being modular make the boundaries very clear. You can delegate things very easily.
If outsourcing is your thing, you can just handle the module APIs and tell them to develop against it. They will never know how the rest was implemented, no fear of secrets being leaked.
Unit tests are so easy. You obviously see what you can test, every else you mock/stub/spy/fake. Unit tests can be can be reused in Integration tests, of course that isn't news, but the trick is running Unit tests outside the OSGi container, and Integration tests inside. So if you decide OSGi was not worth it, your code stills works fine (unit tests being the proof).
You can make your app a collection of modules, and every module having independent versioning and source repositories. Makes easier to handle and find bugs. For example, the current app crashed, you find out that sub-module-1.2 is throwing errors, try with version sub-module-1.1(still bad), then version 1.0(good), bug was introduced in 1.1 (avoids bisecting the source code). Programmers don't need to be perfectly synchronized with each other if they are working in different modules.
How do you plan to update the app? Most frameworks are of the all-or-nothing approach, where you have to stop the world, update, then restart the app. If you make things modular, you just need to update that thing. Making the downtime very small, and sometimes even zero.
If you need to make a big change in your app, but can't afford to refactor everything right now. With OSGi you can run the system with both my-module-1.0 and my-module-2.0. You can even adapt my-module-1.0 to redirect calls to my-module-2.0, but that is a kind of last resort hack (just saying that you can, if you want to).
I can do everything you say without OSGi, right? Well, probably you can, but in the end, would be something like OSGi.
I love the Dependency Injection of my framework. No problem, OSGi have something like that.
I hate Dependency Injection, it kills my app perfomance. No problem, you can use something like osgi.getService(MyService.class);. The OSGi container isn't concerned about intercepting every call of your app.
OSGi is like Java++, Java plus modules.
You can mix Spring Boot with OSGi, can't say if this is good or bad. There are many libraries and frameworks that fit your list, many will work out-of-the-box with OSGi.
I am new to OSGi and am using Equinox "Virgo Tomcat Server" (VTS) along with eclipse blueprint, and got big assignment to do in limited time
There is application already developed in J2EE Style
By using JSP->Struts2->Spring->MySQL and SOAP Web Services.
-There are various layer in the existing architecture
Simple Request flow is as mention below
From UI layer->it goes to strus2 configration-> it goes to Spring Configuration->From Spring configuration xml (that is module wise application context xml) Struts Action class is called -From Struts Action class layer -> it goes to Task layer->handler layer->Service Layer -> Adapter or DAO layer ->DB in some cases from service layer call also goes to WebService layer and communicate with Back-end legacy system
My Queries are as Follows
Q1] From UI/JSP to up-to strtus2 action layer code for every module should be club together in to a single .war file say "onlinebank.war" and from struts2 action onwords module wise code in every layer should go in to Module wise OSGi bundles
For e.g. if there are 10 modules there should be 10 osgi bundles
And each module wise bundle should contain module specific code from every layer after action layer and there should be communication between one war "onlinebank.war" and 10 osgi bundles
Q2]To take Q1 to next level
If there are 10 modules then instead of crunching module specific code in one OSGi bundle,
I have to create 3 bundles for each module(XXXAPI,XXXMain,XXXConfig)
for e.g. TestModule
I] TestModuleAPI (will contain only interfaces and abstract classes)
II] TestModuleMain (will contain implementation of interfaces and abstract classes and will provide some default functionality)
III]TestModuleConfig (will be accessing the default functionality of Main Bundle Via API Bundle and also provide some customize/new functionality)
So if there are 10 Module and 3 OSGi Bundles for each module (API,Main,Config) then for 10 bundles there should be 3*10=30 bundles and there should be proper communication between -single war "onlinebank.war" and the 30 bundles
Also there should be proper communication among 30 bundles it self to resolve the dependencies and works together properly/synchronously
Any help will be greatly appreciated
Regards,
Gokul
This is a big task you are tackling. I did such a migration and am quite familiar with OSGi. Still it took about 2 months. So you should first not underestimate the problems you will be facing.
The next thing is that a typical spring application is not well modularized. As there are no private/public packages in JSE developers tend to ignore module boundaries. The modules often also do not have a clean and small API at all so people known what they should access and what not.
So I think your first task is to refactor the application so each bundle offers a minimal API and other modules only access the API. For this task it might make sense to use an architecture tool that allows to define and control these accesses. While still in spring you create beans from a service interface from the API. Later in OSGi the API will allow to define clean OSGi services. If you skip this step then OSGi will not have big advantages. OSGi only works well if the application is strictly modularized.
Then for the actual OSGi migration I can only urge you to hire some specialist to help you. It will be a waste of time and resources if you do this alone.
spring-boot uses "starters" to define a set of libraries dependencies a project may include. This maven module, a starter for Jersey, for example:
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-starters/spring-boot-starter-jersey
spring-boot uses autoconfigures to instantiate and configure the classes in the starter module. The autoconfigure for Jersey:
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfiguration.java
Is there any reason not to co-locate new 3rd party/private starters in the same module as the autoconfigures, instead of split across separate modules like the example above?
It's a good question, and one that we have debated inconclusively in the Spring Boot engineering team, so there is no correct answer. Relevant points for discussion:
spring-boot-autoconfigure started out as quite a small library (pre 1.0). It has grown now to the extent that its pom is kind of ridiculously long (and nearly everything is optional).
Starters perform more than one function, in the sense that they can be used to activate bits of autoconfiguration, but also (and more importantly)
, they are an opinionated, curated set of dependencies that might (and usually does) go beyond the minimum needed to activate some autoconfiguration. This is basically Marten's point.
Spring Boot .NEXT (1.3 at the point) will more than likely unbundle spring-boot-autoconfigure into multiple modules (e.g. there might be one for jetty, or maybe one for servlet containers, or something esle).
When the unbundling happens we might see some starters becoming obsolete (who knows at this point), but I suspect they will still exist. Spring Cloud has a lot of unbundled autoconfiguration, but still has starters, for instance.
For small third party libraries I see no reason why starters and autoconfiguration shouldn't be co-located. I think the only justification for allowing this thread on stackoverflow is if it can be re-worded to make the question more obviously about that.
Am a total beginner with spring framework and trying to know if it even fits my use case, before investing time learning it.
I'm responsible for a stand alone java project(used as a jar by a server) which basically serves requests from a server, and in turn makes service calls to various internal services.
This standalone java project, currently has all of its service calls hard coded. I want to use Spring to inject dependencies so I can make this stuff testable.
I have no idea how spring works. Does it even hold for standalone jars or is it only for 'running applications'?
If I make my standalone project 'spring enabled', when the server uses my jar, will it automagically work by creating beans or is there some requirement from the server side?
In short, yes, you can use Spring in a standalone jar-application ("console application", if you will), we do it all the time at work. You just need to create the ApplicationContext yourself when your application starts, see for example here: http://www.devdaily.com/blog/post/java/load-spring-application-context-file-java-swing-application
This is just one example I pulled straight out of Google, there are probably numerous others. Still, you really need to read at least the basics from the Spring documentation to get started, otherwise you'll probably hit a wall pretty soon.
I've been reading/learning more about Spring lately, and how one would use Spring in combination with other open-source tools like Tomcat and Hibernate. I'm evaluating whether or not Spring MVC could be a possible replacement technology for the project I work on, which uses WebLogic and a LOT of custom-rolled Java EE code. The thing is, I've always suspected that our solution is over-engineered and WAY more complex than it needs to be. Amazingly, it's 2009, and yet, we're writing our own transaction-handling and thread-pooling classes. And it's not like we're Amazon, eBay, or Google, if you know what I mean. Thus, I'm investigating a "simpler is better" option.
So here's my question: I'd like to hear opinions on how you make the decision that a full-blown Java EE application server is necessary, or not. How do you "measure" the size/load/demand on a Java EE app? Number of concurrent users? Total daily transactions? How "heavy" does an app need to get before you throw up your hands in surrender and say, "OK, Tomcat just isn't cutting it, we need JBoss/WebLogic/WebSphere"?
I don't think that the decision to use a full-fledged Java EE server or not should be based on number of users or transactions. Rather it should be based on whether you need the functionality.
In my current project we're actually moving away from JBoss to vanilla Tomcat because we realized we weren't using any of the Java EE functionality beyond basic servlets anyway. We are, however, using Spring. Between Spring's basic object management, transaction handling and JDBC capabilities, we aren't seeing a compelling need for EJB. We currently use Struts 2 rather than Spring's MVC, but I've heard great things about that. At any rate, Spring integrates well with a number of Java web frameworks.
Spring does not attempt to replace certain advanced parts of the JavaEE spec, such as JMS and JTA. Instead, it builds on those, making them consistent with the "Spring way", and generally making them easier to use.
If your application requires the power of the likes of JMS and JTA, then you can easily use them via Spring. Not a problem with that.
Google open sources a lot of their code. If you're writing low-level things yourself, instead of implementing code that's already written, you're often overthinking the problem.
Back to the actual question, Walmart.com, etrade.com, The Weather Channel and quite a few others just use Tomcat. Marketing and sales guys from IBM would have you believe different, perhaps, but there's no upper limit on Tomcat.
Except for EJB, I'm not sure what Tomcat is missing, and I'm not a fan of EJB.
What tomcat does not offer apart from the more exotic elements of Java EE is session beans (aka EJBs). Session beans allow you to isolate your processing efficiently. So you could have one box for the front end, another for the session beans (business logic) and another for the database.
You would want to do this for at least 2 reasons:
Performance; You're finding that one box to handle everything is loading the box too much. Separating the different layers onto different boxes would allow you to scale out. Session beans are also able to load balance at a more fine grained level. Tomcat and other web services of that ilk don't have clustering out of the box.
Flexibility; Now that you've moved your business logic into its own environment you could develop an alternate front end which used the same layer, but say, was a thick client front end for example. Or maybe other contexts would like to make use of the session beans.
Though I should probably point out that if you use web services to communicate with that middle tier, it could also be on tomcat!
The only reason to use a full blown Java EE server is if you need distributed XA transactions, if you don't need XA transactions then you can use Spring + JPA + Tomcat + Bean Validation + JSTL + EL + JSP + Java Mail.
Also a Java EE server is supposed to implement JMS but it does not make sense to run the JMS server in the same VM as the rest of the app server so if you need JMS you should have a separate JMS server.
I strongly disagree with all answers given here.
Everything can be added to Tomcat, including EJB, CDI, JTA, Bean Validation, JAX-RS, etc.
The question is: do you want this? Do you want to assemble all those dependencies in the right versions and test that it all works together, when others have already done this?
Let's be clear: nobody uses only Tomcat! Everyone always adds a web framework, an ioc container, an orm, a transaction manager, web services, etc etc
Lightweight Java EE servers like TomEE already include all of that and makes the full stack experience of having all those things integrated so much better.
Maybe this can be of interest:
http://onjava.com/onjava/2006/02/08/j2ee-without-application-server.html
HTH