2

I have some code that does this at the top of a class:

static {
    ...
    mapper.addMappingConfig(ModelRestMapper.class.getResourceAsStream("/com/mycompany/myapp/rest/dozer/mapping/mapping.xml"));
    ...
}

This code sometimes fails with this exception:

[#|2014-05-23T12:21:33.111-0700|SEVERE|glassfish3.1.2|org.dozer.loader.xml.MappingStreamReader|_ThreadID=305;_ThreadName=Thread-2;|Error while loading dozer mapping InputStream: [null]
    java.lang.IllegalArgumentException: InputStream cannot be null
    at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:117)
    at org.dozer.loader.xml.MappingStreamReader.read(MappingStreamReader.java:50)
    at org.dozer.DozerBeanMapper.addMapping(DozerBeanMapper.java:247)
    at com.mycompany.commons.objectmapping.Mapper.addMappingConfig(Mapper.java:62)
    at com.mycompany.myapp.rest.dozer.mapping.ModelRestMapper.<clinit>(ModelRestMapper.java:30) //the line I showed you
at sun.misc.Unsafe.ensureClassInitialized(Native Method)
at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:43)
at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:140)
at java.lang.reflect.Field.acquireFieldAccessor(Field.java:1057)
at java.lang.reflect.Field.getFieldAccessor(Field.java:1038)
at java.lang.reflect.Field.set(Field.java:741)
at org.glassfish.web.loader.WebappClassLoader.clearReferences(WebappClassLoader.java:1836)
at org.glassfish.web.loader.WebappClassLoader.stop(WebappClassLoader.java:1662)
at org.glassfish.web.loader.WebappClassLoader.preDestroy(WebappClassLoader.java:1631)
at org.glassfish.javaee.full.deployment.EarClassLoader.preDestroy(EarClassLoader.java:91)
at org.glassfish.deployment.common.DeploymentContextImpl.preDestroy(DeploymentContextImpl.java:151)
at com.sun.enterprise.v3.server.ApplicationLifecycle$1.actOn(ApplicationLifecycle.java:281)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:465)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:389)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:348)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:363)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1085)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:95)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1291)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1259)
at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:461)
at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:212)
at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:179)
at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
at com.sun.enterprise.v3.services.impl.ContainerMapper$Hk2DispatcherCallable.call(ContainerMapper.java:354)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:745)
|#]

I'd say this happens about once every 10 deploys and it always seems to work the next time I try. This is a class deployed inside a war and the app server is GlassFish 3.1.2. The class is nothing special, just a pojo. When the error happens and I open up the war, I see that xml file exactly where it should be. This is my JRE:

java version "1.7.0_55"
Java(TM) SE Runtime Environment (build 1.7.0_55-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.55-b03, mixed mode)

Am I not supposed to use code like this in a war? Why is this happening and how do I prevent it?

Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356

1 Answers1

3

According to the stack trace the exception occurred when the application context is being destroyed. The problem seems to be connected to the fact that the Glassfish's WebappClassLoader by default sets any of the static and final fields of all the loaded classes to null as workaround to avoid memory leaks.

That could lead to the (re-)initialization of your class, that is calling the static initialization block that tries to load a resource and fails due to some sort of race condition.

There is a system property org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES that control the process of clearing the references (link). You can try to set to false and see what's happened.

Another (better) option is to move the loading of the resource outside of the static initializer block.

Alexey Gavrilov
  • 10,593
  • 2
  • 38
  • 48
  • OK I think I'll use the better option. I'll see if this ever happens again and if it fixes the problem I'll mark yours as the answer. – Daniel Kaplan May 23 '14 at 20:42