Unable to inject dependencies of injected bean with Arquillian - jboss-arquillian

I am using Arquillian to inject the dependencies for my tests. It works OK if I inject the beans directly to my test class, but if the beans have dependencies of their own tht have to be injected, those dependencies do not get injected.
For example: the FacLptConfiguration bean gets imported correctly into my Test Class, but it does not get injected into the CfdFileCreator bean. I injected FacLptConfigurtion to the test class just to confirm that the injection works, but the user of this class is CfdFileCreator.
#RunWith(Arquillian.class)
public class CfdFileCreatorArquillianTest {
#Deployment
public static WebArchive createDepolyment() {
return ShrinkWrap.create(WebArchive.class)
.addClass(FacLptConfiguration.class)
.addClass(InterimFileCreator.class)
.addClass(CfdFileCreator.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsWebInfResource(new File("C:/aLearn/FacLpt/web/WEB-INF/env-entries.properties"));
}
public static String TEST_FOLDER = "C:/aLearn/FacLpt/src/test/testdata/pruebas/";
#Inject
private FacLptConfiguration facLptConfiguration;
#Inject
private CfdFileCreator cfdFileCreator;
#Test
public void createCfd() {
System.out.println("in createCFD");
cfdFileCreator.createCFDFile();
}
}
These injections are not working:
#Singleton
public class CfdFileCreator {
#Inject
private InterimFileCreator interimFileCreator;
#Inject
private FacLptConfiguration facLptConfiguration;

I think your problem is the location of the beans.xml. For a web archive it should be WEB-INF/beans.xml. Use:
addAsWebInfResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"))
See also https://community.jboss.org/thread/175404

Related

Quarkus 2.5: #Inject inside JAX-RS Application subclass not working anymore

After upgrading Quarkus from 1.6.1.Final to 2.5.Final the following #Inject fails inside javax.ws.rs.core.Application subclass:
#ApplicationScoped
public class MyBean {
public String foo() {
retun "bar";
}
}
#ApplicationPath("/")
public class MyApplication extends Application {
#Inject
MyBean myBean;
#Override
public Set<Class<?>> getClasses() {
myBean.foo(); // Causes NPE on Quarkus 2.5.Final, worked well with 1.6.1.Final
}
}
I tried with CDI.current().select(MyBean.class).get() but got Unable to locate CDIProvider.
Any other workaround I can try? Thanks.
#Inject in JAX-RS Application classes has been since disallowed. I was able to solve my issue (registering resource classes by config) using #IfBuildProperty annotation.

Resteasy and Google Guice: how to use multiple #ApplicationPath and resource with #Injection?

I created a project to test the dependency injection offered by Google Guice in my Jax-rs resources, using Resteasy.
My intentions are:
Use multiple #ApplicationPath for the versions of my API. In each class annotated with #ApplicationPath I load a set of classes for the specific version.
Each resource have a #Inject (from Google Guice) in his constructor to inject some services.
I created two classes annotated with #ApplicationPath: ApplicationV1RS and ApplicationV2RS. In both I added the same resources classes (UserResource and HelloResource), only for my test.
My Module is configured like this:
public class HelloModule implements Module
{
public void configure(final Binder binder)
{
binder.bind(IGreeterService.class).to(GreeterService.class);
binder.bind(IUserService.class).to(UserService.class);
}
}
When I call http://localhost:9095/v1/hello/world or http://localhost:9095/v2/hello/world, I receive the same error:
java.lang.RuntimeException: RESTEASY003190: Could not find constructor
for class: org.jboss.resteasy.examples.guice.hello.HelloResource
Well, as I expected, this not works. The Google Guice is not "smart" to instantiate the resource classes using the construtor for me.
But I can't find a way to work. To be really honest, I'm really confuse about how the Google Guice, Jetty and Resteasy play with each other in this scenario.
If I abandon the idea of use #ApplicationPath, my resources work with Google Guice configuring my HelloModule like this:
public class HelloModule implements Module
{
public void configure(final Binder binder)
{
binder.bind(HelloResource.class);
binder.bind(IGreeterService.class).to(GreeterService.class);
binder.bind(UserResource.class);
binder.bind(IUserService.class).to(UserService.class);
}
}
But in this case, I'm passing the control to register my resources (HelloResource and UserResource) to Guice. It's not flexible for me, I can't setup my multiple #ApplicationPath.
So, what I'm missing or not understanding?
I created a project with the problemetic code. Is very easy to setup and test: https://github.com/dherik/resteasy-guice-hello/tree/so-question/README.md
Thanks!
When you have getClasses method in your Application then it tries to create instance for all the registered resources using the default constructor which is missing in our Resources class. One way is to create a default constructor and Inject the dependencies through setter Injection.
And then instead of overriding getClasses in ApplicationV1RS and ApplicationV2RS you override getSingletons. Since Resources can be Singleton.
Below are the changes that I made to make it work the way you want.
ApplicationV1RS.java
#ApplicationPath("v1")
public class ApplicationV1RS extends Application {
private Set<Object> singletons = new HashSet<Object>();
public ApplicationV1RS(#Context ServletContext servletContext) {
}
#Override
public Set<Object> getSingletons() {
Injector injector = Guice.createInjector(new HelloModule());
HelloResource helloResource = injector.getInstance(HelloResource.class);
UserResource userResource = injector.getInstance(UserResource.class);
singletons.add(helloResource);
singletons.add(userResource);
return singletons;
}
}
ApplicationV2RS.java
#ApplicationPath("v2")
public class ApplicationV2RS extends Application {
private Set<Object> singletons = new HashSet<Object>();
public ApplicationV2RS(#Context ServletContext servletContext) {
}
#Override
public Set<Object> getSingletons() {
Injector injector = Guice.createInjector(new HelloModule());
HelloResource helloResource = injector.getInstance(HelloResource.class);
UserResource userResource = injector.getInstance(UserResource.class);
singletons.add(helloResource);
singletons.add(userResource);
return singletons;
}
}
HelloResource.java
#Path("hello")
public class HelloResource {
#Inject
private IGreeterService greeter;
public HelloResource() {
}
#GET
#Path("{name}")
public String hello(#PathParam("name") final String name) {
return greeter.greet(name);
}
}
UserResource.java
#Path("user")
public class UserResource {
#Inject
private IUserService userService;
public UserResource() {
}
#GET
#Path("{name}")
public String hello(#PathParam("name") final String name) {
return userService.getUser(name);
}
}
Add #Singleton to your Service Classes.
Hope it helps.
I have also pushed the code to forked repo. check it out

How to use arquillian to test EJB calling webservices using #webserviceref annotation

I'm trying to use arquillian to test one method of an EJB using a webservice through #WebServiceRef annotation
In my method decorated by #Deployment I declared the resource
#Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addPackages(true, .... PortType.class.getPackage())
.addAsResource("test-my.wsdl","my.wsdl")
.addAsManifestResource("META-INF/beans.xml", "beans.xml").addAsManifestResource("META-INF/test-persistence.xml", "persistence.xml");
}
Then I coded the bean as following
#Stateless
#LocalBean
public class WSBean {
#WebServiceRef(wsdlLocation = "/my.wsdl")
PortType portType;
public void test() throws Exception{
portType.lireAdresseClient(null, null);
}
}
and the test
#RunWith(Arquillian.class)
public class WSintegrationTest extends DefaultServicesIntegrationTest {
#Deployment
....
#Inject
private WSBean wsBean;
#Test
public void testAppel() throws Exception {
System.out.println("TEST APPEL");
wsBean.test();
}
}
Can I do that with Arquillian ?
How can I fix it ?
Thanks
Regards
Also if you want you can take a look at https://github.com/javaee-samples/javaee7-samples/tree/master/jaxws you will find examples of JAXWS with its Arquillian test.

Arquillian can not inject EJB

I have a testclass:
#RunWith(Arquillian.class)
public class ActionServiceTest {
#EJB
private ActionService actionService;
...
}
This works fine.
Now I created another File ActionBuilder which should also have the EJB injected (but has no #RunWith Annotation) and is called from the ActionServiceTest, e.g.
new ActionBuilder().foo()
.
public class ActionBuilder {
#EJB
ActionService actionService;
...
}
In this case actionService is null. Can you tell me why?
Looks like you're using new which will bypass any container injection.

EJB 3.1 : Singleton bean not getting injected inside another stateless bean though both beans are getting registered

Here is my bean that is trying to inject a singleton bean InformationService :
#Path("/information/{name}")
#Stateless (name="InformationResource")
public class InformationResource {
#EJB
private InformationService appService;
#GET
#Produces(MediaType.APPLICATION_XML)
public Information getInfo(#PathParam("name") String name){
return appService.getMap().get(name);
}
#PUT
#POST
#Consumes(MediaType.APPLICATION_XML)
public Information putInfo(#PathParam("name") String name, Information info){
return appService.getMap().put(name,info);
}
#DELETE
public void deleteInfo(#PathParam("name") String name){
appService.getMap().remove(name);
}
}
This is the InformationService class
#Singleton
public class InformationService {
private Map<String,Information> map;
#PostConstruct
public void init(){
map = new HashMap<String,Information>();
map.put("daud", new Information("B.Tech","Lucknow"));
map.put("anuragh", new Information("M.Sc","Delhi"));
}
public Map<String,Information> getMap(){
return map;
}
}
Its part of a very simple JAX-RS implementation and I am deploying as war in JBoss 6.1 Final. The problem is that InformationService throwing a NullPointerException when I make the proper get request. If I initialize appService explicitly, everything works fine. Why is #EJB annotation not working ?
Are you using Jersey as REST implementation? If so, EJB injection is not supported out of the box.
This link provides more information on this and also a solution.
Check that your #Singleton is javax.ejb.Singleton.
Any other exceptions before NPE ?