Injecting across lib and classes in a war
ron_sigal Dec 19, 2012 7:29 PMHi,
I set out to write some Resteasy tests in which injections occur across ear, jar, and war boundaries, and I've run into a problem with my first test, the simple case with classes and jars in a war. I have a JAX-RS resource:
@Path("modules")
public class TestResource
{
@Inject
private Injectable injectable;
@PostConstruct
public void pc()
{
System.out.println("injectable: " + injectable);
}
@GET
@Path("test")
public Response test()
{
System.out.println("injectable: " + injectable);
System.out.println("Injectable classloader: " + Injectable.class.getClassLoader());
System.out.println("TestResource classloader: " + TestResource.class.getClassLoader());
return (injectable != null) ? Response.ok().build() : Response.serverError().build();
}
}
and a class to be injected:
public class Injectable
{
}
I have two versions:
1. TestResource is in /classes and Injectable is in a jar in /lib:
@Deployment
public static Archive<?> createTestArchive()
{
JavaArchive jar = ShrinkWrap.create(JavaArchive.class, "test.jar")
.addClasses(Injectable.class)
;
WebArchive war = ShrinkWrap.create(WebArchive.class, "resteasy-cdi-ejb-test.war")
.addClasses(JaxRsActivator.class)
.addClasses(TestResource.class)
.addAsLibrary(jar)
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
System.out.println(jar.toString(true));
System.out.println(war.toString(true));
return war;
}
In this case I get the exception
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Injectable] with qualifiers [@Default] at injection point [[field] @Inject private org.jboss.resteasy.cdi.modules.TestResource.injectable]
When I turn on DEBUG level logging for Weld, I see that a managed bean has been created for TestResource:
18:59:56,934 DEBUG [org.jboss.weld.Bootstrap] (MSC service thread 1-16) WELD-000106 Bean: Managed Bean [class org.jboss.resteasy.cdi.modules.TestResource] with qualifiers [@Any @Default]
but there is none for Injectable.
2. TestResource is in a jar in /lib and Injectable is in /classes:
@Deployment
public static Archive<?> createTestArchive()
{
JavaArchive jar = ShrinkWrap.create(JavaArchive.class, "test.jar")
.addClasses(TestResource.class)
;
WebArchive war = ShrinkWrap.create(WebArchive.class, "resteasy-cdi-ejb-test.war")
.addClasses(JaxRsActivator.class)
.addClasses(Injectable.class)
.addAsLibrary(jar)
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
System.out.println(jar.toString(true));
System.out.println(war.toString(true));
return war;
}
In this case Weld doesn't complain, but when the test runs, injectable is null. Also, I see that a managed bean has been created for Injectable:
18:59:53,368 DEBUG [org.jboss.weld.Bootstrap] (MSC service thread 1-4) WELD-000106 Bean: Managed Bean [class org.jboss.resteasy.cdi.modules.Injectable] with qualifiers [@Any @Default]
but not for TestResource.
So, in each case, the class in /classes is getting processed as a bean, and the class in the jar is not.
By the way, as you would expect, the same classloader is being used for the two classes:
19:20:07,829 INFO [stdout] (http--127.0.0.1-8080-3) Injectable classloader: ModuleClassLoader for Module "deployment.resteasy-cdi-ejb-test.war:main" from Service Module Loader
19:20:07,829 INFO [stdout] (http--127.0.0.1-8080-3) TestResource classloader: ModuleClassLoader for Module "deployment.resteasy-cdi-ejb-test.war:main" from Service Module Loader
Any ideas?
-Ron