Arquillian/WeldSE with CDI beans in another jar
lucianom86 Oct 20, 2015 12:59 PMHi all,
I have the following scenario: I have a jar ("cdiproj") with a CDI bean and its beans.xml file and then I have another project ("arquillian-test") responsible for testing this jar. On this test project, I'm running Weld SE and adding a dependency to the "cdiproj" jar in the MANIFEST.MF file and then adding this file to my deployment.
Here's the code.
cdiproj - MyBean.java
package com.test.cdi; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class MyBean { public void someMethod() { System.out.println("---> Some method"); } }
And I have a beans.xml under src/main/resources/META-INF project. That's all for "cdiproj".
Then in the "arquillian-test" project.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tests</groupId> <artifactId>arquillian-test</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencyManagement> <dependencies> <dependency> <groupId>org.jboss.arquillian</groupId> <artifactId>arquillian-bom</artifactId> <version>1.1.10.Final</version> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>org.jboss.weld</groupId> <artifactId>weld-core-bom</artifactId> <version>1.1.0.Final</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.jboss.spec</groupId> <artifactId>jboss-javaee-6.0</artifactId> <version>1.0.0.Final</version> <type>pom</type> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.arquillian.junit</groupId> <artifactId>arquillian-junit-container</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.arquillian.container</groupId> <artifactId>arquillian-weld-se-embedded-1.1</artifactId> <version>1.0.0.CR9</version> <scope>test</scope> </dependency> <!-- <dependency> <groupId>org.jboss.arquillian.container</groupId> <artifactId>arquillian-weld-ee-embedded-1.1</artifactId> <version>1.0.0.CR9</version> <scope>test</scope> </dependency> --> <dependency> <groupId>org.jboss.weld</groupId> <artifactId>weld-core</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.weld</groupId> <artifactId>weld-api</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>el-impl</artifactId> <version>2.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>com.test</groupId> <artifactId>cdi-proj</artifactId> <version>0.0.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.5.10</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency> </dependencies> </project>
MyTest.java
package com.test; import javax.inject.Inject; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import com.test.cdi.MyBean; @RunWith(Arquillian.class) public class MyTest { // @Inject // private MyBean myBean; @Deployment public static JavaArchive createTestArchive() { // ShrinkWrap.create(MavenImporter.class).configureFromFile("/path/to/settings.xml") // .loadPomFromFile("/path/to/pom.xml").importBuildOutput().as(JavaArchive.class); final JavaArchive jar = ShrinkWrap.create(JavaArchive.class, "MyTest.jar"); jar.addClass(MyTest.class); jar.addAsResource("META-INF/beans.xml"); //jar.addAsManifestResource("META-INF/MANIFEST-APP.MF", "MANIFEST.MF"); jar.setManifest("META-INF/MANIFEST-APP.MF"); // jar.addClass(MyBean.class); //jar.addClasses(SystemRecorder.class, SystemRecorderBean.class); // return jar; } @Test public void test() { MyBean myBean = new MyBean(); myBean.someMethod(); try { Class.forName("com.test.cdi.MyBean"); System.out.println("--> Class found"); } catch (ClassNotFoundException e) { e.printStackTrace(); Assert.fail("Should have loaded class"); } //Assert.assertNotNull(myBean); } }
META-INF/MAINIFEST-APP.MF
Manifest-Version: 1.0 Class-Path: /home/user/.m2/repository/com/test/cdi-proj/0.0.1/cdi-proj-0.0.1.jar
If I remove the comment from the @Inject I get the error:
WELD-001408 Unsatisfied dependencies for type [MyBean] with qualifiers [@Default] at injection point [[field] @Inject private com.test.MyTest.myBean]
However, I can instantiate this MyBean class and load it using Class.forName without any issue, the only problem is that I can't inject it. If I add MyBean.class in the MyTest.jar, then it works.
Any ideas what I need to do in order to inject this CDI Bean?
Thanks in advance,
Luciano
ps.: I know I could test MyBean class in the same project, but this is just a simplified version of my real project, where we have a lot of modules and a test module that test all of them integrated. We already have tests for container, but we also need to add tests for SE, as we support this environment in our product as well.