Maven
  1. Maven
  2. MNG-4207

Plugins that use ArtifactResolver with http repositories AND depend on log4j run into ExceptionInInitializerError

    Details

    • Complexity:
      Intermediate
    • Testcase included:
      yes
    • Number of attachments :
      2

      Description

      plugins that use log4j as a dependency and that also resolve artifacts using the ArtifactResolver to access one or more http repositories are running into a stacktrace as follows:

      [FATAL ERROR] org.apache.maven.plugin.coreit.ItMojo#execute() caused a linkage error (java.lang.ExceptionInInitializerError) and may be out-of-date. 
          Check the realms:
      [FATAL ERROR] Plugin realm = app0.child-container[org.apache.maven.its.plugins:maven-it-plugin-log4j:2.1-SNAPSHOT]
      urls[0] = file:/Users/jdcasey/.m2/repository/org/apache/maven/its/plugins/maven-it-plugin-log4j/2.1-SNAPSHOT/maven-it-plugin-log4j-2.1-SNAPSHOT.jar
      urls[1] = file:/Users/jdcasey/.m2/repository/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar
      urls[2] = file:/Users/jdcasey/.m2/repository/log4j/log4j/1.2.14/log4j-1.2.14.jar
      [FATAL ERROR] Container realm = plexus.core
      urls[0] = file:/Users/jdcasey/apps/maven/apache-maven-2.2.0-RC3-SNAPSHOT/lib/maven-2.2.0-RC3-SNAPSHOT-uber.jar
      [INFO] ------------------------------------------------------------------------
      [ERROR] FATAL ERROR
      [INFO] ------------------------------------------------------------------------
      [INFO] null
      org/apache/log4j/Category
      [INFO] ------------------------------------------------------------------------
      [DEBUG] Trace
      java.lang.ExceptionInInitializerError
              at org.apache.maven.wagon.shared.http.AbstractHttpClientWagon.openConnectionInternal(AbstractHttpClientWagon.java:153)
              at org.apache.maven.wagon.AbstractWagon.openConnection(AbstractWagon.java:105)
              at org.apache.maven.wagon.AbstractWagon.connect(AbstractWagon.java:207)
              at org.apache.maven.artifact.manager.DefaultWagonManager.getRemoteFile(DefaultWagonManager.java:439)
              at org.apache.maven.artifact.manager.DefaultWagonManager.getArtifact(DefaultWagonManager.java:372)
              at org.apache.maven.artifact.manager.DefaultWagonManager.getArtifact(DefaultWagonManager.java:327)
              at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:216)
              at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:90)
              at org.apache.maven.plugin.coreit.ItMojo.execute(ItMojo.java:97)
              at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:483)
              at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:678)
              at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:540)
              at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:519)
              at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:371)
              at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:332)
              at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:181)
              at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:356)
              at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:137)
              at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
              at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:41)
              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:585)
              at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
              at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
              at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
              at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
      Caused by: hidden.org.apache.commons.logging.LogConfigurationException: 
          hidden.org.apache.commons.logging.LogConfigurationException: No suitable Log constructor [Ljava.lang.Class;@986c47 for 
          hidden.org.apache.commons.logging.impl.Log4JLogger (Caused by java.lang.NoClassDefFoundError: org/apache/log4j/Category) 
          (Caused by hidden.org.apache.commons.logging.LogConfigurationException: No suitable Log constructor [Ljava.lang.Class;@986c47 
          for hidden.org.apache.commons.logging.impl.Log4JLogger (Caused by java.lang.NoClassDefFoundError: org/apache/log4j/Category))
              at hidden.org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:543)
              at hidden.org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:235)
              at hidden.org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:209)
              at hidden.org.apache.commons.logging.LogFactory.getLog(LogFactory.java:351)
              at hidden.org.apache.commons.httpclient.HttpClient.<clinit>(HttpClient.java:66)
              ... 28 more
      Caused by: hidden.org.apache.commons.logging.LogConfigurationException: No suitable Log constructor [Ljava.lang.Class;@986c47 
          for hidden.org.apache.commons.logging.impl.Log4JLogger (Caused by java.lang.NoClassDefFoundError: org/apache/log4j/Category)
              at hidden.org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor(LogFactoryImpl.java:413)
              at hidden.org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:529)
              ... 32 more
      Caused by: java.lang.NoClassDefFoundError: org/apache/log4j/Category
              at java.lang.Class.getDeclaredConstructors0(Native Method)
              at java.lang.Class.privateGetDeclaredConstructors(Class.java:2357)
              at java.lang.Class.getConstructor0(Class.java:2671)
              at java.lang.Class.getConstructor(Class.java:1629)
              at hidden.org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor(LogFactoryImpl.java:410)
              ... 33 more
      

      The problem seems to come from some sort of conflict between the dependencies of httpclient, which is now included in the Maven core as part of the non-lightweight http wagon, and other users of log4j (plugins, mainly). Still tracking down the exact cause of the problem, trying to determine how best to fix it. I'm including Benjamin Bentmann's original test case for this issue, since he's the one who has done most of the legwork at this point.

      instructions for the attached files (maven-it-plugin-log4j.zip and pom.xml):

      1. unpack and install the IT plugin using Maven
      2. Using the attached pom.xml as the project POM, try `mvn initialize -X`
      3. observe the stacktrace that results.

        Issue Links

          Activity

          Hide
          John Casey added a comment -

          seems to have lost my original attachments. These are the same files again...

          Show
          John Casey added a comment - seems to have lost my original attachments. These are the same files again...
          Hide
          John Casey added a comment -

          Linking to the original issue that caused the switch to the non-lightweight http wagon.

          Show
          John Casey added a comment - Linking to the original issue that caused the switch to the non-lightweight http wagon.
          Hide
          John Casey added a comment -

          Note that the stacktrace above uses 2.2.0-RC3, which is identical to the staged release of 2.2.0 when this bug was found.

          Show
          John Casey added a comment - Note that the stacktrace above uses 2.2.0-RC3, which is identical to the staged release of 2.2.0 when this bug was found.
          Hide
          John Casey added a comment -

          The problem is in the way the commons-logging API discovers which logging framework to delegate to. Commons-logging is used by httpclient, which is used by the non-lightweight http wagon. The first thing clogging checks for is the presence of the Log4J classes, and if it finds them, it tries to load them preferentially over the other logging frameworks. If a plugin depends on log4j, it seems like this can confuse clogging into thinking Maven's core has access to these classes - probably because clogging is using the Thread context classloader to discover the log4j classes - which in turn leads commons-logging to throw an exception when it tries to instantiate log4j (commons-logging in this case is loaded from shaded classes that are in the Maven core). Including - and shading - log4j into the Maven core seems to solve this problem by making the classes available in the correct classloader.

          Show
          John Casey added a comment - The problem is in the way the commons-logging API discovers which logging framework to delegate to. Commons-logging is used by httpclient, which is used by the non-lightweight http wagon. The first thing clogging checks for is the presence of the Log4J classes, and if it finds them, it tries to load them preferentially over the other logging frameworks. If a plugin depends on log4j, it seems like this can confuse clogging into thinking Maven's core has access to these classes - probably because clogging is using the Thread context classloader to discover the log4j classes - which in turn leads commons-logging to throw an exception when it tries to instantiate log4j (commons-logging in this case is loaded from shaded classes that are in the Maven core). Including - and shading - log4j into the Maven core seems to solve this problem by making the classes available in the correct classloader.

            People

            • Assignee:
              John Casey
              Reporter:
              John Casey
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: