Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to inject @ApplicationScoped bean in JAX-RS service

I've created JAX-RS service in which I want to inject an application scoped bean. The problem is that the bean is not injected. How is this caused and how can I solve it?

JAX-RS service:

@Path("room")
public class RoomService {

    @Inject
    GameController gc;

    public RoomService() {}

    @Path("create")
    @GET
    @Produces("application/json")
    public String create() {
        Room r = new Room();
        gc.addRoom(r); // gc is null
        return r.toJson();
    }
}

Application scoped bean

import java.util.ArrayList;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import pepuch.multuplayergameserver.entity.Game;
import pepuch.multuplayergameserver.entity.Room;

@Named
@ApplicationScoped
public class GameController {

    private Game game;

    public GameController() {
        this.game = new Game(new ArrayList<Room>());
    }

    public boolean addRoom(Room room) {
        if (!game.getRooms().contains(room)) {
            return game.getRooms().add(room);
        }

        return false;
    }

}
like image 736
pepuch Avatar asked Mar 16 '13 18:03

pepuch


2 Answers

You need to make the bean a managed resource to make it eligible for injection. At the bare minimum, add @RequestScoped to the JAX-RS SIB to make it injection-worthy.

Another alternative annotation is @ManagedBean. The point is , Jersey won't address the desired injection target, if the parent bean is not in a managed context

import javax.enterprise.context.RequestScoped

@RequestScoped
@Path("room")
public class RoomService {

    @Inject
    GameController gc;

    public RoomService() {}

    @Path("create")
    @GET
    @Produces("application/json")
    public String create() {
        Room r = new Room();
        gc.addRoom(r); // gc is null
        return r.toJson();
    }
}

EDIT: be sure to have a beans.xml file in your WEB-INF folder. Your beans.xml file will look something like:

  <beans xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee     http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">   

  </beans>

EDIT: Based on this JIRA, you may replace @RequestScoped with @ManagedBean

like image 197
kolossus Avatar answered Sep 17 '22 13:09

kolossus


The built-in context object is active during servlet, web service and EJB invocations, or in the case of the conversation context object, for JSF requests.

You may have difficulty accessing request,scope and application beans from JAX-RS service as it doesn't clearly states the support for this , however in your case it seems like you just need a singleton rather than a context based bean.

Keep it like this if you are using CDI (beans.xml),

@Singleton
public class GameController {
    private Game game;
    public GameController() {
        this.game = new Game(new ArrayList<Room>());
    }
....
}

If you are using CDI with Spring (no beans.xml) then keep the @Named

@Named
@Singleton
public class GameController {
    private Game game;
    public GameController() {
        this.game = new Game(new ArrayList<Room>());
    }
....
}

If the above doesn't work then I will suggest marking your JAX-RS service as @ManagedBean along with the above change as it is unclear if CDI manages JAX-RS service.

like image 35
Avinash Singh Avatar answered Sep 18 '22 13:09

Avinash Singh