ptoinson
ptoinson

Reputation: 2051

Jersey Inject RequestScoped IllegalStateException

Been working on this one for hours and nothing seems to work. It's Jersey 2.23.2. The idea is that I want to inject a request based Hibernate Session into a Jersey provider to use in my REST API. Instead, I get this:

javax.servlet.ServletException: A MultiException has 2 exceptions.  They are:
1. java.lang.IllegalStateException: Could not find an active context for javax.enterprise.context.RequestScoped
2. java.lang.IllegalStateException: While attempting to create a service for SystemDescriptor(
    implementation=com.pixmoto.api.server.SFFactory
    contracts={org.hibernate.Session}
    scope=javax.enterprise.context.RequestScoped
    qualifiers={}
    descriptorType=PROVIDE_METHOD
    descriptorVisibility=NORMAL
    metadata=
    rank=0
    loader=org.glassfish.hk2.utilities.binding.AbstractBinder$2@6e9becd5
    proxiable=null
    proxyForSameScope=null
    analysisName=null
    id=129
    locatorId=0
    identityHashCode=1082491454
    reified=true) in scope javax.enterprise.context.RequestScoped an error occured while locating the context

Here's my code:

public class JerseyResourceConfig extends ResourceConfig {

    public JerseyResourceConfig() {
        packages(this.getClass().getPackage().getName() + ";org.codehaus.jackson.jaxrs");

        register(new AbstractBinder(){
            @Override
            protected void configure() {
                bindFactory(SFFactory.class)
                .to(Session.class)
                .in(RequestScoped.class);
            }
        });
    }
}

public class App {

    private static final Logger logger = LogManager.getLogger(App.class);

    public static void main(String[] args) throws Exception {

        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);

        Server jettyServer = new Server(8080);

        Slf4jRequestLog requestLog = new Slf4jRequestLog();
        requestLog.start();
        jettyServer.setRequestLog(requestLog);

        ClassList classlist = ClassList.setServerDefault(jettyServer);
        classlist.addAfter(
                "org.eclipse.jetty.webapp.FragmentConfiguration", 
                "org.eclipse.jetty.plus.webapp.EnvConfiguration", 
                "org.eclipse.jetty.plus.webapp.PlusConfiguration");

        jettyServer.setHandler(context);

        JerseyResourceConfig config = new JerseyResourceConfig();
        ServletHolder servlet = new ServletHolder(new ServletContainer(config));
        context.addServlet(servlet, "/*");

        try {
            jettyServer.start();
            jettyServer.join();
        } catch (Exception ex) {
            logger.error(ex);
            throw ex;
        } finally {
            jettyServer.destroy();
        }
    }
}

@Path("/api/users")
@Produces(MediaType.APPLICATION_JSON)
public class UserProvider {

    @Inject
    private javax.inject.Provider<Session> session;

    @GET
    public List<User> getUsers() {

        Session s = session.get();
        List<User> users = s.createQuery( "from User", User.class).getResultList();
        return users;
    }
}

public class SFFactory implements Factory<Session> {

    private final SessionFactory sessionFactory;

    public SFFactory() {

     this.sessionFactory = new Configuration()
                .configure() // configures settings from hibernate.cfg.xml
                .buildSessionFactory();
    }

    @Override
    public Session provide() {
        return sessionFactory.openSession();
    }

    @Override
    public void dispose(Session session) {
        if (session.isOpen()) {
            session.close();
        }
    }
}

I've tried what seems like hundreds of permutations. Tirelessly searched the web. As long as I have spent looking at this with no resolution, I'm figuring it must be something really simple.

I can get it to bind when I specify Singleton rather than RequestScoped in the AbstractBinder configure method, but that is not what I would like. I would like a new Session on every request for a single SessionFactory.

I don't have any more hair to pull out. Any help would be immensely appreciated.

Upvotes: 5

Views: 2491

Answers (1)

Paul Samsotha
Paul Samsotha

Reputation: 209052

You're using the wrong RequestScoped (you're using the CDI one). You should be using the Jersey specific one.

Upvotes: 7

Related Questions