I'm working on a project where we need to build several 'standalone' modules connecting to one database. These modules are mainly background business processes, so not much frontend. Except for one web module showing the data and allowing basic CRUD functions. For this we are planning to use the following techniques:

JPA2 (using hibernate-jpa implementation)

CDI (using spring implementation)

JSF2 + primefaces (for our web module)

The initial plan was to just create a jar file (with a main method) per module and install it as a (windows) service via a service wrapper. For our web module we would use Glassfish or JBoss to run it. However, lately Java EE came to our minds. We could run all our modules in a Java EE container like Glassfish or JBoss, not only our web module. Some questions for the case that we go for Java EE:

Can / should we still use CDI with spring? Or should we switch to EJB3?

What are the consequences for JPA when we use it from within a container instead of standalone modules? Is there any difference?

Since most of our modules are not web related does it still make sense to run them in a Java EE container?

3 Answers
3

Others have pointed out some of the pros, so here are some cons if you deploy the background process into the same jvm as your web app.

Starting and stopping the server running the web module means you start and stop the background processes, this may or may not be a problem for you.

You are sharing the heap with all the three applications if the background processes consume a lot of memory or cpu then that might impact your web app or if the web app consumes a lot of resources it might impact the background processes.

The web app might need to be deployed in way that is accessible over the internet but the background processes might be happy to run without any access to the net. So why expose the background processes to the internet if you don't have to.

When you upgrade the app server, or frameworks, or configuration it means three things to test, if the background processes are running on their own you can upgrade them on a separate release cycle from the web app.

It is simpler to develop and test code outside the container. Running your background processes inside the container means a more complex development environment for the background processes, you have to wait for the server to start, you start depending on in container resources that you then have to mock form unit tests ... etc.

JPA is the same inside and outside the container. The only difference is how you obtain an EntityManager, this can be configured with Spring to be the same both in and out of the container. CDI should be runnable outside the container.

Major areas of difference will be how you do transactions with the db for example using Spring transactions vs. ejb transactions.

Update:
To answer your question form the comment: in JPA the EntityManager is not thread safe so in a Java EE server there will be one entity manager per persistence unit per thread. The Entity manager creation and closure is managed by the app server for you. Every entity manager has a cache within it. It is possible to configure a second level cache that spans multiple entity managers. In running outside the container you will have to manage the number of JPA entity managers yourself, this will depend on the number of threads in your background process and transaction boundaries that you want to have. If you look at a book called "Pro JPA2" there is a section that talks about the details of running inside or outside the container.

In my application I don't have a background process but every class that needs an entity manager just gets it injected using @PersistenceContext EntityManager em; and spring takes care of making it all work inside and outside the container. Spring 3.1 has a feature called profiles that makes it trivial to have the same code run inside our outside a container without changing a single line of code. I am not a CDI user so I don't know if CDI has an equivalent of the spring 3.1 profiles feature.

Thanks for showing me the cons as well! About the entitymanager, with JEE, wouldn't we have only 1 instance as opposed to standalone where we would have 1 instance per JVM (/module)? Would this have influence on hibernate caching?
–
Robe ElckersNov 28 '12 at 7:41

just in case somebody takes this seriously, note that almost all the cons disappear if you simply use two different containers, one for batch one for web. in fact, use one container for each of the things. the pros of having a uniform standard container with CDI, JPA what not are enormous. as for development productivity eclipse can provide similar turnaround with java ee containers too. the only modification needed would be to turn off the http listeners for the batch container. just say no to spring or anything non-standard -- java ee 7 has been approved and you get a whole bunch of goodies.
–
necromancerMay 9 '13 at 7:08

@RobeEleckers additionally a container is essentially a jvm so if you simply turn off the network listeners you are running a batch java process.
–
necromancerMay 9 '13 at 7:10

is it possible to use CDI in a standalone java app?
–
amphibientNov 27 '12 at 16:27

you haven't really explained why it "does make sense to bundle together batch and real time aspects of a single product as long as you doesn't see any performance issues", i.e. what the benefits are associated with the additional level of complexity of running it within an app server as opposed to standalone.
–
amphibientNov 27 '12 at 16:31

@foampile Related modules often depend on the same set of core modules. So it makes sense to bundle them together. I am not sure what the complexity in running in an appserver? MDB's are meant for async processing and they run in the context of appserver.
–
PangeaNov 27 '12 at 16:37

@foampile Yes CDI can be used in standalone app. Look at Weld's documentation on how.
–
PangeaNov 27 '12 at 16:37

that is true, however, i find more virtue in striving towards SOA and component-based model that can be used from diverse platforms rather than tightly coupling seemingly separate-able modules. just my $0.02. i think your position does make sense, however it may discourage separation of modules
–
amphibientNov 27 '12 at 16:43

It makes sense to run in a application server rather than a standalone java program for the common reasons such as

1) You can use CDI with spring since EJB3 is also based on similar concept.
2) There is no difference as far as JPA is concerned except that if you need to add more volume to the application later, load can be added via adding more machines which run the same application - However, do note that this is a non-trivial amount of work and hence it depends on the business requirement to make the choice
3) Application servers win over standalone apps for the reasons of inbuilt security, reliability, management and scalability over standalone java apps.