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<[email protected]> 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 > [email protected] > https://lists.jboss.org/mailman/listinfo/rules-dev > -- Michael D Neale home: www.michaelneale.net blog: michaelneale.blogspot.com _______________________________________________ rules-dev mailing list [email protected] https://lists.jboss.org/mailman/listinfo/rules-dev
