Godmar Back wrote:
I don't know how to switch the compiler, but lLooking at the
source, I
see that janino uses ClassLoaderIClassLoader,
http://fisheye.codehaus.org/browse/~raw,r=1.6/janino/janino/src/org/codeh...
which in fact uses a reflection-based loader.
I believe I had already pointed out the problem with using reflection
to resolve external references: it can lead to unexpected first active
uses (in other words, using a class as a reference in compilation
could trigger the class's static {} initializer.) which may or may not
be tolerable (if the class is already loaded or has no static
initializer, it's not a problem - otherwise, it's a nightmare.)
In any event, this is all besides the point (at least the point I was
trying to make). I argue that a sound design should separate runtime
and compilation classpath (or at least provide the option of doing
so), but I acknowledge that the current approach is pragmatic and
probably works for a large number of cases.
To return to the original point of discussion, I'm wondering how to
make it easy for different .drl files to refer to each other. You had
brought up the Rule Agent, though it wasn't clear to me whether you
meant that the rule agent implementation as it currently exists
already has a way of specifying such dependencies, and if so, how - or
whether you are consider this a future addition.
>From my (admittedly brief) examination of the the rule agent, it
appears to be a tool that monitors filesystem or network-based sources
of rules in pre-compiled packages, then loads them. What I am seeking
is a simple way for one rulebase to refer to a set of classes and
rules on which it depends, similar to how, for instance, an XML file
can refer to an external DTD or Schema.
The rule agent allows you to specify one or more binary packages ro
DRLs, which it will compile (as long as drools-compiler is in the
classpath) and build a rulebase for on the fly. We will try and add JARs
to this for the next major release, so it can load the model on the fly
too. I don't want one drl having to be hard coded to another drl or
other remote resources, I would rather it was specified at the
configuration level for something like the rule agent.
- Godmar
On 10/2/07, Mark Proctor <mproctor(a)codehaus.org> wrote:
> try using janino instead of eclipse jdt
>
>
> Godmar Back wrote:
> PS: it turns out that Drool's class loader in
> org/drools/rule/PackageCompilationData.java falls back to
> getResource
> also (that's why I had to delete .class file in my first attempt at
> RLoader.) Installing a class loader that fails getResource() for
> .class files makes it even simpler to see that Drools's compilation
> machinery relies on it. So, to convince yourselves, use this loader:
>
> // RLoader.java, v2
> import java.io.File;
> import java.net.URL;
>
> public class RLoader extends ClassLoader {
> public RLoader() { }
> public RLoader(ClassLoader parent) { super(parent); }
> public Class loadClass(String name) throws ClassNotFoundException {
> return getParent().loadClass(name);
> }
>
> public URL getResource(String name) {
> if (name.endsWith(".class")) {
> System.out.println("Classloader asked for .class file as
> resource URL: " + name);
> new Throwable().printStackTrace();
> return null;
> }
> return getParent().getResource(name);
> }
> }
>
> and you can observe the same failure - maybe this convinces you.
>
> - Godmar
>
>
> On 9/27/07, Godmar Back <godmar(a)gmail.com> wrote:
>
>
> On 9/27/07, Mark Proctor <mproctor(a)codehaus.org> wrote:
>
>
> Godmar Back wrote:
> I agree that it may not belong into the .drl file, though loading
> bytecode through the classloader via getResourceAsStream() also seems
> a rather ad-hoc solution.
>
>
> I've already told you, that you are mistaken here. You do not need to keep
> bytecode hanging around, and available via getResourceAsStream() for any
> compilation to work. I can generate a class at runtime, in memory, add it
> to a classloader and have the engine compile against it without
> getResourceAsStream() being able to search for and return the .class'
> bytecode.
>
>
> Ok - here's an experiment you can perform.
>
> Write a class loader RLoader.java as follows:
>
> // RLoader.java
> import java.io.File;
> import java.io.InputStream;
>
> public class RLoader extends ClassLoader {
> public RLoader() { }
> public RLoader(ClassLoader parent) { super(parent); }
> public Class loadClass(String name) throws ClassNotFoundException {
> return getParent().loadClass(name);
> }
> public InputStream getResourceAsStream(String name) {
> if (name.endsWith(".class")) {
> System.out.println("Classloader asked for .class file as
> resource: " + name);
> new Throwable().printStackTrace();
>
> // delete the .class file to ensure that no other part of
> drools attempts to read it.
> new File(name).delete();
> return null;
> }
> return getParent().getResourceAsStream(name);
> }
> }
>
> Now use this class as your system class loader. Specify:
> -Djava.system.class.loader=RLoader
>
> When you then run your application, you will see output such as:
>
> Classloader asked for .class file as resource:
> org/enhancementpatterns/castor/CastorEnhancements/AddVisitor.class
> java.lang.Throwable
> at RLoader.getResourceAsStream(RLoader.java:13)
> at
>
org.drools.rule.PackageCompilationData$PackageClassLoader.getResourceAsStream(PackageCompilationData.java:386)
> at
>
org.drools.commons.jci.compilers.EclipseJavaCompiler$2.isPackage(EclipseJavaCompiler.java:282)
> at
>
org.drools.commons.jci.compilers.EclipseJavaCompiler$2.isPackage(EclipseJavaCompiler.java:313)
> at
>
org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.isPackage(LookupEnvironment.java:1157)
> at
>
org.eclipse.jdt.internal.compiler.lookup.PackageBinding.findPackage(PackageBinding.java:75)
> at
>
org.eclipse.jdt.internal.compiler.lookup.PackageBinding.getTypeOrPackage(PackageBinding.java:190)
> at
>
org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.findImport(CompilationUnitScope.java:438)
> at
>
org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.findSingleImport(CompilationUnitScope.java:492)
> at
>
org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.faultInImports(CompilationUnitScope.java:356)
> at
>
org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.faultInTypes(CompilationUnitScope.java:425)
> at
> org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:589)
> at
> org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:411)
> at
>
org.drools.commons.jci.compilers.EclipseJavaCompiler.compile(EclipseJavaCompiler.java:353)
> at
>
org.drools.commons.jci.compilers.AbstractJavaCompiler.compile(AbstractJavaCompiler.java:51)
> at
> org.drools.rule.builder.dialect.java.JavaDialect.compileAll(JavaDialect.java:332)
> at
> org.drools.compiler.DialectRegistry.compileAll(DialectRegistry.java:60)
> at
> org.drools.compiler.PackageBuilder.addPackage(PackageBuilder.java:288)
> at
> org.drools.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:158)
>
> Leading to failures such as:
> Exception in thread "main"
> org.drools.rule.InvalidRulePackage: Rule
> Compilation error : [Rule name=Add Visitors, agendaGroup=MAIN,
> salience=0, no-loop=false]
> org/enhancementpatterns/castor/test/Rule_Add_Visitors_0.java
> (3:127) : Only a type can be imported.
> org.enhancementpatterns.castor.CastorEnhancements.AddVisitor
> resolves
> to a package
>
> - Godmar
>
>
> _______________________________________________
> rules-users mailing list
> rules-users(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/rules-users
>
>
>
>
> _______________________________________________
> rules-users mailing list
> rules-users(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/rules-users
>
>
>
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users