[jboss-jira] [JBoss JIRA] (DROOLS-1030) Nullpointer in JpaTimerJobInstance.call on startup
Mario Fusco (JIRA)
issues at jboss.org
Fri Jan 22 12:07:00 EST 2016
[ https://issues.jboss.org/browse/DROOLS-1030?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13152635#comment-13152635 ]
Mario Fusco commented on DROOLS-1030:
-------------------------------------
Reproduce with the following test class
{code}
package org.drools.persistence.session;
import org.drools.persistence.util.PersistenceUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.definition.type.Expires;
import org.kie.api.definition.type.Role;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.Environment;
import org.kie.api.runtime.rule.EntryPoint;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.persistence.jpa.JPAKnowledgeService;
import org.kie.internal.runtime.StatefulKnowledgeSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.naming.InitialContext;
import javax.transaction.UserTransaction;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static org.drools.persistence.util.PersistenceUtil.DROOLS_PERSISTENCE_UNIT_NAME;
import static org.drools.persistence.util.PersistenceUtil.createEnvironment;
import static org.junit.Assert.fail;
@Ignore
public class JpaPersistentCepSessionTest {
private static ExecutorService executor = Executors.newSingleThreadExecutor();
private static Logger logger = LoggerFactory.getLogger( JpaPersistentCepSessionTest.class );
private HashMap<String, Object> context;
private Environment env;
@Before
public void setUp() throws Exception {
context = PersistenceUtil.setupWithPoolingDataSource( DROOLS_PERSISTENCE_UNIT_NAME );
env = createEnvironment(context);
}
@After
public void tearDown() throws Exception {
PersistenceUtil.cleanUp(context);
}
@Test
public void test1() throws Exception {
KnowledgeBase kbase = getKnowledgeBase( );
UserTransaction ut = (UserTransaction) new InitialContext().lookup( "java:comp/UserTransaction" );
ut.begin();
final StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );
ut.commit();
EntryPoint entryPoint = ksession.getEntryPoint( "EntryPointA" );
MyEvent e = new MyEvent();
e.setUsers(get());
MySecondEvent event = new MySecondEvent();
event.setType("SomeType");
ut = (UserTransaction) new InitialContext().lookup( "java:comp/UserTransaction" );
ut.begin();
entryPoint.insert(e);
ksession.insert(event);
ut.commit();
executor.execute( new Runnable() {
@Override
public void run() {
ksession.fireAllRules();
}
} );
// ksession.fireAllRules();
Thread.sleep(10000L);
System.out.println("IDENTIFIER = " + ksession.getIdentifier());
}
@Test
public void test2() throws Exception {
long identifier = 19L;
KnowledgeBase kbase = getKnowledgeBase( );
final StatefulKnowledgeSession ksession = JPAKnowledgeService.loadStatefulKnowledgeSession( identifier, kbase, null, env );
MyEvent e = new MyEvent();
e.setUsers(get());
EntryPoint entryPoint = ksession.getEntryPoint("EntryPointA");
UserTransaction ut = (UserTransaction) new InitialContext().lookup( "java:comp/UserTransaction" );
ut.begin();
entryPoint.insert(e);
ut.commit();
executor.execute( new Runnable() {
@Override
public void run() {
ksession.fireAllRules();
}
} );
Thread.sleep(10000L);
}
public KnowledgeBase getKnowledgeBase( ) {
String str =
"import " + MyEvent.class.getCanonicalName() + "\n" +
"import " + MyModel.class.getCanonicalName() + "\n" +
"import " + MySecondEvent.class.getCanonicalName() + "\n" +
"rule \"Rule1\"\n" +
"\n" +
" when\n" +
" MyEvent( $new_users : users) from entry-point \"EntryPointA\";\n" +
" $p : MyModel() from $new_users;\n" +
" then\n" +
" System.out.println(\"Added model: \" + $p);\n" +
" insert( $p );\n" +
" \n" +
"end\n" +
"\n" +
"rule \"Rule2\"\n" +
" \n" +
" when\n" +
" $e : MySecondEvent( type == \"SomeType\");\n" +
" $p : MyModel( processed == false );\n" +
" then\n" +
" System.out.println( $p);\n" +
" $p.setProcessed(true);\n" +
" update($p)\n" +
"end\n";
KieBaseConfiguration kbconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
kbconf.setOption( EventProcessingOption.STREAM );
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newByteArrayResource( str.getBytes() ), ResourceType.DRL );
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbconf);
if ( kbuilder.hasErrors() ) {
fail( kbuilder.getErrors().toString() );
}
kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
return kbase;
}
public static List<MyModel> get() {
List<MyModel> res = new ArrayList<MyModel>();
for(int i=0; i< 10; i++) {
MyModel m = new MyModel();
m.setName( UUID.randomUUID().toString() );
res.add(m);
}
return res;
}
@Role(Role.Type.EVENT)
@Expires("1m")
public static class MyEvent implements Serializable {
private List<MyModel> users = new ArrayList<MyModel>();
public void setUsers(List<MyModel> users) {
this.users = users;
}
public List<MyModel> getUsers() {
return users;
}
}
@Role(Role.Type.EVENT)
@Expires("1m")
public static class MyModel implements Serializable {
private String name;
private boolean processed;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
public void setProcessed(boolean processed) {
this.processed = processed;
}
public boolean isProcessed() {
return processed;
}
}
@Role(Role.Type.EVENT)
@Expires("1s")
public static class MySecondEvent implements Serializable {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
}
{code}
> Nullpointer in JpaTimerJobInstance.call on startup
> ---------------------------------------------------
>
> Key: DROOLS-1030
> URL: https://issues.jboss.org/browse/DROOLS-1030
> Project: Drools
> Issue Type: Bug
> Components: core engine
> Environment: Mac OS 10.10.5, Eclipse Mars Release, Java 1.8, Drools 6.3.0.Final
> Reporter: Artur Kronenberg
> Assignee: Mario Fusco
> Attachments: test-standalone.zip
>
>
> Hi,
> I have noticed Nullpointer exceptions when I try and reload a persisted session on startup. It is a bit hard to recreate (I am actually not managing it now since I deleted all old sessions to attempt recreation) but I figured maybe someone has an idea. Essentially I am getting this NPE twice:
> java.lang.NullPointerException: null
> at org.drools.persistence.jpa.JpaTimerJobInstance.call(JpaTimerJobInstance.java:50) [drools-persistence-jpa-6.3.0.Final.jar:6.3.0.Final]
> at org.drools.persistence.jpa.JpaTimerJobInstance.call(JpaTimerJobInstance.java:30) [drools-persistence-jpa-6.3.0.Final.jar:6.3.0.Final]
> at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_51]
> at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_51]
> at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_51]
> at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_51]
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_51]
> at java.lang.Thread.run(Thread.java:745) [na:1.8.0_51]
> When debugging I noticed the following behaviour which points to a race condition:
> If I start my server and try to recreate the session, those NPEs happen 2x.
> If I start my server and put a breakpoint BEFORE creating the CommandService for execution, I can wait for a few seconds and the service can be found.
> It appears that the scheduler's timerJobFactoryManager is not fully there at the time the sessions is being loaded? Or something else is racing with the service creation.
> Is there a way for me to make sure everything is fully instantiated before I use drools? Does a workaround exist? Is this even a bug?
> Thanks and let me know your thoughts. If I run into this again I will attempt to try and reproduce it. Let me know if more info is needed!
> UPDATE:
> I noticed that the reason I can't reproduce it at the moment is that the JpaTimerJobInstance is never called with the newly persisted session. It appears that that timer job depends on something else to happen so that it thinks it needs to start the timerJob
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
More information about the jboss-jira
mailing list