Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play! framework, single Jetty instance, deploy multiple projects, share libs

I'm trying to deploy two or more independent Play! (1.2.4) based projects to the same Jetty instance.

According to this post it apparently is possible to extract the common lib's from each PrjName.war/WEB-INF/lib directory and place them into a shared lib directory i.e. jetty/lib/ext.

We have a large number of smaller independent projects that we would like to implement using Play! but all need to be deployed in the same Jetty instance sharing all the libs to reduce RAM usage. Is my assumption correct that several projects sharing the same lib's will reduce the overall memory footprint?

My attempts putting all the libs in a shared location i.e. jetty/lib/ext worked for a single project but deploying the second project fails and breaks the first one.

It appears to be an issue with conflicting EhCache instances.

Here is the jetty log:

...
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
       at java.lang.reflect.Method.invoke(Unknown Source)
       at org.eclipse.jetty.start.Main.invokeMain(Main.java:469)
       at org.eclipse.jetty.start.Main.start(Main.java:612)
       at org.eclipse.jetty.start.Main.parseCommandLine(Main.java:265)
       at org.eclipse.jetty.start.Main.main(Main.java:79)
Caused by: net.sf.ehcache.ObjectExistsException: Cache play already
exists
       at net.sf.ehcache.CacheManager.addCache(CacheManager.java:859)
       at play.cache.EhCacheImpl.<init>(EhCacheImpl.java:32)
       at play.cache.EhCacheImpl.newInstance(EhCacheImpl.java:41)
       at play.cache.Cache.init(Cache.java:241)
       at play.Play.start(Play.java:511)
       ... 42 more

Any help is greatly appreciated.

like image 642
Tino Avatar asked Dec 20 '11 23:12

Tino


1 Answers

When you use shared jars, Jetty will use the System's Classloader to load classes inside the shared jars. And, since Play EhCacheImpl is (almost) a singleton, the second application to start will influence the first and vice versa. That is the exception you are getting now: Play is trying to instance two caches, in the same classloaders, with the same name. I can think about the following solutions:

  1. Fix Playframework so that it can handle this situation
  2. Use your own cache implementation (not sure if this is the only thing that prevents your both applications to work together)
  3. Use a common setup and replicate jars for each application.

The option 3 sounds better to me, since you don't have to chance the framework and it is also more secure regarding regression bugs. About the memory footprint, you can use visualvm to validate if the memory consumption is significantly different to justify shared jars.

like image 106
marcospereira Avatar answered Oct 04 '22 12:10

marcospereira