1

I'm useing the cdi-api-1.2 dependecy, when executing jbehave tests with the maven-jbehave-plugin I noticed that classes are loaded form the cdi-api-1.0 and not from the 1.2 version.

After duing some research it turns out, that the cdi-api-1.0 dependecy is provided by maven itself ($MAVEN_HOME/lib/) and part of the jbehave-maven-plugin classpath.

Does anyone had similar issues and an idea how this class loading mess can be solved?

// Sascha

The POM:

  <dependencies>
    <dependency>
        <groupId>org.jbehave</groupId>
        <artifactId>jbehave-core-example</artifactId>
        <version>4.1</version>
    </dependency>
    <dependency>
        <groupId>org.jbehave</groupId>
        <artifactId>jbehave-weld</artifactId>
        <version>4.1</version>
        <exclusions>
            <exclusion>
                <groupId>javax.enterprise</groupId>
                <artifactId>cdi-api</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.jboss.weld.se</groupId>
                <artifactId>weld-se</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.jboss.weld.se</groupId>
        <artifactId>weld-se</artifactId>
        <version>2.3.5.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.weld.se</groupId>
        <artifactId>weld-se-core</artifactId>
        <version>2.3.5.Final</version>
    </dependency>
    <dependency>
        <groupId>javax.enterprise</groupId>
        <artifactId>cdi-api</artifactId>
        <version>1.2</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>


</dependencies>

<build>
    <plugins>

        <plugin>
            <groupId>org.jbehave</groupId>
            <artifactId>jbehave-maven-plugin</artifactId>

            <executions>
                <execution>
                    <id>unpack-view-resources</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>unpack-view-resources</goal>
                    </goals>
                </execution>
                <execution>
                    <id>embeddable-stories</id>
                    <phase>integration-test</phase>
                    <configuration>
                        <includes>
                            <include>**/JBehaveWeldStories.java</include>
                        </includes>
                        <ignoreFailureInStories>true</ignoreFailureInStories>
                        <ignoreFailureInView>true</ignoreFailureInView>
                    </configuration>
                    <goals>
                        <goal>run-stories-as-embeddables</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
Sascha
  • 127
  • 7
  • Please show your pom file...which Maven version do you use? Which version of the jbehave-maven-plugin do you use? – khmarbaise Apr 26 '17 at 10:38
  • The POM shouldn't be the problem and I use maven 3.5.0. The cdi-api-1.0 is loaded by the maven plexus class loader (so very early in the classloader chain), the cdi-api-1.2 is then loaded by one of the child class loaders (which is the maven-plugin-class-loader). So there are two versions of the same class in the class loader chain. – Sascha Apr 26 '17 at 12:36
  • Have you seen that in the debug output ? Furthermore I would try to contact the jbehave-maven-plugin developers to see if they know something like this... – khmarbaise Apr 26 '17 at 17:06
  • No, the debug log wasn't very helpful here. I debugged the plugin code to find the root cause of my problem. But yes, maybe the plugin developers can get more input on this. – Sascha Apr 28 '17 at 05:38

1 Answers1

0

I am currently facing a similar problem. A plugin I'm developing starts a Weld container to get CDI injection using cdi-plugin-utils. When I tried to update to Weld 3.1.0.Final, I ran into this problem as that release needs a newer CDI API:

java.lang.IncompatibleClassChangeError: javax.enterprise.inject.Any and javax.enterprise.inject.Any$Literal disagree on InnerClasses attribute

Using -verbose:class JVM option (invoker.mavenOpts=-verbose:class in my case), one can clearly see where the offending classes are loaded from:

[Loaded javax.enterprise.inject.Any from file:/path/to/maven/3.5.4/libexec/lib/cdi-api-1.0.jar]
...
[Loaded javax.enterprise.inject.Any$Literal from file:/path/to/my-maven-plugin/target/local-repo/org/jboss/weld/se/weld-se-shaded/3.1.0.Final/weld-se-shaded-3.1.0.Final.jar]

Unfortunately, I don't have a solution yet. I tried experimenting with establishing a child-first classloader similar to this answer, but couldn't yet figure out how to activate it inside the mojo.

Hope these pointers help somebody.

Jens Bannmann
  • 4,845
  • 5
  • 49
  • 76