play2war / play2-war-plugin

WAR Plugin for Play framework 2.x
Apache License 2.0
443 stars 71 forks source link

Cannot override ehcache.xml when deploying with play2 war plugin #109

Closed ghost closed 11 years ago

ghost commented 11 years ago

Im moving this issue here from the Play issue tracker as they thought its was related to the war plugin.

I'm trying to override the ehcache.xml bundled inside play.jar in a Play 2 (2.0.4 java) app thats being deployed to JBoss 5 using the play2-war-plugin 0.8.1.

None of these methods to override the configuration works:

1) Deploy my own ehcache.xml in /conf. Someone in google groups reported this was working (in Play standalone I guess) but with 2 ehcache.xml on classpath I'm not having any luck with this on Jboss. Play consistently picks the one inside play.jar. Users will probably have mixed success depending on their classloader setup.

2) Use a servlet context listener that creates the CacheManager singleton instance before Play does thereby overriding the config file:

public void contextInitialized(ServletContextEvent servletContextEvent) {
  CacheManager.create(this.getClass().getResourceAsStream(
    "/my-ehcache.xml"));

3) Remove ehcache.xml from play.jar and add it to /conf.

4) Create a new plugin written in scala that extends the default ehcache plugin and override how the cache manager is created. I disabled the default cache and added my own plugin to /conf/play.plugins.

Solution 2, 3 and 4 initially works when I deploy to JBoss - it reads the "/conf/my-ehcache.xml" that I supplied instead of the ehcache.xml embedded in play.jar. However if I let the server stand idle for a few minutes and then hot deploy the app again then I get the stacktrace below on redeployment. If I make quick redeployments then the bug does not manifest itself. Once the bug manifests itself all subsequent hot redeployments fail with the same stacktrace but I can fix it by stopping the JBoss server, clean its temp folders (maybe not necessary), redeploy app and restart server.

I have tried the solutions using both play2-war-plugin 0.7.3 and 0.8.1.

Stacktrace for 2) 3) and 4):

ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/]] (HDScanner) Exception sending context initialized event to listener instance of class play.core.server.servlet25.Play2Servlet
java.lang.ExceptionInInitializerError
    at com.typesafe.config.impl.ConfigImpl.systemPropertiesAsConfigObject(ConfigImpl.java:365)
    at com.typesafe.config.impl.ConfigImpl.systemPropertiesAsConfig(ConfigImpl.java:373)
    at com.typesafe.config.ConfigFactory.systemProperties(ConfigFactory.java:366)
    at com.typesafe.config.ConfigFactory.defaultOverrides(ConfigFactory.java:319)
    at com.typesafe.config.ConfigFactory.load(ConfigFactory.java:161)
    at com.typesafe.config.ConfigFactory.load(ConfigFactory.java:112)
    at com.typesafe.config.ConfigFactory.load(ConfigFactory.java:72)
    at com.typesafe.config.ConfigFactory.loadDefaultConfig(ConfigFactory.java:181)
    at com.typesafe.config.ConfigFactory.load(ConfigFactory.java:246)
    at com.typesafe.config.ConfigFactory.load(ConfigFactory.java:234)
    at play.api.Configuration$.load(Configuration.scala:50)
    at play.api.Application$$anonfun$1.apply(Application.scala:36)
    at play.api.Application$$anonfun$1.apply(Application.scala:36)
    at play.utils.Threads$.withContextClassLoader(Threads.scala:17)
    at play.api.Application.<init>(Application.scala:35)
    at play.core.server.servlet.WarApplication.<init>(Play2Server.scala:42)
    at play.core.server.servlet.Play2Servlet.contextInitialized(Play2CommonServlet.scala:340)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3910)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4389)
    at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeployInternal(TomcatDeployment.java:313)
    at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeploy(TomcatDeployment.java:145)
    at org.jboss.web.deployers.AbstractWarDeployment.start(AbstractWarDeployment.java:461)
    at org.jboss.web.deployers.WebModule.startModule(WebModule.java:122)
    at org.jboss.web.deployers.WebModule.start(WebModule.java:97)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157)
    at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96)
    at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
    at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
    at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668)
    at org.jboss.system.microcontainer.ServiceProxy.invoke(ServiceProxy.java:206)
    at $Proxy38.start(Unknown Source)
    at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:42)
    at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:37)
    at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62)
    at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71)
    at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
    at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
    at org.jboss.system.microcontainer.ServiceControllerContext.install(ServiceControllerContext.java:297)
    at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1652)
    at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:938)
    at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
    at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:988)
    at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:826)
    at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:556)
    at org.jboss.system.ServiceController.doChange(ServiceController.java:688)
    at org.jboss.system.ServiceController.start(ServiceController.java:460)
    at org.jboss.system.deployers.ServiceDeployer.start(ServiceDeployer.java:163)
    at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:99)
    at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:46)
    at org.jboss.deployers.spi.deployer.helpers.AbstractSimpleRealDeployer.internalDeploy(AbstractSimpleRealDeployer.java:62)
    at org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer.deploy(AbstractRealDeployer.java:55)
    at org.jboss.deployers.plugins.deployers.DeployerWrapper.deploy(DeployerWrapper.java:179)
    at org.jboss.deployers.plugins.deployers.DeployersImpl.doDeploy(DeployersImpl.java:1454)
    at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1172)
    at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1193)
    at org.jboss.deployers.plugins.deployers.DeployersImpl.install(DeployersImpl.java:1113)
    at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
    at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1652)
    at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:938)
    at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
    at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:988)
    at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:826)
    at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:556)
    at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:789)
    at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:699)
    at org.jboss.system.server.profileservice.repository.MainDeployerAdapter.process(MainDeployerAdapter.java:117)
    at org.jboss.system.server.profileservice.hotdeploy.HDScanner.scan(HDScanner.java:409)
    at org.jboss.system.server.profileservice.hotdeploy.HDScanner.run(HDScanner.java:294)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.ClassCastException: sun.instrument.InstrumentationImpl cannot be cast to java.lang.String
    at com.typesafe.config.impl.PropertiesParser.fromPathMap(PropertiesParser.java:145)
    at com.typesafe.config.impl.PropertiesParser.fromProperties(PropertiesParser.java:67)
    at com.typesafe.config.impl.Parseable$ParseableProperties.rawParseValue(Parseable.java:614)
    at com.typesafe.config.impl.Parseable$ParseableProperties.rawParseValue(Parseable.java:597)
    at com.typesafe.config.impl.Parseable.parseValue(Parseable.java:135)
    at com.typesafe.config.impl.Parseable.parseValue(Parseable.java:129)
    at com.typesafe.config.impl.Parseable.parse(Parseable.java:168)
    at com.typesafe.config.impl.ConfigImpl.loadSystemProperties(ConfigImpl.java:354)
    at com.typesafe.config.impl.ConfigImpl.access$100(ConfigImpl.java:26)
    at com.typesafe.config.impl.ConfigImpl$SystemPropertiesHolder.<clinit>(ConfigImpl.java:360)
    ... 81 more
dlecan commented 11 years ago

JVM loads resources by analyzing jars in classpath alphanumerically sorted. What is the name of your application ?

ghost commented 11 years ago

the name is playehcacheplugintest_2.9.1-1.0.0-SNAPSHOT.jar

dlecan commented 11 years ago

Can you rename it "a_playehcacheplugintest" (eg.) in MY_PROJECT/project/Build.scala and try again ?

ghost commented 11 years ago

Thanks - now it picks up the ehcache.xml deployed in my own Jar although I'm not too exited about renaming my Jar to override the default Play ehcache.xml :)

According to this http://stackoverflow.com/questions/5474765/order-of-loading-jar-files-from-lib-directory its because Tomcat sorts the Jars in the lib folder that this solution works?

dlecan commented 11 years ago

According to this http://stackoverflow.com/questions/5474765/order-of-loading-jar-files-from-lib-directory its because Tomcat sorts the Jars in the lib folder that this solution works?

Yes it is. It would possible to rename project's jar when it is embedded in war package, by setting an option configured in your build file. Please open another issue if you need it.

ghost commented 11 years ago

Although we got Play to load our own ehcache.xml some developers on our team are complaining the exception mentioned in the ticket still happens on hot redeployment in JBoss EAP 5.1.2.

In a small proof of concept app I cant trigger the issue but in a larger app it now seems to happen often after adding /conf/ehcache.xml.

The report Im getting from other developers is that after adding the ehcache.xml it now happens every time the developers change a scala template even when running the app in Play standalone.

I dont think the contents of the ehcache.xml is causing the problem but just for good measure Im posting it here (the change thats important to us is to limit the cache to a physical size - here shown as 50Mb - instead of the default limit of 10000 objects which is not really a limit):

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd" updateCheck="false"  maxBytesLocalHeap="50M">
    <defaultCache   
            eternal="false"
            timeToIdleSeconds="0"
            timeToLiveSeconds="0"
            overflowToDisk="false"
            memoryStoreEvictionPolicy="LFU"
    />  
</ehcache>
dlecan commented 11 years ago

Someone reported a similar issue with Play itself on Play Google group months ago. Search for "ehcache" in https://groups.google.com/group/play-framework/tree/browse_frm/month/2012-7?_done=/group/play-framework/browse_frm/month/2012-7?scoring%3Dd%26start%3D750%26&scoring=d&start=750&&pli=1

Weird thing, individual messages seem to have been deleted ?!?

Does it also happen with native Play reloading feature ?

dlecan commented 11 years ago

it now happens every time the developers change a scala template even when running the app in Play standalone.

Sorry, I didn't catch this. For me, this is a Play reloading issue, which should be reported to Play itself.

Do not hesitate to reopen this issue if you think something is wrong with Play2War.