java.lang.NullPointerException
at com.google.inject.persist.jpa.JpaPersistService.begin(JpaPersistService.java:77)
at com.google.inject.persist.jpa.JpaLocalTxnInterceptor.invoke(JpaLocalTxnInterceptor.java:53)
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<!-- A JPA Persistence Unit -->
<persistence-unit name="persistence.unit"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!-- JPA entities must be registered here -->
<!--<class>com.wideplay.warp.jpa.JpaTestEntity</class> -->
</persistence-unit>
</persistence>
persistModule = new JpaPersistModule(PERSISTENCE_UNIT_NAME);
install(persistModule);
bind(org.hibernate.Session.class).toProvider(new SessionProvider());
filter("/*").through(PersistFilter.class);
Can you please give more of the stack trace (all of it).
Because the cause of this NPE is different depending on where the
call comes from.
--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice...@googlegroups.com.
To post to this group, send email to google...@googlegroups.com.
Visit this group at https://groups.google.com/group/google-guice.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/fd020b11-2a91-4656-9c49-6f5b0fef744e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
java.lang.NullPointerException
at com.google.inject.persist.jpa.JpaPersistService.begin(JpaPersistService.java:77)
at com.google.inject.persist.jpa.JpaLocalTxnInterceptor.invoke(JpaLocalTxnInterceptor.java:53)
at com.app.guice.AppGuiceServletContextListener.contextInitialized(AppGuiceServletContextListener.java:60)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1234)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:460)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
at org.mortbay.jetty.Server.doStart(Server.java:222)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at com.app.Start.start(Start.java:126)
at com.app.Start.main(Start.java:194)
Follows my servlet context listener:
package com.app.guice;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import org.mortbay.jetty.Server;
import com.app.setup.AppLifeCycle;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.servlet.GuiceServletContextListener;
public class AppGuiceServletContextListener extends GuiceServletContextListener {
private AppLifeCycle appLifeCycle;
private Server server;
private ServletContext servletContext;
private Injector injector;
public AppGuiceServletContextListener(Server server) {
super();
this.server = server;
}
@Override
public void contextDestroyed(ServletContextEvent ctx) {
super.contextDestroyed(ctx);
if (appLifeCycle != null) {
appLifeCycle.destroy();
}
}
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
servletContext = servletContextEvent.getServletContext();
super.contextInitialized(servletContextEvent);
appLifeCycle = injector.getInstance(AppLifeCycle.class);
appLifeCycle.init(servletContext);
}
@Provides
@Singleton
Server provideServer(Injector injector) {
final Server server = this.server;
injector.injectMembers(server);
return server;
}
@Override
protected Injector getInjector() {
System.out.println(servletContext);
if (injector == null)
injector = Guice.createInjector(new MainModule(String.format("%s/WEB-INF/app", servletContext.getRealPath("/")), servletContext));
return injector;
}
}
OK, this is easy to fix.
Guice JPA needs a running UnitOfWork in order to function. The
UnitOfWork is a thread local context and therefore needs to be
started and stopped for every thread which wants to make use of
JPA.
Be advised that you must end the UnitOfWork because starting it a
second time without ending it first will trigger an exception (and
sadly there is no way to test if the UnitOfWork is already
running...)
The PersistFilter takes care of this in 99% of the cases.
It is registerd as a ServletFilter and starts a UnitOfWork
whenever a request enters the server and ends it when the result
is returned to the client.
You are now starting a transaction from somewhere within the
contextInitialized() method. So you are not in a request thread.
As a consequence you need to manually control the UnitOfWork.
This can be done easily:
@Inject the UnitOfWork and then add the following code:
unitOfWork.begin();
java.lang.NullPointerException
at com.google.inject.persist.jpa.JpaPersistService.begin(JpaPersistService.java:77)
at com.google.inject.persist.jpa.JpaLocalTxnInterceptor.invoke(JpaLocalTxnInterceptor.java:53)
at com.eckertcaine.bridge.guice.BridgeGuiceServletContextListener.contextInitialized(AppGuiceServletContextListener.java:60)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1234)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:460)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
at org.mortbay.jetty.Server.doStart(Server.java:222)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at com.eckertcaine.bridge.Start.start(Start.java:126)
at com.eckertcaine.bridge.Start.main(Start.java:194)
if (injector == null)
injector = Guice.createInjector(new MainModule(String.format("%s/WEB-INF/app", servletContext.getRealPath("/")), servletContext));
return injector;
}
}
the line that points the error on the context listener is appLifeCycle.init(servletContext);
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/5e2af91c-af64-4b65-8f72-bf4e74499ff1%40googlegroups.com.
A second cause could be that the PersistenceService has not been
started yet.
The persistence service is started by the PersistFiler.init()
method.
Unfortunately there is no way of checking if the PersistanceService is already started. And trying to start it twice will cause an exception the be thrown.
So my advice:
Make sure to delay the accessing of the DB until after the
PersistFiler.init() method and wrap your code in a UnitOfWork.
The simplest trick is to register another ServletFilter after the
PersistFilter and place your code in the init() method of this
filter...
You may also have a look at Onami Persist which is an alternative implementation (but without @Finder)
--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice...@googlegroups.com.
To post to this group, send email to google...@googlegroups.com.
Visit this group at https://groups.google.com/group/google-guice.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/4df2e8df-81e9-4523-80c6-b4c1cfafa763%40googlegroups.com.
Is this an open source project?
If sou you could point me to the repo and I can have a look.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/643a15e6-bbaa-4f9a-ab2e-deaea5461f77%40googlegroups.com.
injector = Guice.createInjector(new MainModule(String.format("%s/WEB-INF/app", getServletContext().getRealPath("/")), getServletContext())); UnitOfWork unitOfWork = injector.getInstance(UnitOfWork.class); System.out.println(unitOfWork); unitOfWork.begin(); try { appLifeCycle = injector.getInstance(AppLifeCycle.class); appLifeCycle.init(getServletContext()); } finally { unitOfWork.end(); }
return injector;
This is what I mentioned before.
You cannot use any of the JPA stuff until PersistService.start()
has been called.
This will be called by the PersistFilter.init().
So you have to wait with the appLifeCycle.init() until after the
init() method of PersistFilter
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/5bd6aa1d-2efc-453c-ba78-707bc1e74043%40googlegroups.com.
Did you make any progress on this issue?
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/a86f2bcc-26b6-499a-97b3-ba28de701295%40googlegroups.com.