5

I've added the CDI feature to the server.xml file<feature>cdi-1.2</feature>.

My maven module contains the beans.xml inside the <module_name>/src/main/resources/META-INF folder.

This is the beans.xml content:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                           http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       version="1.1" bean-discovery-mode="all">
</beans>

But when I use the @Inject annotation it doesn't work, my bean is always null.

Code:

package ch.webapp.presentation;

...

@Path("/test/")
public class MyController {
    @Inject
    private MyService myService;

    @GET
    @Path("/foo/{count}")
    @OAuthSecurity(scope = "login")
    @Produces("application/json")
    public Response news(@PathParam("count") int count) {
        return Response
                .ok(myService.getBar(count))
                .build();
    }
}

EDIT:

That's my bean

package ch.webapp.service;

...

@RequestScoped
public class MyService {
    public String getBar(int count) {
        return "foo";
    }
}

I initialize jax-rs by extended the MFPJAXRSApplication class

package ch.webapp;

...

public class AccountApplication extends MFPJAXRSApplication {
    @Override
    protected void init() throws Exception {
    }

    @Override
    protected void destroy() throws Exception {
    }

    @Override
    protected String getPackageToScan() {
        return getClass().getPackage().getName();
    }
}

Environment details:

Launching mfp (WebSphere Application Server 8.5.5.8/wlp-1.0.11.cl50820151201-1942) on Java HotSpot(TM) 64-Bit Server VM, version 1.8.0_172-b11 (en_CH)

Console Product version: 8.0.0.00-20180717-175523

What's wrong?

Andy Guibert
  • 41,446
  • 8
  • 38
  • 61
Matteo Codogno
  • 1,569
  • 6
  • 21
  • 36
  • 2
    is `MyService` defined as a CDI bean or have an explicit producer (`@Produces`) method? – Andy Guibert Aug 16 '18 at 14:31
  • 2
    (to define `MyService` as a CDI bean you simply put `@ApplicationScoped` or `@RequestScoped` on the `MyService` class) – Andy Guibert Aug 16 '18 at 15:15
  • 1
    The `MyService` class is annotated with `@Stateless` – Matteo Codogno Aug 16 '18 at 20:36
  • 1
    Are you sure that CDI is activated for JAX-RS resources? It may need some additional config (I cannot tell, since I do not know Websphere). Is `MyService` `@Stateless`, or `@RequestScoped`? There is not much point in being both! Is it located in the same jar as `MyController`? If not, is there a beans.xml in the jar containing `MyService`? Also make sure `@RequestScoped` is `javax.enterprize.context` and not the one under `javax.faces.bean`! – Nikos Paraskevopoulos Aug 17 '18 at 14:22
  • 1
    Do you access the resource in the usual way directly via an http client? I want to be certain you aren't constructing MyController yourself. – covener Aug 22 '18 at 11:00
  • 1
    @covener yes, I invoke the rest endpoint from web, postman or react native app. – Matteo Codogno Aug 24 '18 at 06:39
  • 1
    How do you initialize jax-rs? Do you have an implementation of Application? With servlet in web.xml? – k5_ Aug 25 '18 at 10:09
  • 1
    @k5_ I updated the question with more details. In my project I've `beans.xml` under the `META-INF` folder and `web.xml` under the `WEB-INF` folder. – Matteo Codogno Aug 27 '18 at 08:22
  • 1
    Have you enabled the [cdi-1.2 feature](https://www.ibm.com/support/knowledgecenter/SSD28V_9.0.0/com.ibm.websphere.wlp.core.doc/ae/twlp_cdi_config.html) in server.xml? – m4gic Aug 28 '18 at 10:22
  • 1
    Please provide Websphere version. – AsSiDe Aug 28 '18 at 11:13
  • 1
    @AsSiDe Websphere libery 8 Launching mfp (WebSphere Application Server 8.5.5.8/wlp-1.0.11.cl50820151201-1942) on Java HotSpot(TM) 64-Bit Server VM, version 1.8.0_172-b11 (en_CH) Console Product version: 8.0.0.00-20180717-175523 – Matteo Codogno Aug 28 '18 at 12:24
  • 1. In which packages your AccountApplication and MyService are defined? 2. What it seems to me is your MyService is in the different module and you're using this maven module as a dependency in another module i.e. your war packaging module or if I'm wrong then AccountApplication and MyService are in the same module and this is your *.war module? Please confirm. 3. FQCN (ie. with package name) of MyController and AccountApplication classes? Please add mentioned details in the original question, I'll form my answer accordingly. – AsSiDe Aug 28 '18 at 14:22
  • @AsSiDe MyService is in the same module of the Controller class. – Matteo Codogno Aug 29 '18 at 12:22
  • @AsSiDe I updated my question with the package info. – Matteo Codogno Aug 29 '18 at 12:27
  • Any reason why your beans.xml is still CDI v1.1 and not v1.2 or v2.0? – titou10 Mar 08 '19 at 01:05

3 Answers3

1

First it seems that websphere jax-rs implementation does not integrate jax-rs resources automatically unless you annotate them appropriately.

Put the jax-rs in a CDI managed context by annotating it appropriately

@Path("/test/")
@javax.enterprise.context.RequestScoped
public class MyController {

    @Inject
    private MyService myService;

    @GET
    @Path("/foo/{count}")
    @OAuthSecurity(scope = "login")
    @Produces("application/json")
    public Response news(@PathParam("count") int count) {
        return Response
                .ok(myService.getBar(count))
                .build();
    }

}

Also be sure that the annotation used for your service is @javax.enterprise.context.RequestScoped

maress
  • 3,533
  • 1
  • 19
  • 37
0

Based on the inputs provided by you please go through the below checklist.

  1. Your services and controllers are in the same module and its packaging type is war, So you must place your beans.xml in this path src/main/resources/WEB-INF/beans.xml. (If this is Java EE 7 application then beans.xml is optional.
  2. In your AccountApplication class try hardcoding the package name to ch.webapp.presentation

    @Override protected String getPackageToScan() { return "ch.webapp.presentation"; }

This is just to check Behaviour of MFPJAXRSApplication.getPackageToScan() method whether it is scanning the specified package only or its child packages too.

  1. Except these, everything seems fine to me. If this still doesn't work add complete application startup logs so that community can find the root cause of it.
AsSiDe
  • 1,826
  • 2
  • 15
  • 24
-2

This is classical mistake. CDI works for managed beans (for instance EJB's and servlets). If you want to enable it on your JAXRS bean, you have to make it "managed", that is annotate MyController as (for instance) javax.annotation.ManagedBean or as a javax.ejb.Stateless.

Also beware that in case of webapp (.war), the beans.xml file has to be located in the WEB-INF folder !

TacheDeChoco
  • 3,683
  • 1
  • 14
  • 17
  • 1
    Which tutorial did you read about the ManagedBean annotation? Each tutorial I have seen does not do this. Even the original 'oracle' tutorial https://javaee.github.io/tutorial/jaxrs-advanced004.html states to do what is done in the other answer (or add stateless like you did) – Kukeltje Aug 27 '18 at 19:18
  • That's the problem of tutorials. They give some examples but do not clearly explain the principles. If you want to inject beans into a bean, your bean has to become "cdi-aware". A JAX-RS bean (resource) is by default not a CDI bean, you have to add annotation to allow injection. You have plenty of different possible annotations (Stateless, Stateful, Singleton, RequestScoped, ApplicationScoped, etc..) and one of these (the most basic actually) is javax.annotation.ManagedBean. – TacheDeChoco Sep 04 '18 at 14:38
  • Please read the doc (https://docs.oracle.com/javaee/6/api/javax/annotation/ManagedBean.html): "the ManagedBean annotation marks a POJO (Plain Old Java Object) as a ManagedBean. A ManagedBean supports a small set of basic services such as resource injection". – TacheDeChoco Sep 04 '18 at 14:38