[rules-dev] Compiling drools-5 to .NET -- issue with ClassLoaders

Michael Neale michael.neale at gmail.com
Sun Sep 6 06:01:01 EDT 2009


Hi Krishna - thanks for chasing that one down - hopefully google will
find it now (via nabble and such) !

On Sat, Sep 5, 2009 at 12:57 PM, kpowerinfinity<kpowerinfinity at gmail.com> wrote:
> Hi Michael,
>
> It seems that the CacheFieldAccessorCache is not initialized with the
> same ClassLoader as the one one provided to the
> KnowledgeBaseConfiguration, if initialized by default, but rather does
> it using
> Class.forName("some.model.class").getClassLoader()
>
> Hence, the ClassLoader was unable to resolve the drools base extractor classes.
>
> IKVM had moved to a new classloading architecture , and the default
> classloader that gets attached doesn't resolve the other classes.
> (See: http://weblog.ikvm.net/CommentView.aspx?guid=8a457a80-1e5f-4182-8f78-b2cd67845553),
> and by making the model class as a AppDomainAssemblyClassLoader), it
> is able to resolve all loaded classes and it works perfectly.
>
> Thought I'd post the resolution here.
>
> Regards
> Krishna.
>
> --
> http://kpowerinfinity.wordpress.com
> http://www.linkedin.com/in/kpowerinfinity
>
>
>
>
> On Fri, Sep 4, 2009 at 8:03 AM, Michael Neale<michael.neale at gmail.com> wrote:
>> would have to look at the code for that - its the only documentation
>> that makes sense for something so low-level...
>>
>> I don't think there were major changes in Drools 4 to 5 in that area -
>> so odd that it doesn't work.
>>
>> On Fri, Sep 4, 2009 at 1:01 AM, kpowerinfinity<kpowerinfinity at gmail.com> wrote:
>>> Hi Mike,
>>>
>>> Do you remember what you needed to do for drools3.0? I had earlier
>>> compiled drools 4.0 and it seemed to work without any major problems.
>>>
>>> Where can I find some documentation on the ASM and where drools picks
>>> up the classes from while generating the "in-situ" classes?
>>>
>>> Thanks, Krishna.
>>>
>>> --
>>> http://kpowerinfinity.wordpress.com
>>> http://www.linkedin.com/in/kpowerinfinity
>>>
>>>
>>>
>>>
>>> On Thu, Sep 3, 2009 at 5:31 AM, Michael Neale<michael.neale at gmail.com> wrote:
>>>> Hi Krishna - I don't think the .Net version on the codehaus is kept
>>>> that up to date, so its probably a good thing you are doing what you
>>>> are doing with the latest.
>>>>
>>>> Yes, those accessor classes are indeed lazily generated and loaded
>>>> "in-situ" - this is for fast access of fields in the alpha network
>>>> which can be hit hard and often... an inlined version of the ASM
>>>> library is used to do this.
>>>>
>>>> I am pretty sure that even in drools 3 we did something like this
>>>> (also using ASM) and that was able to work with IKVM - so there must
>>>> be some small change that has made the IKVM classloader angry...
>>>>
>>>> On a barely related note: is it worth thinking about a Source to
>>>> Source translator to C# - there are a few around (ILog even open
>>>> sourced one, although it didn't cope with Generics last I checked...)
>>>> ?
>>>>
>>>>
>>>> Michael.
>>>>
>>>> On Wed, Sep 2, 2009 at 11:56 PM, kpowerinfinity<kpowerinfinity at gmail.com> wrote:
>>>>> Hello,
>>>>>
>>>>> I've been trying to compile the latest version of drools to .NET for a
>>>>> few days now. However, due to the classloaders structure, the classes
>>>>> in the org.drools.base.extractors.* are not found by the classloader,
>>>>> and the execution stops with a NoClassDefFoundError for classes in
>>>>> that package.
>>>>>
>>>>> Here's some details about the setup:
>>>>> Drools version: 5.0.1
>>>>> IKVM Version: 0.40.0.1
>>>>>
>>>>> I have successfully compiled all the required libraries into a DLL
>>>>> using IKVM, and a simple rule (containing a null LHS) runs
>>>>> successfully, all the classes are found, and the rule engine produces
>>>>> the correct output. However, when I add a condition into the LHS, it
>>>>> fails because it can't find one of the classes in
>>>>> /org.drools.base.extractors..*Reader/
>>>>>
>>>>> A sample rule I am using is:
>>>>> """
>>>>> package package
>>>>> import rules.Customer
>>>>> import rules.VoucherSeries
>>>>>
>>>>> rule "everything free for Krishna"
>>>>>
>>>>>        when
>>>>>                $c : Customer( firstname == "Krishna" )
>>>>>        then
>>>>>                VoucherSeries fact0 = new VoucherSeries();
>>>>>                fact0.setSeriesCode( "FREE" );
>>>>>                insert(fact0 );
>>>>> end
>>>>> """
>>>>>
>>>>> I have verified that all the classes are present in the classloader I
>>>>> am passing to the KnowledgeBuilderConfiguration. In fact, I also tried
>>>>> creating a MapBasedClassLoader that contains all the missing classes
>>>>> so that they can be easily found using fastFindClass. In the code
>>>>> listing below, both klass and klass2 resolve to the correct class
>>>>> objects.
>>>>>
>>>>> """
>>>>>            java.util.Properties p = new java.util.Properties();
>>>>>            p.put("drools.dialect.java.compiler", "JANINO");
>>>>>            java.lang.ClassLoader cl =
>>>>> java.lang.Class.forName("org.drools.base.extractors.BaseLongClassFieldReader").getClassLoader();
>>>>>            org.drools.rule.CompositeClassLoader compositeClassLoader
>>>>> = new org.drools.rule.CompositeClassLoader(cl);
>>>>>
>>>>>            org.drools.rule.MapBackedClassLoader mbcl =
>>>>> getMapBackedClassLoader(cl);
>>>>>
>>>>>            compositeClassLoader.addClassLoader(mbcl);
>>>>>            java.lang.Class klass =
>>>>> compositeClassLoader.fastFindClass("rules.Customer");
>>>>>            java.lang.Class klass2 =
>>>>> compositeClassLoader.fastFindClass("org.drools.base.extractors.BaseObjectClassFieldReader");
>>>>>            java.lang.ClassLoader finalClassLoader = compositeClassLoader;
>>>>>
>>>>>            org.drools.builder.KnowledgeBuilderConfiguration kbc =
>>>>> org.drools.builder.KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(p,
>>>>> finalClassLoader);
>>>>> """
>>>>>
>>>>> However, adding the DRL / PKG file, it fails with the exception:
>>>>>
>>>>> java.lang.NoClassDefFoundError was caught
>>>>>  Message="org.drools.base.extractors.BaseObjectClassFieldReader"
>>>>>  Source="IKVM.Runtime"
>>>>>  StackTrace:
>>>>>       at IKVM.NativeCode.java.lang.ClassLoader.defineClass1(Object
>>>>> thisClassLoader, String name, Byte[] b, Int32 off, Int32 len, Object
>>>>> pd, String source)
>>>>>       at java.lang.ClassLoader.defineClass1(String , Byte[] , Int32 ,
>>>>> Int32 , ProtectionDomain , String )
>>>>>       at java.lang.ClassLoader.defineClass(String name, Byte[] b,
>>>>> Int32 off, Int32 len, ProtectionDomain protectionDomain)
>>>>>       at org.drools.base.ClassFieldAccessorCache.ByteArrayClassLoader.defineClass(String
>>>>> name, Byte[] bytes, ProtectionDomain domain)
>>>>>       at org.drools.base.ClassFieldAccessorFactory.getClassFieldReader(Class
>>>>> clazz, String fieldName, CacheEntry cache)
>>>>>       at org.drools.base.ClassFieldAccessorCache.CacheEntry.getReadAccessor(AccessorKey
>>>>> key, Class cls)
>>>>>       at org.drools.base.ClassFieldAccessorCache.getReadAcessor(ClassFieldReader
>>>>> reader)
>>>>>       at org.drools.base.ClassFieldAccessorStore.wire(ClassFieldReader reader)
>>>>>       at org.drools.base.ClassFieldAccessorStore.getReader(String
>>>>> className, String fieldName, AcceptsReadAccessor target, AccessorType
>>>>> accessorType)
>>>>>       at org.drools.base.ClassFieldAccessorStore.getReader(String
>>>>> className, String fieldName, AcceptsReadAccessor target)
>>>>>       at org.drools.rule.builder.PatternBuilder.getFieldReadAccessor(RuleBuildContext
>>>>> context, BaseDescr descr, ObjectType objectType, String fieldName,
>>>>> AcceptsReadAccessor target, Boolean reportError)
>>>>>       at org.drools.rule.builder.PatternBuilder.build(RuleBuildContext
>>>>> , Pattern , FieldConstraintDescr , AbstractCompositeConstraint )
>>>>>       at org.drools.rule.builder.PatternBuilder.buildConstraint(RuleBuildContext
>>>>> , Pattern , Object , AbstractCompositeConstraint )
>>>>>       at org.drools.rule.builder.PatternBuilder.build(RuleBuildContext
>>>>> context, BaseDescr descr, Pattern prefixPattern)
>>>>>       at org.drools.rule.builder.PatternBuilder.build(RuleBuildContext
>>>>> context, BaseDescr descr)
>>>>>       at org.drools.rule.builder.GroupElementBuilder.build(RuleBuildContext
>>>>> context, BaseDescr descr, Pattern prefixPattern)
>>>>>       at org.drools.rule.builder.RuleBuilder.build(RuleBuildContext context)
>>>>>       at org.drools.compiler.PackageBuilder.addRule(RuleDescr )
>>>>>       at org.drools.compiler.PackageBuilder.addPackage(PackageDescr
>>>>> packageDescr)
>>>>>       at org.drools.compiler.PackageBuilder.addPackageFromDrl(Resource
>>>>> resource)
>>>>>       at org.drools.compiler.PackageBuilder.addKnowledgeResource(Resource
>>>>> resource, ResourceType type, ResourceConfiguration configuration)
>>>>>       at org.drools.builder.impl.KnowledgeBuilderImpl.add(Resource
>>>>> resource, ResourceType type)
>>>>>       at Capillary.Client.RulesEngine.RuleManager.ReadRules(String
>>>>> filename) in D:\coderoot\module\DataEntryClient-DVS\SubProjects\RulesEngine\RuleManager.cs:line
>>>>> 116
>>>>>  InnerException:
>>>>>
>>>>> I saw the code at org/drools/base/ClassFieldAccessorCache.java, and it
>>>>> seems me that the Reader class for the particular type is being
>>>>> defined in situ using a byte[] array, but I am unable to understand
>>>>> why it can't load the class at that point.
>>>>>
>>>>> Can anybody with a better idea of the drools classloading structure
>>>>> guide me here?
>>>>>
>>>>> Also, is the drools.NET project active now? I would post all the steps
>>>>> I took for posterity.
>>>>>
>>>>> Thanks and Regards,
>>>>> Krishna.
>>>>>
>>>>> --
>>>>> http://kpowerinfinity.wordpress.com
>>>>> http://www.linkedin.com/in/kpowerinfinity
>>>>> _______________________________________________
>>>>> rules-dev mailing list
>>>>> rules-dev at lists.jboss.org
>>>>> https://lists.jboss.org/mailman/listinfo/rules-dev
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Michael D Neale
>>>> home: www.michaelneale.net
>>>> blog: michaelneale.blogspot.com
>>>>
>>>> _______________________________________________
>>>> rules-dev mailing list
>>>> rules-dev at lists.jboss.org
>>>> https://lists.jboss.org/mailman/listinfo/rules-dev
>>>>
>>>
>>> _______________________________________________
>>> rules-dev mailing list
>>> rules-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/rules-dev
>>>
>>
>>
>>
>> --
>> Michael D Neale
>> home: www.michaelneale.net
>> blog: michaelneale.blogspot.com
>>
>> _______________________________________________
>> rules-dev mailing list
>> rules-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/rules-dev
>>
>
> _______________________________________________
> rules-dev mailing list
> rules-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-dev
>



-- 
Michael D Neale
home: www.michaelneale.net
blog: michaelneale.blogspot.com



More information about the rules-dev mailing list