Bug 1002481 - SwitchYard Drools CEP no longer supports Exchange which leads to NPE
SwitchYard Drools CEP no longer supports Exchange which leads to NPE
Status: CLOSED CURRENTRELEASE
Product: JBoss Fuse Service Works 6
Classification: JBoss
Component: Rules / jBPM integration, SwitchYard (Show other bugs)
6.0.0 GA
Unspecified Unspecified
urgent Severity urgent
: ER3
: 6.0.0
Assigned To: David Ward
Jiri Pechanec
: TestBlocker
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2013-08-29 05:57 EDT by Martin Vecera
Modified: 2014-06-16 19:48 EDT (History)
4 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed:
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
Application resources (2.54 KB, application/x-xz)
2013-08-29 06:04 EDT, Martin Vecera
no flags Details
Artifacts in different format (2.61 KB, application/x-compressed-tar)
2013-08-30 09:39 EDT, Martin Vecera
no flags Details
Test sources (1.69 KB, application/x-gzip)
2013-09-02 07:50 EDT, Martin Vecera
no flags Details
Standalone reproducer (102.91 KB, application/x-gzip)
2013-09-03 07:01 EDT, Martin Vecera
no flags Details
cepnull.zip - standalone reproducer w/o Arquillian (28.78 KB, application/zip)
2013-09-03 08:53 EDT, Keith Babo
no flags Details


External Trackers
Tracker ID Priority Status Summary Last Updated
JBoss Issue Tracker SWITCHYARD-1689 Major Closed Wrong classloader set in FireUntilHalt thread of Rules component 2014-09-08 09:31:51 EDT

  None (edit)
Description Martin Vecera 2013-08-29 05:57:20 EDT
I have a simple Drools service with a CEP rule listening on an entry point. From this rule I send an object to another service using channels. This leads to the following exception:
11:14:00,417 DEBUG [org.switchyard.internal.EventManager] (pool-1-thread-4) Observer threw exception on event class org.switchyard.runtime.event.ExchangeCompletionEvent: java.lang.NullPointerException
	at org.switchyard.admin.base.SwitchYardBuilder.exchangeCompleted(SwitchYardBuilder.java:138)
	at org.switchyard.admin.base.SwitchYardBuilder.notify(SwitchYardBuilder.java:110)
	at org.switchyard.internal.EventManager.publish(EventManager.java:52) [switchyard-runtime-1.1.0.M1-redhat-1.jar:1.1.0.M1-redhat-1]
	at org.switchyard.bus.camel.CamelExchange.sendInternal(CamelExchange.java:232) [switchyard-bus-camel-1.1.0.M1-redhat-1.jar:1.1.0.M1-redhat-1]
	at org.switchyard.bus.camel.CamelExchange.send(CamelExchange.java:174) [switchyard-bus-camel-1.1.0.M1-redhat-1.jar:1.1.0.M1-redhat-1]
	at org.switchyard.component.bean.ClientProxyBean$ClientProxyInvocationHandler.invoke(ClientProxyBean.java:311) [switchyard-component-bean-1.1.0.M1-redhat-1.jar:1.1.0.M1-redhat-1]
	at com.sun.proxy.$Proxy194.heartBeat(Unknown Source)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_25]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_25]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_25]
	at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_25]
	at org.jboss.weld.bean.proxy.AbstractBeanInstance.invoke(AbstractBeanInstance.java:45) [weld-core-1.1.13.Final-redhat-1.jar:1.1.13.Final-redhat-1]
	at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105) [weld-core-1.1.13.Final-redhat-1.jar:1.1.13.Final-redhat-1]
	at org.jboss.weld.proxies.CEPService$1366014918$Proxy$_$$_WeldClientProxy.heartBeat(CEPService$1366014918$Proxy$_$$_WeldClientProxy.java) [weld-core-1.1.13.Final-redhat-1.jar:]
	at org.jboss.soa.qa.drools.cep.CEPService$heartBeat.call(Unknown Source)


The code in SwitchYardBuilder tries to obtain provider Exchange.getProvider() which returns null. This is no wonder since the in the last build of SOA-P I was not able to set provider to Drools globals in my service.

Comments in SwitchYardBuilder.exchangeCompleted(ExchangeCompletionEvent event) indicates that this is just a statistics colletion. So this should be rewritten.
Comment 1 Martin Vecera 2013-08-29 06:04:17 EDT
Created attachment 791675 [details]
Application resources
Comment 2 Keith Babo 2013-08-30 08:44:37 EDT
I'm not clear on what's meant by this comment:
"This is no wonder since the in the last build of SOA-P I was not able to set provider to Drools globals in my service."

You should never have to set provider in application code.  The provider is set by the runtime.  I would like to view the reproducer, but xz is not recognized by the version of tar in OS X so another format (gz, zip, tar) would help me out a lot.
Comment 3 Martin Vecera 2013-08-30 09:39:24 EDT
Created attachment 792182 [details]
Artifacts in different format

Unfortunatelly, I do not have a standalone reproducer at the moment. I can create one if needed. Attached are the important files. 

By setting the provider I meant configuring it in JBDS in Rules Component, Properties, Implementation, Operations, Globals and adding exchange.provider.name. This way I wanted to set the service name in a global variable...
Comment 4 Keith Babo 2013-08-30 12:55:54 EDT
Thanks, I can view the artifacts now.  How are you driving the test?  I see there's a DroolsCEPServiceTest in switchyard.xml that's not included in the tar.  A reproducer would help a lot, but just knowing what drives the test will help too.
Comment 5 Martin Vecera 2013-09-02 07:50:58 EDT
Created attachment 792800 [details]
Test sources

I just inject the service and call it. Attaching the test sources.
Comment 6 Keith Babo 2013-09-02 09:18:32 EDT
The Groovy test with Arquillian looks cool, but this is pretty far outside our normal test suite.  At this stage, we need a test case which uses our own unit test framework or a deployable application that can be driven externally (either through a test client you provide or through a gateway binding like SOAP).
Comment 7 Martin Vecera 2013-09-03 02:58:33 EDT
It does not do anything difficult, it just directly calls the service...
It will take me some time to create a standalone reproducer, so this is why I originally skipped it hoping the description is sufficient. Meanwhile, if you look at org.switchyard.admin.base.SwitchYardBuilder.exchangeCompleted you can see
        Exchange exchange = event.getExchange();
        QName serviceName = exchange.getProvider().getName();
The problem is that exchange is null.
Comment 8 Martin Vecera 2013-09-03 07:01:12 EDT
How to run the reproducer:

0) Reconfigure sample-settings.xml to contain correct paths. You need full ER1 repo.
1) tests/parents/parent mvn -s sample-settings.xml package install -DskipTests
2) tests/qa mvn -s sample-settings.xml package install -DskipTests
2b) now you can import tests/switchyard/drools-cep-test to JBDS supposing you have appropriate Maven config in Eclipse (the same repositories and local repo are used)
3) tests/switchyard mvn -s sample-settings.xml package install -DskipTests
4) start SOA-P standalone-full.xml in out of the box config
5) tests/switchyard/drools-cep-test mvn -s sample-settings.xml integration-test
Comment 9 Martin Vecera 2013-09-03 07:01:46 EDT
Created attachment 793122 [details]
Standalone reproducer
Comment 10 Keith Babo 2013-09-03 08:02:06 EDT
I will try and run the reproducer as is, but this is pretty far away from a supported scenario in the product based on how Arquillian is being used with injection of a SY reference in the test application. The reason I wanted a standalone reproducer is that it eliminates any possible bootstrap/lifecycle issues when using Arquillian.
Comment 11 Keith Babo 2013-09-03 08:04:53 EDT
Re: the NPE, this has no impact on the actual message flow as the admin layer catches any exceptions when processing events so they do not interrupt the processing of messages.  That's why the exception itself is printed at DEBUG - the scope of the failure here is that metrics could not be collected on the exchange.
Comment 12 Keith Babo 2013-09-03 08:53:49 EDT
Created attachment 793180 [details]
cepnull.zip - standalone reproducer w/o Arquillian
Comment 13 Keith Babo 2013-09-03 08:54:34 EDT
I went ahead and created a new standalone application to reproduce this using the artifacts provided.  I added an SCA binding and introduced a remote test client to replace the use of reference injection in Arquillian.  I am able to see the NPE in DEBUG output with this application, but I want to reiterate that this is not the root cause of the issue here.  The following exception info from the message trace does point to something though:

CamelExceptionCaught : java.lang.IllegalStateException: Unable to find BeanManager. Please ensure that you configured the CDI implementation of your choice properly.

My suspicion here is that the class loader chain used for dispatch on the Drools channel is not being set correctly (or is being reset somewhere by Drools), which causes the CDI BeanManager lookup to fail.  Kicking this over to David to debug deeper.  

David - the attached cepnull.zip will allow you to reproduce.  You should be able to test using a 1.0.0.Final or 1.1.0-SNAPSHOT build if you don't have a SOA-P 6 build around.
Comment 14 David Ward 2013-09-08 19:38:24 EDT
I was able to reproduce this with Keith's example.  It is indeed the classloader used in the FireUntilHalt thread that is spawned which is incorrect, causing the BeanManager to not be found.  I tested a fix that works.  i.e.: After the fix, there is no more exception, and the demo application's AuditorCEPServiceBean is properly invoked.  I will now create a jira and submit a pull request.
Comment 15 David Ward 2013-09-08 19:40:16 EDT
PS: This had absolutely nothing to do with "exchange" being available for use as a variable.  So, this line in the switchyard.xml:

<rules:global from="exchange.serviceName.localPart" to="service"/>

should be removed, and these line in the RulesComponent.drl should be removed/modified as well:

global java.lang.String service
System.out.println("In service: CEPService(" + service + "), payload: " + message.getContent() + ", context: " + context);
Comment 16 JBoss JIRA Server 2013-09-08 20:15:13 EDT
David Ward <dward@jboss.org> made a comment on jira SWITCHYARD-1689

https://github.com/jboss-switchyard/components/pull/561
Comment 17 Martin Vecera 2013-09-09 04:27:52 EDT
(In reply to David Ward from comment #15)
> PS: This had absolutely nothing to do with "exchange" being available for
> use as a variable.  So, this line in the switchyard.xml:
> 
> <rules:global from="exchange.serviceName.localPart" to="service"/>
> 
> should be removed, and these line in the RulesComponent.drl should be
> removed/modified as well:
> 
> global java.lang.String service
> System.out.println("In service: CEPService(" + service + "), payload: " +
> message.getContent() + ", context: " + context);

Yes, it became clear too me later. Sorry for the misleading analysis...
Comment 18 JBoss JIRA Server 2013-09-10 08:58:45 EDT
Keith Babo <kbabo@redhat.com> made a comment on jira SWITCHYARD-1689

pushed
Comment 22 Jiri Pechanec 2013-12-18 07:34:11 EST
Verified in ER7
Comment 23 JBoss JIRA Server 2014-06-16 19:48:02 EDT
Keith Babo <kbabo@redhat.com> updated the status of jira SWITCHYARD-1689 to Closed

Note You need to log in before you can comment on or make changes to this bug.