What's the best way to share business object instances between Java web apps using JBoss and Spring?

天大地大妈咪最大 提交于 2019-11-30 11:36:55
Will Hartung

Are the web applications deployed on the same server?

I can't speak for Spring, but it is straightforward to move your business logic in to the EJB tier using Session Beans.

The application organization is straight forward. The Logic goes in to Session Beans, and these Session Beans are bundled within a single jar as an Java EE artifact with a ejb-jar.xml file (in EJB3, this will likely be practically empty).

Then bundle you Entity classes in to a seperate jar file.

Next, you will build each web app in to their own WAR file.

Finally, all of the jars and the wars are bundled in to a Java EE EAR, with the associated application.xml file (again, this will likely be quite minimal, simply enumerating the jars in the EAR).

This EAR is deployed wholesale to the app server.

Each WAR is effectively independent -- their own sessions, there own context paths, etc. But they share the common EJB back end, so you have only a single 2nd level cache.

You also use local references and calling semantic to talk to the EJBs since they're in the same server. No need for remote calls here.

I think this solves quite well the issue you're having, and its is quite straightforward in Java EE 5 with EJB 3.

Also, you can still use Spring for much of your work, as I understand, but I'm not a Spring person so I can not speak to the details.

What about spring parentContext? Check out this article:

http://springtips.blogspot.com/2007/06/using-shared-parent-application-context.html

Terracotta might be a good fit here (disclosure: I am a developer for Terracotta). Terracotta transparently clusters Java objects at the JVM level, and integrates with both Spring and Hibernate. It is free and open source.

As you said, the problem of more than one client web app using an L2 cache is keeping those caches in synch. With Terracotta you can cluster a single Hibernate L2 cache. Each client node works with it's copy of that clustered cache, and Terracotta keeps it in synch. This link explains more.

As for your business objects, you can use Terracotta's Spring integration to cluster your beans - each web app can share clustered bean instances, and Terracotta keeps the clustered state in synch transparently.

Actually, if you want a lightweight solution and don't need transactions or clustering just use Spring support for RMI. It allows to expose Spring beans remotely using simple annotations in the latest versions. See http://static.springframework.org/spring/docs/2.0.x/reference/remoting.html.

You should take a look at the Terracotta Reference Web Application - Examinator. It has most of the components you are looking for - it's got Hibernate, JPA, and Spring with a MySQL backend.

It's been pre-tuned to scale up to 16 nodes, 20k concurrent users.

Check it out here: http://reference.terracotta.org/examinator

Thank you for your answers so far. We're still not quite there, but we have tried a few things now and see things more clearly. Here's a short update:

The solution which appears to be the most viable is EJB. However, this will require some amount of changes in our code, so we're not going to fully implement that solution right now. I'm almost surprised that we haven't been able to find some Spring feature to help us out here.

We have also tried the JNDI route, which ends with the need for stubs for all shared interfaces. This feels like a lot of hassle, considering that everything is on the same server anyway.

Yesterday, we had a small break through with JMX. Although JMX is definately not meant for this kind of use, we have proven that it can be done - with no code changes and a minimal amount of XML (a big Thank You to Spring for MBeanExporter and MBeanProxyFactoryBean). The major drawbacks to this method are performance and the fact that our domain classes must be shared through JBoss' server/lib folder. I.e., we have to remove some dependencies from our WARs and move them to server/lib, else we get ClassCastException when the business layer returns objects from our own domain model. I fully understand why this happens, but it is not ideal for what we're trying to achieve.

I thought it was time for a little update, because what appears to be the best solution will take some time to implement. I'll post our findings here once we've done that job.

Spring does have an integration point that might be of interest to you: EJB 3 injection nterceptor. This enables you to access spring beans from EJBs.

I'm not really sure what you are trying to solve; at the end of the day each jvm will either have replicated instances of the objects, or stubs representing objects existing on another (logical) server.

You could, setup a third 'business logic' server that has a remote api which your two web apps could call. The typical solution is to use EJB, but I think spring has remoting options built into its stack.

The other option is to use some form of shared cache architecture... which will synchronize object changes between the servers, but you still have two sets of instances.

Take a look at JBossCache. It allows you to easily share/replicate maps of data between mulitple JVM instances (same box or different). It is easy to use and has lots of wire level protocol options (TCP, UDP Multicast, etc.).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!