7

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.

Tino
  • 325
  • 1
  • 8

1 Answers1

1

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.

marcospereira
  • 12,045
  • 3
  • 46
  • 52