[rules-users] Class loading problem when registering a knowledge package

Szabolcs Bárdy szbardy at b2international.com
Mon Jan 18 08:10:39 EST 2010


Hi All,

my question would be the following:

There is a class called DroolsStreamUtils, which is used throughout
the drools core library in order to read in contents of a knowledge
package from an input stream. The class has the following method:

 public static Object streamIn(InputStream in, ClassLoader
classLoader, boolean compressed)
            throws IOException, ClassNotFoundException {
        if (compressed)
            in  = new GZIPInputStream(in);
        return new DroolsObjectInputStream(in).readObject();
 }

It creates a DroolsObjectInputStream to read in the object, but it
does not uses the specified class loader to create
DroolsObjectInputStream instance. The DroolsObjectInputStream is
created the with the folloing constructor:

public DroolsObjectInputStream(InputStream inputStream) throws IOException {
        this( inputStream,
              null );
    }

 public DroolsObjectInputStream(InputStream inputStream,
                                   ClassLoader classLoader) throws IOException {
        super( inputStream );
        if ( classLoader == null ) {
            classLoader = Thread.currentThread().getContextClassLoader();
            if ( classLoader == null ) {
                classLoader = getClass().getClassLoader();
            }
        }

        this.classLoader = classLoader;
        this.parentClassLoader = classLoader;
 }

Why can I specify a ClassLoader for DroolsStreamUtils if it is not used?

This causes us the following problem:

We are using Drools in a web application. We are planning to use
Guvnor as our rule repository. We have loaded the rules into the
repository and trying to use a KnowledgeAgent with a changeset xml to
obtain the package built by Guvnor. When the KnowledgeAgent is trying
to build the KnowlegeBase, it fails with a ClassCastException, as it
does not find the drools libraries on the class path. The
KnowledgeAgent uses the above written DroolsStreamUtils to read in the
package contents, and it uses a wrong class loader.

The same problem occurs if I am trying to use a KnowledgeBuilder to
register the package: .

knowledgeBuilder.add(ResourceFactory.newUrlResource("http://localhost:8080/drools-guvnor/org.drools.guvnor.Guvnor/package/com.ii4sm.core.drools.validation/LATEST"),
ResourceType.PKG);

I can specify a ClassLoader for the KnowledgeBuilder, however it has
no effect, since the following code is used by the KnowledgeBuilder to
register the package:

if ( ResourceType.PKG.equals( type )) {
                InputStream is = resource.getInputStream();
                Package pkg = (Package) DroolsStreamUtils.streamIn( is );
                is.close();
                addPackage( pkg );
}

As the DroolsStreamUtils won't use the class loader specified for the
KnowledgeBuilder, this approach fails as well.

If I read in the package with my own code, creating a
DroolsObjectInputStream with the correct class loader, everything
works fine.

Am I doing something wrong?

Cheers,
Szabolcs



More information about the rules-users mailing list