1 Reply Latest reply on Jul 11, 2007 7:08 PM by aaron dixon

    Advanced Classloader issue w Drools

    aaron dixon Newbie

      I'm using Drools 4.0.0.12865MR3.

      I have a rules file "Foo.drl" and class "com.foo.Foo" that I'd like to load and execute rules against. However, I potentially need to load Foo in the same VM using two different classloaders, CL1 and CL2. (The underlying use case is one in which I'm doing dynamic class generation.)

      Drools will fail with the below exception if I attempt to build afresh and execute my rules in the same VM but loading the class with a second class loader. See code and exception below.

      NOTE. The first execution (using CL1) succeeds. It seems that Drools is maintaining some kind of internal state/cache of some dynamically generated classes that causes it to fail when loading using the second classloader.

       public void go() throws Exception {
       // Save original classloader
       ClassLoader original = Thread.currentThread().getContextClassLoader();
      
       // Create Classloader 1 with parent of original
       FooClassLoader loader1 = new FooClassLoader(original);
       Thread.currentThread().setContextClassLoader(loader1);
       testRules();
      
       // Create Classloader 2 with parent of original
       FooClassLoader loader2 = new FooClassLoader(original);
       Thread.currentThread().setContextClassLoader(loader2);
       testRules();
      
       // Restore
       Thread.currentThread().setContextClassLoader(original);
       }
      
       private void testRules() throws Exception {
       PackageBuilder builder = new PackageBuilder();
       Package pkg = buildPackage(new String[] { "Foo.drl" }, builder);
       RuleBase base = RuleBaseFactory.newRuleBase();
       base.addPackage(pkg);
       StatelessSession session = base.newStatelessSession();
       final ClassLoader loader = Thread.currentThread().getContextClassLoader();
       Object inst = loader.loadClass("com.foo.Foo").newInstance();
       session.execute(new Object[] { inst });
       }
      



      [1] Found foo : foo
      Exception in thread "main" java.lang.ClassCastException: adixon.prototype.rules.classloader.demo.copy.FooShadowProxy
      at org.drools.base.adixon.prototype.rules.classloader.demo.copy.Foo$getName.getValue(Unknown Source)
      at org.drools.base.ClassFieldExtractor.getValue(ClassFieldExtractor.java:94)
      at org.drools.base.evaluators.StringFactory$StringEqualEvaluator.evaluate(StringFactory.java:85)
      at org.drools.rule.LiteralRestriction.isAllowed(LiteralRestriction.java:61)
      at org.drools.rule.LiteralConstraint.isAllowed(LiteralConstraint.java:82)
      at org.drools.reteoo.AlphaNode.assertObject(AlphaNode.java:121)
      at org.drools.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:20)
      at org.drools.reteoo.ObjectTypeNode.assertObject(ObjectTypeNode.java:159)
      at org.drools.reteoo.Rete.assertObject(Rete.java:175)
      at org.drools.reteoo.ReteooRuleBase.assertObject(ReteooRuleBase.java:190)
      at org.drools.reteoo.ReteooWorkingMemory.doInsert(ReteooWorkingMemory.java:70)
      at org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:772)
      at org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:584)
      at org.drools.reteoo.ReteooStatelessSession.execute(ReteooStatelessSession.java:63)
      at adixon.prototype.rules.classloader.demo.copy.Driver.testRules(Driver.java:47)
      at adixon.prototype.rules.classloader.demo.copy.Driver.go(Driver.java:33)
      at adixon.prototype.rules.classloader.demo.copy.Driver.main(Driver.java:17)