Reputation: 2051
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
Reputation: 209052
You're using the wrong RequestScoped
(you're using the CDI one). You should be using the Jersey specific one.
Upvotes: 7