Question

We have a project that uses

  • Weld-SE for dependency injection
  • static native methods to call a native library

When writing unit tests, in order to test managed beans that interact with the native library, we'd like to mock the class on which they're defined. However, PowerMock (specifically, the annotation @PrepareForTest) seems to mess with Weld's initialization. For example, if I have the following:

@RunWith(PowerMockRunner.class)
@PrepareForTest(StaticNativeAPI.class)
public class Test {
  @Before
  public void setup() {
    WeldContainer wc = new Weld().initialize();
  }
}

then Weld will fail to initialize with the following error:

org.jboss.weld.exceptions.DeploymentException: WELD-001423 Cannot enable the same alternative bean class [com.mycompany.AltBean in jar:file:/C:/Users/Me/.m2/repository/com/mycompany/project/version-SNAPSHOT/project-version-SNAPSHOT-tests.jar!/META-INF/beans.xml@8, com.mycompany.AltBean in jar:file:/C:/Users/Me/.m2/repository/com/mycompany/project/version-SNAPSHOT/project-version-SNAPSHOT-tests.jar!/META-INF/beans.xml@8] in beans.xml

at org.jboss.weld.manager.Enabled.createMetadataMap(Enabled.java:123)
at org.jboss.weld.manager.Enabled.<init>(Enabled.java:94)
at org.jboss.weld.manager.Enabled.of(Enabled.java:79)
at org.jboss.weld.bootstrap.BeanDeployment.<init>(BeanDeployment.java:114)
at org.jboss.weld.bootstrap.WeldBootstrap$DeploymentVisitor.visit(WeldBootstrap.java:184)
at org.jboss.weld.bootstrap.WeldBootstrap$DeploymentVisitor.visit(WeldBootstrap.java:153)
at org.jboss.weld.bootstrap.WeldBootstrap.startContainer(WeldBootstrap.java:284)
at org.jboss.weld.bootstrap.api.helpers.ForwardingBootstrap.startContainer(ForwardingBootstrap.java:42)
at org.jboss.weld.environment.se.Weld.initialize(Weld.java:129)
at com.mycompany.Test.setup(Test.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.internal.runners.ClassRoadie.runBefores(ClassRoadie.java:56)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:43)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:104)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:234)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:133)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:114)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:188)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:166)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:86)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:101)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:74)

In other words, it appears to be parsing beans.xml twice. Does anybody know how to get these two libraries to play nicely together?

Was it helpful?

Solution

It appears to be a bug with the MockClassLoader.

I submitted a patch, so it will probably be fixed by version 1.5.5.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top