Question

After uninstalling my code that depends on "org.apache.servicemix.bundles.drools/5.5.0.Final_1" and then installing my bundle again, drools dependant code that worked previously is now throwing an IllegalStateException "Bundle is uninstalled" message but only on specific drools code, for example when I try to create a new session:

StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

If I uninstall org.apache.servicemix.bundles.drools and then reinstall it the issue is resolved but I don't think this is the correct solution. There are other bundles dependant on drools and this could disturb their functionality.

Here is the complete stack trace:

 java.lang.IllegalStateException: Bundle is uninstalled
    at org.apache.felix.framework.Felix.loadBundleClass(Felix.java:1832)
    at org.apache.felix.framework.BundleImpl.loadClass(BundleImpl.java:937)
    at org.springframework.osgi.util.BundleDelegatingClassLoader.findClass(BundleDelegatingClassLoader.java:99)
        at org.springframework.osgi.util.BundleDelegatingClassLoader.loadClass(BundleDelegatingClassLoader.java:156)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at org.drools.util.CompositeClassLoader$DefaultLoader.load(CompositeClassLoader.java:204)
        at org.drools.util.CompositeClassLoader$DefaultLoader.load(CompositeClassLoader.java:187)
        at org.drools.util.CompositeClassLoader.loadClass(CompositeClassLoader.java:88)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at org.drools.SessionConfiguration.newTimerService(SessionConfiguration.java:441)
        at org.drools.time.TimerServiceFactory.getTimerService(TimerServiceFactory.java:27)
        at org.drools.common.AbstractWorkingMemory.<init>(AbstractWorkingMemory.java:315)
        at org.drools.common.AbstractWorkingMemory.<init>(AbstractWorkingMemory.java:246)
        at org.drools.common.AbstractWorkingMemory.<init>(AbstractWorkingMemory.java:212)
        at org.drools.reteoo.ReteooWorkingMemory.<init>(ReteooWorkingMemory.java:103)
        at org.drools.reteoo.ReteooStatefulSession.<init>(ReteooStatefulSession.java:81)
        at org.drools.reteoo.ReteooRuleBase.newStatefulSession(ReteooRuleBase.java:402)
        at org.drools.reteoo.ReteooRuleBase.newStatefulSession(ReteooRuleBase.java:387)
        at org.drools.impl.KnowledgeBaseImpl.newStatefulKnowledgeSession(KnowledgeBaseImpl.java:175)
        at org.drools.impl.KnowledgeBaseImpl.newStatefulKnowledgeSession(KnowledgeBaseImpl.java:162)
        at com.example.drools.ReportingRules.run(ReportingRules.java:78)
        at com.example.uimetadata.viewknowledge.builder.ReportViewKnowledgeBuilder.build(ReportViewKnowledgeBuilder.java:38)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.apache.camel.component.bean.MethodInfo.invoke(MethodInfo.java:390)
        at org.apache.camel.component.bean.MethodInfo$1.doProceed(MethodInfo.java:277)
        at org.apache.camel.component.bean.MethodInfo$1.proceed(MethodInfo.java:250)
        at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:161)
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
        at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99)
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
        at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:73)
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
        at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99)
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
        at org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:91)
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
        at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99)
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
        at org.apache.camel.fabric.FabricTraceProcessor.process(FabricTraceProcessor.java:81)
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
        at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99)
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
        at org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:334)
        at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:220)
        at org.apache.camel.processor.interceptor.StreamCachingInterceptor.process(StreamCachingInterceptor.java:52)
        at org.apache.camel.processor.RouteContextProcessor.processNext(RouteContextProcessor.java:46)
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
        at org.apache.camel.processor.interceptor.DefaultChannel.process(DefaultChannel.java:308)
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
        at org.apache.camel.processor.Pipeline.process(Pipeline.java:117)
        at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
        at org.apache.camel.processor.RouteContextProcessor.processNext(RouteContextProcessor.java:46)
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
        at org.apache.camel.processor.UnitOfWorkProcessor.processAsync(UnitOfWorkProcessor.java:150)
        at org.apache.camel.processor.UnitOfWorkProcessor.process(UnitOfWorkProcessor.java:117)
        at org.apache.camel.processor.RouteInflightRepositoryProcessor.processNext(RouteInflightRepositoryProcessor.java:48)
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
        at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99)
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90)
        at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:73)
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73)
        at org.apache.camel.component.seda.SedaConsumer.sendToConsumers(SedaConsumer.java:275)
        at org.apache.camel.component.seda.SedaConsumer.doRun(SedaConsumer.java:183)
        at org.apache.camel.component.seda.SedaConsumer.run(SedaConsumer.java:139)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

Here is my drools code:

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.*;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.rule.FactHandle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class ReportingRules {

    private static Logger logger = LoggerFactory.getLogger(ReportingRules.class);

    private KnowledgeBase kbase;

    private ReportingRules() {

        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

        kbuilder.add(ResourceFactory.newClassPathResource("com/example/drools/reports/reportRender.drl"), ResourceType.DRL);

        KnowledgeBuilderErrors errors = kbuilder.getErrors();
        if (errors.size() > 0) {
            for (KnowledgeBuilderError error: errors) {
                logger.error(error.getMessage());
            }
            throw new ReportRulesException("ReportRules: " + error.getMessage());
        }

        kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
    }

public void run(ReportViewKnowledge reportViewKnowledge) {

        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

        FactHandle factHandle = ksession.insert(reportViewKnowledge);

        ksession.fireAllRules();
    }
Was it helpful?

Solution 2

During my investigation I determined the cause of the exception was that after uninstalling our core bundle that was utilizing the drools library from "Apache ServiceMix :: Bundles :: drools" bundle we needed to call osgi:refresh on "Apache ServiceMix :: Bundles :: drools" because bundles are "wired" with references to their dependents and must be refreshed when a dependent is uninstalled.

It would have helped if I read the manual before jumping head first into development :) So to avoid my mistake, here is the link to the OSGi Alliance web site and learn as much as you can about OSGi. This particular info can be found in the osgi.core-4.3.0.pdf, Page 147, Section 7.3 which is correct in my case since we are running JBoss Fuse 6.0 which is based on Karaf 2.3.0 container.

OTHER TIPS

What I see from the code here, is that the session configuration in drools stores class loaders in a static member. The error indicates that the composite class loader from this session configuration contains the class loader from your first (now uninstalled) bundle. The only way to remove this reference is indeed by removing the class containing the reference (by uninstalling drools).

From the code, it seems that the way to solve this is by creating your own session configuration object and set the class loader on that object. I am not familiar with drools, but I guess you need to first create a KnowledgeBuilderConfiguration passing the class loader of your class and then create a KnowledgeBase instance from that, like:

KnowledgeBuilderConfiguration c = 
    KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(null,
        ReportingRules.class.getClassLoader();
kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(c);

Hope this helps somewhat to get the final solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top