Bug 996144

Summary: Kie-spring cannot create KieModule when in container
Product: [Retired] JBoss BRMS Platform 6 Reporter: Marek Winkler <mwinkler>
Component: BREAssignee: Mario Fusco <mfusco>
Status: CLOSED CURRENTRELEASE QA Contact: Marek Winkler <mwinkler>
Severity: high Docs Contact:
Priority: unspecified    
Version: 6.0.0CC: mfusco, rzhang
Target Milestone: ER3   
Target Release: 6.0.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-08-06 20:20:31 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Spring context used for the test
none
server.log
none
Exception stacktrace
none
server.log with wrong pom.properties path
none
NPE in ClasspathKieProject.getPomProperties() - parent dir is null? none

Description Marek Winkler 2013-08-12 13:56:37 UTC
Created attachment 785692 [details]
Spring context used for the test

Description of problem:

I have tried to adopt kie-spring tests from https://github.com/droolsjbpm/droolsjbpm-integration/tree/master/kie-spring/src/test, however, I ran into problems when trying to run them in container (EAP 6.1 using Arquillian). The tests fail to create the application context with the following exception (see attachment for full stacktrace):

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'statefulSession': Cannot resolve reference to bean 'kbaseListeners' while setting bean property 'kBase'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'kbaseListeners': Invocation of init method failed; nested exception is java.lang.RuntimeException: Cannot find KieModule: org.jboss.qa.kie.spring:event-listeners-tests:1.0.0
     [java] 	at org.drools.compiler.kie.builder.impl.KieServicesImpl.newKieContainer(KieServicesImpl.java:83)
     [java] 	at org.kie.spring.KieObjectsResolver.resolveKContainer(KieObjectsResolver.java:80)

EAP 6.1 server.log contains the following error (again, see attachment for full log):

15:10:13,362 ERROR [org.drools.compiler.kie.builder.impl.ClasspathKieProject] (http-/127.0.0.1:8080-2) Unable to build index of kmodule.xml url=vfs:/content/spring.war/WEB-INF/classes/org/jboss/qa/brms/bre/spring/eventListenersTestContext.xml

Before creating a stand-alone reproducer, I would like to ask, what the recommended setup for Spring is:

- do I have to supply kmodule.xml in META-INF, or is it sufficient defining KieBases and KieSessions in Spring context's xml (I would expect the latter)?

- what is the role of META-INF/kmodule-spring.xml?

- what is the recommended way of initializing a Spring context when using kie-spring? I have been using the following code (taken from kie-spring tests):

  InternalKieSpringUtils.getSpringContext(releaseId, appContextXmlUrl);

  I have also tried to avoid using InternalKieSpringUtils (because the name starts with 'Internal') by using directly KModuleSpringMarshaller and KieSpringUtils, but it did not help.

This issue resembles the problem with KIE module injection using CDI, fixed by mfusco (https://bugzilla.redhat.com/show_bug.cgi?id=955193), as the KieModule cannot be built and added to the KieContainer. However, the cause seems to be different here - the org.drools.compiler.kie.builder.impl.ClasspathKieProject.createInternalKieModule() expects a JAR or a directory, but it is given a path to the Spring context xml file.

Marking as a blocker, as this issue probably prevents using kie-spring with EAP 6.1 (and potentially other containers).

Version-Release number of selected component (if applicable):

Drools 6.0.0-SNAPSHOT
Drools 6.0.0.CR1

How reproducible:

I will prepare a standalone reproducer, if needed, after the questions mentioned above are answered.

Comment 1 Marek Winkler 2013-08-12 13:58:55 UTC
Created attachment 785695 [details]
server.log

Comment 2 Marek Winkler 2013-08-12 14:02:02 UTC
Created attachment 785696 [details]
Exception stacktrace

Comment 3 Marek Winkler 2013-08-13 09:27:49 UTC
After discussion with Vinod, I have created application context using 

  new ClassPathXmlApplicationContext(appContextXmlFile)

which helped me to get further. However, the ClasspathKieProject.getPomProperties() fails to locate pom.properties file in the deployed WAR archive and throws a NPE (see attachment for full stacktrace):

java.lang.NullPointerException: null
 	at java.io.File.<init>(File.java:251)
 	at org.drools.compiler.kie.builder.impl.ClasspathKieProject.getPomProperties(ClasspathKieProject.java:240)

The server log contains the following error, which indicates (unless I missed something), that the rootPath variable in ClasspathKieProject.getPomProperties(String) is absolute after removing the protocol 'vfs:', and therefore points to non-existent directory:

10:51:15,486 WARN  [org.drools.compiler.kie.builder.impl.ClasspathKieProject] (http-/127.0.0.1:8080-2) Unable to load pom.properties tried recursing down from/content/spring.war/WEB-INF/classes/
null

In my opinion, there are two problems:
  - the NPE should be caught and handled
  - ClasspathKieProject.getPomProperties() seems not to handle correctly the vfs: protocol - this should manifest in KIE CDI container tests as well, I will check it.

Comment 4 Marek Winkler 2013-08-13 09:29:33 UTC
Created attachment 786089 [details]
server.log with wrong pom.properties path

Comment 5 Marek Winkler 2013-08-13 09:30:59 UTC
Created attachment 786090 [details]
NPE in ClasspathKieProject.getPomProperties() - parent dir is null?

Comment 6 Marek Winkler 2013-08-14 09:49:44 UTC
Another update: 

Plain KIE CDI tests (without Spring) pass. I realized that there is probably a problem in not using the ClasspathKieProject.fixURLFromKProjectPath(URL) method, as the ClasspathKieProject.fetchKModule(URL) does for plain (without Spring) CDI.

I have tried to change the org.kie.spring.KModuleBeanFactoryPostProcessor.initConfigFilePath() to the following:

    protected void initConfigFilePath() {
        // the original initialization code
        //configFilePath = getClass().getResource("/").getPath();

        ProjectClassLoader cl = ProjectClassLoader.createProjectClassLoader();
        configFilePath = ClasspathKieProject.fixURLFromKProjectPath(cl.getResource("META-INF/kmodule.xml"));
    }

and our KIE Spring tests in container pass. However, this is not a general solution, as this code:

- detects the configFilePath from any location (e.g. any JAR) on the classpath, i.e. the found pom.properties might be not the one really looked for;

- requires META-INF/kmodule.xml to be located in the module, where pom.properties is being looked for (I think it was the original intention to get rid of kmodule.xml in this case).

Should there be any generic configFilePath detection mechanism (I am not sure if it is possible in this case), or should the configFilePath be set externally, e.g. in the Spring context XML?

Comment 7 Marek Winkler 2013-08-19 13:27:48 UTC
Created PR with reproducer: https://github.com/droolsjbpm/droolsjbpm-integration/pull/66

Please run org.drools.jboss.integration.spring.KieSpringTest and note two possible problems: 

- NPE in org.drools.compiler.kie.builder.impl.ClasspathKieProject.getPomProperties

- log message indicating that it is trying to look for pom.properties in a non-existent location (/content/...):

15:24:49,672 WARN  [org.drools.compiler.kie.builder.impl.ClasspathKieProject] (pool-1-thread-1) Unable to load pom.properties tried recursing down from/content/arquillian-service/
null

Comment 8 Marek Winkler 2013-08-20 15:55:00 UTC
Sorry, forgot to mention that you should run the tests with 'arquillian-jbossas-managed' maven profile, otherwise the weld container is used instead of JBoss AS.

The problem is present when using EAP 6.1.

Comment 10 Marek Winkler 2013-09-23 13:14:34 UTC
Verified on BRMS 6.0.0-ER3.