You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Burton Rhodes <bu...@gmail.com> on 2021/01/21 17:56:25 UTC

NPE using OpenSessionBackgroundProcess class

I have an application that uses the OpenSessionBackgroundProcess class as
described here:
https://docs.huihoo.com/apache/struts/2.1.8/hibernateandspringenabledexecuteandwaitinterceptor.html

It works fine the vast majority of the time, but every once in a while I
get a NPE at the line "synchronized (lock)" in the beforeInvocation()
method.  I am unable to reproduce this error manually and really have no
idea why it occurs.  Anyone have a clue as to how to troubleshoot this so I
can find a solution?

// Method where NPE is thrown
protected void beforeInvocation() throws Exception {
    while (!initializationComplete) {
       try {
            synchronized (lock) {   <-- **** NPE is here ****
                lock.wait(100);
            }
        } catch (InterruptedException e) {
            // behavior ignores cause of re-awakening.
        }
    }
    EntityManager em = entityManagerFactory.createEntityManager();
    TransactionSynchronizationManager.bindResource(entityManagerFactory,
new EntityManagerHolder(em));
    super.beforeInvocation();
}

Stack Trace:
java.lang.Exception: Uncaught error by user,
at
com.afs.web.common.struts.interceptor.ExceptionInterceptor.intercept(ExceptionInterceptor.java:60)
at
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at
org.apache.struts2.factory.StrutsActionProxy.execute(StrutsActionProxy.java:48)
at
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:574)
at
org.apache.struts2.dispatcher.ExecuteOperations.executeAction(ExecuteOperations.java:79)
at
org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:141)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
at
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
at
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:158)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:152)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)
at
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.web.filter.ForwardedHeaderFilter.doFilterInternal(ForwardedHeaderFilter.java:149)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
at
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:186)
at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:543)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.ajp.AjpProcessor.service(AjpProcessor.java:482)
at
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:810)
at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1623)
at
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.NullPointerException: null
at
com.afs.web.common.struts.interceptor.OpenSessionBackgroundProcess.beforeInvocation(OpenSessionBackgroundProcess.java:33)
at
org.apache.struts2.interceptor.BackgroundProcess$1.run(BackgroundProcess.java:54)
... 1 common frames omitted

Re: NPE using OpenSessionBackgroundProcess class

Posted by Martin Gainty <mg...@hotmail.com>.
AFAIK Object does not  implement Serializable

is there an object your code can implement for lock object that implements Serializable?

m-

________________________________
From: Burton Rhodes <bu...@gmail.com>
Sent: Monday, January 25, 2021 1:52 PM
To: Struts Users Mailing List <us...@struts.apache.org>
Subject: Re: NPE using OpenSessionBackgroundProcess class

The complete class is below (and also here: https://pastebin.com/Z8QyTRzM).
It extends org.apache.struts2.interceptor.BackgroundProcess which
implements serializable.  Do I need to explicitly implement?  Or do you see
anything else that might be the cause?  Many thanks.

package com.afs.web.common.struts.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import org.apache.struts2.interceptor.BackgroundProcess;
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
import org.springframework.orm.jpa.EntityManagerHolder;
import
org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 * Used in conjunction with {@link OpenSessionExecuteAndWaitInterceptor}
 */
public class OpenSessionBackgroundProcess extends BackgroundProcess {

EntityManagerFactory entityManagerFactory;
protected boolean initializationComplete;
private Object lock = new Object(); // used for synchronization

public OpenSessionBackgroundProcess(String name, ActionInvocation
invocation, int threadPriority, EntityManagerFactory entityManagerFactory) {
super(name, invocation, threadPriority);
this.entityManagerFactory = entityManagerFactory;
initializationComplete = true;
synchronized (lock) {
lock.notify();
}
}

protected void beforeInvocation() throws Exception {
while (!initializationComplete) {
try {
synchronized (lock) {
lock.wait(100);
}
} catch (InterruptedException e) {
// behavior ignores cause of re-awakening.
}
}
EntityManager em = entityManagerFactory.createEntityManager();
TransactionSynchronizationManager.bindResource(entityManagerFactory, new
EntityManagerHolder(em));
super.beforeInvocation();
}

protected void afterInvocation() throws Exception {
super.afterInvocation();
EntityManagerHolder emHolder = (EntityManagerHolder)
TransactionSynchronizationManager.unbindResource(entityManagerFactory);
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
}

On Fri, Jan 22, 2021 at 2:44 AM Lukasz Lenart <lu...@apache.org>
wrote:

> czw., 21 sty 2021 o 18:56 Burton Rhodes <bu...@gmail.com>
> napisał(a):
> >             synchronized (lock) {   <-- **** NPE is here ****
>
> How is this lock defined? Is it a serializable class?
>
>
> Regards
> --
> Łukasz
> + 48 606 323 122 http://www.lenart.org.pl/
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>

Re: NPE using OpenSessionBackgroundProcess class

Posted by Burton Rhodes <bu...@gmail.com>.
Ahh... many thanks.

On Tue, Jan 26, 2021 at 7:02 AM Lukasz Lenart <lu...@apache.org>
wrote:

> wt., 26 sty 2021 o 13:45 Burton Rhodes <bu...@gmail.com>
> napisał(a):
> >
> > Lukasz -
> > Sorry if this is a dumb question, but where and how do I call the
> > readObject() method that you suggested?
>
> It is used by JVM when an object is deserialized
> https://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html
>
> https://stackoverflow.com/questions/12963445/serialization-readobject-writeobject-overrides
>
>
> Regards
> --
> Łukasz
> + 48 606 323 122 http://www.lenart.org.pl/
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>

Re: NPE using OpenSessionBackgroundProcess class

Posted by Lukasz Lenart <lu...@apache.org>.
wt., 26 sty 2021 o 13:45 Burton Rhodes <bu...@gmail.com> napisał(a):
>
> Lukasz -
> Sorry if this is a dumb question, but where and how do I call the
> readObject() method that you suggested?

It is used by JVM when an object is deserialized
https://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html
https://stackoverflow.com/questions/12963445/serialization-readobject-writeobject-overrides


Regards
-- 
Łukasz
+ 48 606 323 122 http://www.lenart.org.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: NPE using OpenSessionBackgroundProcess class

Posted by Burton Rhodes <bu...@gmail.com>.
Lukasz -
Sorry if this is a dumb question, but where and how do I call the
readObject() method that you suggested?

On Tue, Jan 26, 2021 at 6:33 AM Burton Rhodes <bu...@gmail.com>
wrote:

> Many thanks... I will give that a try!
>
>
> On Tue, Jan 26, 2021 at 1:51 AM Lukasz Lenart <lu...@apache.org>
> wrote:
>
>> pon., 25 sty 2021 o 19:52 Burton Rhodes <bu...@gmail.com>
>> napisał(a):
>> > public class OpenSessionBackgroundProcess extends BackgroundProcess {
>>
>> BackgroundProcess is marked as Serializable so container can
>> temporarily store it on disk
>>
>> > private Object lock = new Object(); // used for synchronization
>>
>> I would mark this as transient and add
>>
>> private void readObject(ObjectInputStream inputStream) throws
>> IOException, ClassNotFoundException {
>>     lock = new Object();
>> }
>>
>> maybe it will help
>>
>>
>> Regards
>> --
>> Łukasz
>> + 48 606 323 122 http://www.lenart.org.pl/
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
>> For additional commands, e-mail: user-help@struts.apache.org
>>
>>

Re: NPE using OpenSessionBackgroundProcess class

Posted by Burton Rhodes <bu...@gmail.com>.
Many thanks... I will give that a try!


On Tue, Jan 26, 2021 at 1:51 AM Lukasz Lenart <lu...@apache.org>
wrote:

> pon., 25 sty 2021 o 19:52 Burton Rhodes <bu...@gmail.com>
> napisał(a):
> > public class OpenSessionBackgroundProcess extends BackgroundProcess {
>
> BackgroundProcess is marked as Serializable so container can
> temporarily store it on disk
>
> > private Object lock = new Object(); // used for synchronization
>
> I would mark this as transient and add
>
> private void readObject(ObjectInputStream inputStream) throws
> IOException, ClassNotFoundException {
>     lock = new Object();
> }
>
> maybe it will help
>
>
> Regards
> --
> Łukasz
> + 48 606 323 122 http://www.lenart.org.pl/
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>

Re: NPE using OpenSessionBackgroundProcess class

Posted by Lukasz Lenart <lu...@apache.org>.
pon., 25 sty 2021 o 19:52 Burton Rhodes <bu...@gmail.com> napisał(a):
> public class OpenSessionBackgroundProcess extends BackgroundProcess {

BackgroundProcess is marked as Serializable so container can
temporarily store it on disk

> private Object lock = new Object(); // used for synchronization

I would mark this as transient and add

private void readObject(ObjectInputStream inputStream) throws
IOException, ClassNotFoundException {
    lock = new Object();
}

maybe it will help


Regards
-- 
Łukasz
+ 48 606 323 122 http://www.lenart.org.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: NPE using OpenSessionBackgroundProcess class

Posted by Burton Rhodes <bu...@gmail.com>.
The complete class is below (and also here: https://pastebin.com/Z8QyTRzM).
It extends org.apache.struts2.interceptor.BackgroundProcess which
implements serializable.  Do I need to explicitly implement?  Or do you see
anything else that might be the cause?  Many thanks.

package com.afs.web.common.struts.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import org.apache.struts2.interceptor.BackgroundProcess;
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
import org.springframework.orm.jpa.EntityManagerHolder;
import
org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 * Used in conjunction with {@link OpenSessionExecuteAndWaitInterceptor}
 */
public class OpenSessionBackgroundProcess extends BackgroundProcess {

EntityManagerFactory entityManagerFactory;
protected boolean initializationComplete;
private Object lock = new Object(); // used for synchronization

public OpenSessionBackgroundProcess(String name, ActionInvocation
invocation, int threadPriority, EntityManagerFactory entityManagerFactory) {
super(name, invocation, threadPriority);
this.entityManagerFactory = entityManagerFactory;
initializationComplete = true;
synchronized (lock) {
lock.notify();
}
}

protected void beforeInvocation() throws Exception {
while (!initializationComplete) {
try {
synchronized (lock) {
lock.wait(100);
}
} catch (InterruptedException e) {
// behavior ignores cause of re-awakening.
}
}
EntityManager em = entityManagerFactory.createEntityManager();
TransactionSynchronizationManager.bindResource(entityManagerFactory, new
EntityManagerHolder(em));
super.beforeInvocation();
}

protected void afterInvocation() throws Exception {
super.afterInvocation();
EntityManagerHolder emHolder = (EntityManagerHolder)
TransactionSynchronizationManager.unbindResource(entityManagerFactory);
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
}

On Fri, Jan 22, 2021 at 2:44 AM Lukasz Lenart <lu...@apache.org>
wrote:

> czw., 21 sty 2021 o 18:56 Burton Rhodes <bu...@gmail.com>
> napisał(a):
> >             synchronized (lock) {   <-- **** NPE is here ****
>
> How is this lock defined? Is it a serializable class?
>
>
> Regards
> --
> Łukasz
> + 48 606 323 122 http://www.lenart.org.pl/
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>

Re: NPE using OpenSessionBackgroundProcess class

Posted by Lukasz Lenart <lu...@apache.org>.
czw., 21 sty 2021 o 18:56 Burton Rhodes <bu...@gmail.com> napisał(a):
>             synchronized (lock) {   <-- **** NPE is here ****

How is this lock defined? Is it a serializable class?


Regards
-- 
Łukasz
+ 48 606 323 122 http://www.lenart.org.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org