NullPointerException in JpaPersistService

210 views
Skip to first unread message

Diogo Luzzardi de Carvalho

unread,
Dec 1, 2017, 2:27:05 PM12/1/17
to google-guice
The following exception is ocorring for me:

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)


Follows my persistence.xml:

<?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>


follows the configuration code:

persistModule = new JpaPersistModule(PERSISTENCE_UNIT_NAME);


install(persistModule);


bind(org.hibernate.Session.class).toProvider(new SessionProvider());


filter("/*").through(PersistFilter.class);



can anyone point me what I'm doing wrong?

regards
Diogo

Stephan Classen

unread,
Dec 1, 2017, 4:44:45 PM12/1/17
to google...@googlegroups.com

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.

Message has been deleted

Diogo Luzzardi de Carvalho

unread,
Dec 1, 2017, 5:25:58 PM12/1/17
to google-guice


On Friday, December 1, 2017 at 8:18:46 PM UTC-2, Diogo Luzzardi de Carvalho wrote:

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;

}

}

Stephan Classen

unread,
Dec 1, 2017, 5:31:11 PM12/1/17
to google...@googlegroups.com, Diogo Luzzardi de Carvalho

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();
    try {
      // do your work here
    } finally {
      unitOfWork.end();

    }


On 01.12.2017 23:18, Diogo Luzzardi de Carvalho wrote:

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);

Stephan Classen

unread,
Dec 1, 2017, 5:42:53 PM12/1/17
to google...@googlegroups.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.

Diogo Luzzardi de Carvalho

unread,
Dec 4, 2017, 10:22:22 AM12/4/17
to google-guice
Hi,

I tried both of your solutions, and the nullpointer keeps happen. Also I debug the application and I installed the JpaPersistModule before I try to run the code when the exception happens.

regards
Diogo

Stephan Classen

unread,
Dec 4, 2017, 10:24:10 AM12/4/17
to google...@googlegroups.com

Is this an open source project?
If sou you could point me to the repo and I can have a look.

Diogo Luzzardi de Carvalho

unread,
Dec 4, 2017, 10:58:13 AM12/4/17
to google-guice
Unfortunately it is not. I notice that when I change my code to do the following:
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;

 The injector was able to inject the UnitOfWork but when I call the method unitOfWork.begin() the exception occurs at line 77 of the JpaPersistService.

Stephan Classen

unread,
Dec 4, 2017, 11:04:00 AM12/4/17
to google...@googlegroups.com

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

Diogo Luzzardi de Carvalho

unread,
Dec 4, 2017, 11:43:33 AM12/4/17
to google-guice
humm, at moment I call the appLifeCycle.init() the PersistFilter is already configured in the application because it is configured at the MainModule class configure method. There is any other way to make the persistService to start?

Stephan Classen

unread,
Dec 11, 2017, 7:30:50 AM12/11/17
to google...@googlegroups.com

Did you make any progress on this issue?

Reply all
Reply to author
Forward
0 new messages