Thanks a lot for the information. Maybe we should add this to a Wiki page?

   From a Drools perspective, a solution like you proposed should work for any case, since we also internally tell MVEL to use the same classloader hierarchy... unless there is some unknown bug.

   Regarding declaring dependencies, I don't understand how Drools could declare such dependency since the fact classes are defined and provided by users and not known by drools in advance. Is there some default mechanism that we could implement to support such things "automagically" in OSGi deployments?

   []s
   Edson

2008/12/5 Faron Dutton <fgdutton@gmail.com>
I have successfully loaded rules and facts from other bundles in Eclipse 3.4.

I encountered the same issue, which is due to the ClassLoader behavior
defined by OSGi v4. Eclipse 3.3 introduced the new behavior and
Eclipse 3.4 aggressively adheres to the specification. Drools attempts
to access a Class through a reference to a ClassLoader, which by
default is its bundle ClassLoader. MVEL attempts to access a Class
through the context ClassLoader, which OSGi sets to the bundle's
ClassLoader. The problem arises because neither the Drools bundle nor
the MVEL bundle (I have each Drools artifact in a separate bundle)
declare a dependency on the package containing the fact's Class.
Therefore, OSGi does not add that package to the bundle's ClassLoader
and you get a ClassNotFoundException when Drools attempts to find the
Class.

I worked around this issue by doing several things:
1) Created an implementation of ClassLoader that delegates to the
bundle (BundleClassLoader).
2) Created a composite ClassLoader that contains many bundle
ClassLoaders (CompositeClassLoader).
3) For each bundle containing a rule or fact, wrap it in a
BundleClassLoader and add it to the CompositeClassLoader.
4) Pass the CompositeClassLoader to the methods mentioned in Edson's post.
5) Wrap the working memory in a Class that sets the context
ClassLoader before each method invocation and restores the original
context ClassLoader afterwards.

This takes care of most but not all of the issues. Specifically, some
invocations of MVEL still fail but the system works. I am continuing
to investigate a more elegant solution.

Faron.





On Wed, Dec 3, 2008 at 10:11 AM, Edson Tirelli <tirelli@post.com> wrote:
>
>    What do you mean by "facts in other plugins"?
>
>    If your facts are loaded by a different classloader hierarchy, you need
> to set the facts classloader in:
>
> PackageBuilderConfiguration.setClassLoader();  // to compile the rules
> RulebaseConfiguration.setClassLoader(); // to create the rulebase and run it
>
>    []s
>    Edson
>
> 2008/12/2 keithnielsen <keithnielsen@discover.com>
>>
>> Further testing shows that while the rules engine can locate facts from
>> other
>> plug-ins (facts located in the same plugin as the rules engine work fine,
>> but not realistic to expect that all facts will be co-located in the same
>> plugin), an attempt to reconstitute them using the ByteArrayClassloader
>> will
>> not work. Has anyone been successful using facts located in other
>> plug-ins?
>> I am using Drools 5.M2 with Eclipse 3.4.
>>
>>
>>
>> keithnielsen wrote:
>> >
>> > I have the following rule:
>> >
>> > rule "Retrieve CID Presentation Model"
>> >       ruleflow-group "RetrieveCID"
>> >
>> >       when
>> >
>> >
>> > CIDPresentationModel($cidValue:cidValue,$cidExpirationDate:expirationDate)
>> >       then
>> >               boolean cidResult =
>> > cidService.verifyCIDIsValid($cidValue,$cidExpirationDate);
>> >               CIDResult result = new CIDResult(cidResult);
>> >               insert(result);
>> >               System.out.println("Executing: Retrieve CID Presentation
>> > Model");
>> > end
>> >
>> > Deep in the bowels of drools there is a call to
>> > ClassFieldAccessorFactory.getClassFieldReader where it attempts to
>> > create
>> > a class using the byte array classloader, i.e. final Class<?> newClass =
>> > byteArrayClassLoader.defineClass(className, bytes,PROTECTION_DOMAIN).
>> > Its
>> > at this point that a NoClassDefFoundError on the
>> > BaseObjectClassFieldReader. From what I understand of
>> > NoClassDefFoundError
>> > it can result when there are two sources of the same class in the
>> > classpath or if there is some reference from the class resulting in the
>> > error to another class that can not be resolved. It only appears in
>> > situations where there is fields involved. It doesnt seem to matter how
>> > simple the object is, the minute I try to use field assignment it throws
>> > an error.
>> >
>> > The rules engine is running as an Eclipse plug-in.
>> >
>>
>> --
>> View this message in context:
>> http://www.nabble.com/NoClassDefFoundError%3A-BaseObjectClassFieldReader-tp20802217p20806634.html
>> Sent from the drools - user mailing list archive at Nabble.com.
>>
>> _______________________________________________
>> rules-users mailing list
>> rules-users@lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/rules-users
>
>
>
> --
>  Edson Tirelli
>  JBoss Drools Core Development
>  JBoss, a division of Red Hat @ www.jboss.com
>
> _______________________________________________
> rules-users mailing list
> rules-users@lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
>
_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users



--
 Edson Tirelli
 JBoss Drools Core Development
 JBoss, a division of Red Hat @ www.jboss.com