Uploaded image for project: 'Geronimo'
  1. Geronimo
  2. GERONIMO-2222

Application errors in static initialization blocks during serialization of configuration during deployment due to incorrect TCCL

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Blocker
    • Resolution: Fixed
    • 1.0, 1.1
    • 1.1.1, 1.2
    • deployment
    • Security Level: public (Regular issues)
    • None

    Description

      Problem

      Exceptions and/or errors may occur in static initialization blocks invoked whilst loading classes when serializing a configuration during deployment.
      These same exceptions/errors don't occur when starting the configuration.

      Symptoms

      Deployment of an EAR that has dependencies on its own copy of Xerces will cause an exception similar to the following if Xerces is initialised in a static block.

      java.lang.ClassCastException
              at org.apache.xerces.parsers.DOMParser.<init>(Unknown Source)
              at org.apache.xerces.parsers.DOMParser.<init>(Unknown Source)
              at com.foo.server.ejb.MyEJB.<clinit>
              at java.io.ObjectStreamClass.hasStaticInitializer(Native Method)
              at java.io.ObjectStreamClass.computeDefaultSUID(ObjectStreamClass.java:1557)
              at java.io.ObjectStreamClass.access$100(ObjectStreamClass.java:47)
              at java.io.ObjectStreamClass$1.run(ObjectStreamClass.java:173)
              at java.security.AccessController.doPrivileged(Native Method)
              at java.io.ObjectStreamClass.getSerialVersionUID(ObjectStreamClass.java:170)
              at java.io.ObjectStreamClass.writeNonProxy(ObjectStreamClass.java:557)
              at java.io.ObjectOutputStream.writeClassDescriptor(ObjectOutputStream.java:591)
              at java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1142)
              at java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1100)
              at java.io.ObjectOutputStream.writeClass(ObjectOutputStream.java:1082)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:996)
              at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1332)
              at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1304)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1247)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
              at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1332)
              at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1304)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1247)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
              at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1332)
              at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1304)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1247)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
              at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1332)
              at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1304)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1247)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
              at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:278)
              at org.apache.geronimo.gbean.GBeanData.writeExternal(GBeanData.java:187)
              at org.apache.geronimo.kernel.config.SerializedGBeanState.storeGBeans(SerializedGBeanState.java:139)
              at org.apache.geronimo.kernel.config.SerializedGBeanState.writeObject(SerializedGBeanState.java:92)
              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:324)
              at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:809)
              at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1296)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1247)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
              at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1332)
              at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1304)
              at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1247)
              at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
              at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:278)
              at org.apache.geronimo.kernel.config.SerializedConfigurationMarshaler.writeConfigurationData(SerializedConfigurationMarshale
      r.java:66)
              at org.apache.geronimo.kernel.config.ConfigurationUtil.writeConfigurationData(ConfigurationUtil.java:163)
              at org.apache.geronimo.system.configuration.ExecutableConfigurationUtil.writeConfiguration(ExecutableConfigurationUtil.java:
      155)
              at org.apache.geronimo.system.configuration.RepositoryConfigurationStore.install(RepositoryConfigurationStore.java:323)
              at org.apache.geronimo.deployment.Deployer.deploy(Deployer.java:322)
              at org.apache.geronimo.deployment.Deployer.deploy(Deployer.java:124)
      

      Deployment of an EAR that has dependencies on its own copy of Log4j will cause errors similar to the following if Log4j is initialised in a static block.

      log4j:ERROR A "org.apache.log4j.ConsoleAppender" object is not assignable to a "org.apache.log4j.Appender" variable.
      log4j:ERROR The class "org.apache.log4j.Appender" was loaded by
      log4j:ERROR [[org.apache.geronimo.kernel.classloader.JarFileClassLoader id=groupId/artifactId/1.0/ear]] whereas object of type
      log4j:ERROR "org.apache.log4j.ConsoleAppender" was loaded by [sun.misc.Launcher$AppClassLoader@53ba3d].
      log4j:ERROR Could not instantiate appender named "WSSysOut".
      log4j: Parsing appender named "WSFile1".
      log4j:ERROR A "org.apache.log4j.RollingFileAppender" object is not assignable to a "org.apache.log4j.Appender" variable.
      log4j:ERROR The class "org.apache.log4j.Appender" was loaded by
      log4j:ERROR [[org.apache.geronimo.kernel.classloader.JarFileClassLoader id=groupId/artifactId/1.0/ear]] whereas object of type
      log4j:ERROR "org.apache.log4j.RollingFileAppender" was loaded by [sun.misc.Launcher$AppClassLoader@53ba3d].
      log4j:ERROR Could not instantiate appender named "WSFile1".
      

      Cause

      The org.apache.geronimo.deployment.deploy(..) method at approx line 187 serializes the configuration by calling store.install(configurationData) but at the time when the configuration is serialized (and static blocks in EJBs invoked) the thread context classloader is set to [org.apache.geronimo.kernel.classloader.JarFileClassLoader id=geronimo/j2ee-security/1.1.1-SNAPSHOT/car].

      Xerces and Log4j are examples of libraries that rely upon the thread context classloader to be set correctly during initialization.

      Solution

      Set the context classloader before serializing the configuration.

      Workaround

      If you have access to the application source code, modify the application's static blocks to call setContextClassLoader(..). For example:

      ClassLoader oldClassloader = Thread.currentThread().getContextClassLoader();
      Thread.currentThread().setContextClassLoader( this.getClass().getClassLoader());
      try {
         // application processing
      } finally {
          Thread.currentThread().setContextClassLoader( oldClassloader );
      }
      

      Alternatively for Log4j problems (Log4j 1.2.6 or later) you could try setting log4j.ignoreTCL=true.

      Attachments

        1. jira-g-2222-xerces-test.zip
          19 kB
          John Sisson
        2. jira-g-2222.zip
          697 kB
          John Sisson
        3. GERONIMO-2222-v1.patch
          2 kB
          John Sisson

        Activity

          People

            johnrsisson John Sisson
            johnrsisson John Sisson
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: