You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@hivemind.apache.org by Kristian Mandrup <km...@hotmail.com> on 2005/01/26 12:29:02 UTC

Problems using custom ClassLoaders and custom URL protocol handlers with Hivemind

Hi HiveMind experts ;-)

 

I have been spending a long time trying to tweak HiveMind to use a custom
ClassLoader using a custom protocol handler… 

 

The following very simple example works. It loads the Calculator HiveMind
service from a .jar file, using MyURLClassLoader extends URLClassLoader

HiveMind is not otherwise available in the JVM classpath.

The output below shows:

getResource [org.class]

Return URL = null

 

Meaning it uses the getResource(String name) of the ClassLoader when trying
to resolve non-classes such as “org”

 

The ClassLoader must have the getResource… methods, since HiveMind uses
JavaAssist LoaderClassPath:

 

public class LoaderClassPath

extends java.lang.Object

implements HYPERLINK
"file:///c:\\Java\\javassist-3.0\\html\\javassist\\ClassPath.html"ClassPath

A class search-path representing a class loader. 

It is used for obtaining a class file from the given class loader by
getResourceAsStream(). The LoaderClassPath refers to the class loader
through WeakReference. If the class loader is garbage collected, the other
search pathes are examined. 

The given class loader must have both getResourceAsStream() and
getResource(). 

The next example uses a custom ClassLoader that takes a custom URL to
retrieve each class bytecode.

 

The output shows, that it continues to use getInputStream() of my public
class RegistryURLConnection extends URLConnection

Even for the non-class entity “org”. Javassist fails when receiving an
InputStream of null…

 

[getInputStream] component found org.apache.hivemind.examples.Divider

[getInputStream] find component :SOA/jars/hive-calculator.jar/org

Component [SOA/jars/hive-calculator.jar/org] not found

ServiceClassLoaderException: ResourceAsStream not found [org.class]

Exception :org.apache.hivemind.ApplicationRuntimeException: Unable to add
method java.lang.Object writeReplace() to class $Calculator_101aaad22e1:
javassist.NotFoundException: org

org.apache.hivemind.ApplicationRuntimeException: Unable to add method
java.lang.Object writeReplace() to class $Calculator_101aaad22e1:
javassist.NotFoundException: org

           at
org.apache.hivemind.impl.servicemodel.SingletonServiceModel.createSingletonP
roxy(SingletonServiceModel.java:114)

 

The big problem seems to lie in Javassist:

In the example that works, the classfile is never null, thus it never
attempts to get the InputStream, but why?

What should be done to ensure classfile is never null?

I guess I’m missing something somewhere???

Any experts on Javassist out there?

 

class CtClassType extends CtClass {

…

 

    public ClassFile getClassFile2() {

        if (classfile != null)

            return classfile;

 

        if (readCounter++ > READ_THRESHOLD) {

            doCompaction();

            readCounter = 0;

        }

 

        InputStream fin = null;

        try {

            fin = classPool.openClassfile(getName()); 

            if (fin == null)

                throw new NotFoundException(getName());

 

            fin = new BufferedInputStream(fin);

            classfile = new ClassFile(new DataInputStream(fin));

            if (!classfile.getName().equals(qualifiedName))

                throw new RuntimeException(classfile.getName() + " in "

                                + qualifiedName.replace('.', '/') +
".java");

 

            return classfile;

        }

        catch (NotFoundException e) {

            throw new RuntimeException(e.toString());

        }

        catch (IOException e) {

            throw new RuntimeException(e.toString());

        }

        finally {

            if (fin != null)

                try {

                    fin.close();

                }

                catch (IOException e) {}

        }

    }

 

 

 

 

 

 

        System.out.println("Using MyURLClassLoader ");

 

        URL url = new File("testdata/hive-calculator.jar").toURL();

        URL[] urls = { url };

        

        MyURLClassLoader loader = new MyURLClassLoader(urls);

 

        Registry hivemindRegistry = RepositoryRegistryBuilder

                .constructDefaultRegistry(loader, paths);

        String serviceName = "org.apache.hivemind.examples.Calculator";

 

        Class calculatorClass = loader.loadClass(serviceName);

        

        if (hivemindRegistry.containsService(calculatorClass)) {

            Object service = hivemindRegistry.getService(calculatorClass);

 

            for (Method m : service.getClass().getMethods()) {

                System.out.println(m.getName());

            }

            System.out.println(service.getClass().getName());

        } else System.out.println("No ServicePoint found for " +
calculatorClass.getName());

        

 

public class MyURLClassLoader extends URLClassLoader {

    public MyURLClassLoader(URL[] urls) {

        super(urls);

    }

    

    public MyURLClassLoader(URL[] urls, ClassLoader loader) {

        super(urls, loader);

    }

 

    

    public URL getResource(String name) {

        System.out.println("getResource [".concat(name).concat("]"));

        URL url = super.getResource(name);

        if (url != null)

            System.out.println("Return URL
[".concat(url.toString()).concat("]"));

        else System.out.println("Return URL = null");

        System.out.flush();

        return url;

    }

    

    public InputStream getResourceAsStream(String name) {

        System.out.println("getResourceAsStream
[".concat(name).concat("]"));

        InputStream in = super.getResourceAsStream(name);

        if (in != null)

            System.out.println("Return InputStream
[".concat(in.toString()).concat("]"));

        else System.out.println("Return InputStream = null"); 

        System.out.flush();

        return in;

    }

}

 

Using MyURLClassLoader 

log4j:WARN No appenders could be found for logger
(org.apache.hivemind.impl.XmlModuleDescriptorProvider).

log4j:WARN Please initialize the log4j system properly.

getResource [org/apache/hivemind/examples/Calculator.class]

Return URL
[jar:file:/C:/IDE/eclipse/workspace/cmsoax/testdata/hive-calculator.jar!/org
/apache/hivemind/examples/Calculator.class]

getResourceAsStream [org/apache/hivemind/examples/Calculator.class]

getResource [org/apache/hivemind/examples/Calculator.class]

Return URL
[jar:file:/C:/IDE/eclipse/workspace/cmsoax/testdata/hive-calculator.jar!/org
/apache/hivemind/examples/Calculator.class]

Return InputStream [java.util.zip.ZipFile$2@18f5824]

getResource [org/apache/hivemind/examples/Adder.class]

Return URL
[jar:file:/C:/IDE/eclipse/workspace/cmsoax/testdata/hive-calculator.jar!/org
/apache/hivemind/examples/Adder.class]

getResource [org/apache/hivemind/examples/Subtracter.class]

Return URL
[jar:file:/C:/IDE/eclipse/workspace/cmsoax/testdata/hive-calculator.jar!/org
/apache/hivemind/examples/Subtracter.class]

getResource [org/apache/hivemind/examples/Multiplier.class]

Return URL
[jar:file:/C:/IDE/eclipse/workspace/cmsoax/testdata/hive-calculator.jar!/org
/apache/hivemind/examples/Multiplier.class]

getResource [org/apache/hivemind/examples/Divider.class]

Return URL
[jar:file:/C:/IDE/eclipse/workspace/cmsoax/testdata/hive-calculator.jar!/org
/apache/hivemind/examples/Divider.class]

getResourceAsStream [org/apache/hivemind/examples/Adder.class]

getResource [org/apache/hivemind/examples/Adder.class]

Return URL
[jar:file:/C:/IDE/eclipse/workspace/cmsoax/testdata/hive-calculator.jar!/org
/apache/hivemind/examples/Adder.class]

Return InputStream [java.util.zip.ZipFile$2@11671b2]

getResourceAsStream [org/apache/hivemind/examples/Subtracter.class]

getResource [org/apache/hivemind/examples/Subtracter.class]

Return URL
[jar:file:/C:/IDE/eclipse/workspace/cmsoax/testdata/hive-calculator.jar!/org
/apache/hivemind/examples/Subtracter.class]

Return InputStream [java.util.zip.ZipFile$2@82764b]

getResourceAsStream [org/apache/hivemind/examples/Multiplier.class]

getResource [org/apache/hivemind/examples/Multiplier.class]

Return URL
[jar:file:/C:/IDE/eclipse/workspace/cmsoax/testdata/hive-calculator.jar!/org
/apache/hivemind/examples/Multiplier.class]

Return InputStream [java.util.zip.ZipFile$2@12452e8]

getResourceAsStream [org/apache/hivemind/examples/Divider.class]

getResource [org/apache/hivemind/examples/Divider.class]

Return URL
[jar:file:/C:/IDE/eclipse/workspace/cmsoax/testdata/hive-calculator.jar!/org
/apache/hivemind/examples/Divider.class]

Return InputStream [java.util.zip.ZipFile$2@1bf3d87]

getResource [org.class]

Return URL = null

getResource [org/apache.class]

Return URL = null

getResource [org/apache/hivemind.class]

Return URL = null

getResource [org/apache/hivemind/internal.class]

Return URL = null

getResource [org/apache/hivemind/internal/ser.class]

Return URL = null

getResource [org.class]

Return URL = null

getResource [org/apache.class]

Return URL = null

getResource [org/apache/hivemind.class]

Return URL = null

getResource [org/apache/hivemind/internal.class]

Return URL = null

getResource [org/apache/hivemind/internal/ser.class]

Return URL = null

add

toString

registryDidShutdown

_setInner

subtract

multiply

divide

hashCode

getClass

wait

wait

wait

equals

notify

notifyAll

$Calculator_101aa4552e4

 

 

 

            RepositoryClassLoader loader = getLoader(registry, repos,
archiveName); 

            

            URL url = RegistryURLFactory.newURL(registry, repos.getName(),
"SOA", compiledClassContainerPath);

            URL[] urls = {url};

 

            Registry hivemindRegistry = RepositoryRegistryBuilder

                    .constructDefaultRegistry(loader, paths);

            String serviceName = "org.apache.hivemind.examples.Calculator";

            Class calculatorClass = loader.loadClass(serviceName);

 

            if (hivemindRegistry.containsService(calculatorClass)) {

                Object service =
hivemindRegistry.getService(calculatorClass);

 

public class RepositoryClassLoader extends ClassLoader {

 

…

 

    public InputStream getResourceAsStream(String name) {

        try {

            InputStream in = super.getResourceAsStream(name);

            if (in == null) {

                return new ByteArrayInputStream(loadClassData(name));    

            }

            else return in;

        } catch (ServiceClassLoaderException e) {

            System.out.println("ServiceClassLoaderException:
ResourceAsStream not found [" + name + "]");

            return null;

        } catch (Exception e) {

            System.out.println("ResourceAsStream exception " +
e.getMessage());

            return null;

        }     

    }

 

    

    public URL getResource(String name) { 

        try {

            return RegistryURLFactory.newURL(getRegistry(),
getRepository().getName(), getProject(),
getCompiledClassContainer().concat("/").concat(name));    

        } catch (MalformedURLException e) {

            System.out.println("MalformedURLException: Resource not found ["
+ name + "]");

            return null;

        } catch (Exception e) {

            System.out.println("getResource exception " + e.getMessage());

            return null;

        }

    }

 

[getInputStream] find component
:SOA/jars/hive-calculator.jar/org.apache.hivemind.examples.Calculator

[getInputStream] component found org.apache.hivemind.examples.Calculator

[getInputStream] find component
:SOA/jars/hive-calculator.jar/org.apache.hivemind.examples.Adder

[getInputStream] component found org.apache.hivemind.examples.Adder

[getInputStream] find component
:SOA/jars/hive-calculator.jar/org.apache.hivemind.examples.Subtracter

[getInputStream] component found org.apache.hivemind.examples.Subtracter

[getInputStream] find component
:SOA/jars/hive-calculator.jar/org.apache.hivemind.examples.Multiplier

[getInputStream] component found org.apache.hivemind.examples.Multiplier

[getInputStream] find component
:SOA/jars/hive-calculator.jar/org.apache.hivemind.examples.Divider

[getInputStream] component found org.apache.hivemind.examples.Divider

[getInputStream] find component :SOA/jars/hive-calculator.jar/org

Component [SOA/jars/hive-calculator.jar/org] not found

ServiceClassLoaderException: ResourceAsStream not found [org.class]

Exception :org.apache.hivemind.ApplicationRuntimeException: Unable to add
method java.lang.Object writeReplace() to class $Calculator_101aaad22e1:
javassist.NotFoundException: org

org.apache.hivemind.ApplicationRuntimeException: Unable to add method
java.lang.Object writeReplace() to class $Calculator_101aaad22e1:
javassist.NotFoundException: org

           at
org.apache.hivemind.impl.servicemodel.SingletonServiceModel.createSingletonP
roxy(SingletonServiceModel.java:114)

           at
org.apache.hivemind.impl.servicemodel.SingletonServiceModel.getService(Singl
etonServiceModel.java:58)

           at
org.apache.hivemind.impl.ServicePointImpl.getService(ServicePointImpl.java:1
89)

           at
org.apache.hivemind.impl.ServicePointImpl.getService(ServicePointImpl.java:2
02)

           at
org.apache.hivemind.impl.RegistryInfrastructureImpl.getService(RegistryInfra
structureImpl.java:207)

           at
org.apache.hivemind.impl.RegistryImpl.getService(RegistryImpl.java:71)

           at
org.planx.cmsoax.soa.hivemind.TestRepositoryRegistryBuilder.testConstruct(Te
stRepositoryRegistryBuilder.java:187)

           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

           at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

           at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
Source)

           at java.lang.reflect.Method.invoke(Unknown Source)

           at junit.framework.TestCase.runTest(TestCase.java:154)

           at junit.framework.TestCase.runBare(TestCase.java:127)

           at junit.framework.TestResult$1.protect(TestResult.java:106)

           at junit.framework.TestResult.runProtected(TestResult.java:124)

           at junit.framework.TestResult.run(TestResult.java:109)

           at junit.framework.TestCase.run(TestCase.java:118)

           at junit.framework.TestSuite.runTest(TestSuite.java:208)

           at junit.framework.TestSuite.run(TestSuite.java:203)

           at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRu
nner.java:474)

           at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.
java:342)

           at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner
java:194)

Caused by: org.apache.hivemind.ApplicationRuntimeException: Unable to add
method java.lang.Object writeReplace() to class $Calculator_101aaad22e1:
javassist.NotFoundException: org

           at
org.apache.hivemind.service.impl.ClassFabImpl.addMethod(ClassFabImpl.java:31
0)

           at
org.apache.hivemind.impl.ProxyBuilder.addSerializable(ProxyBuilder.java:84)

           at
org.apache.hivemind.impl.ProxyBuilder.<init>(ProxyBuilder.java:67)

           at
org.apache.hivemind.impl.servicemodel.SingletonServiceModel.createSingletonP
roxyClass(SingletonServiceModel.java:129)

           at
org.apache.hivemind.impl.servicemodel.SingletonServiceModel.createSingletonP
roxy(SingletonServiceModel.java:89)

           ... 21 more

Caused by: java.lang.RuntimeException: javassist.NotFoundException: org

           at javassist.CtClassType.getClassFile2(CtClassType.java:197)

           at javassist.CtClassType.getFieldsCache(CtClassType.java:551)

           at javassist.CtClassType.getDeclaredField2(CtClassType.java:572)

           at javassist.CtClassType.getField2(CtClassType.java:515)

           at javassist.CtClassType.getField(CtClassType.java:507)

           at
javassist.compiler.MemberResolver.lookupFieldByJvmName2(MemberResolver.java:
249)

           at
javassist.compiler.TypeChecker.fieldAccess(TypeChecker.java:774)

           at
javassist.compiler.TypeChecker.atFieldRead(TypeChecker.java:702)

           at javassist.compiler.TypeChecker.atExpr(TypeChecker.java:504)

           at javassist.compiler.ast.Expr.accept(Expr.java:67)

           at
javassist.compiler.TypeChecker.fieldAccess(TypeChecker.java:759)

           at
javassist.compiler.TypeChecker.atFieldRead(TypeChecker.java:702)

           at javassist.compiler.TypeChecker.atExpr(TypeChecker.java:504)

           at javassist.compiler.ast.Expr.accept(Expr.java:67)

           at
javassist.compiler.TypeChecker.fieldAccess(TypeChecker.java:759)

           at
javassist.compiler.TypeChecker.atFieldRead(TypeChecker.java:702)

           at javassist.compiler.TypeChecker.atExpr(TypeChecker.java:504)

           at javassist.compiler.ast.Expr.accept(Expr.java:67)

           at
javassist.compiler.TypeChecker.fieldAccess(TypeChecker.java:759)

           at
javassist.compiler.TypeChecker.atFieldRead(TypeChecker.java:702)

           at javassist.compiler.TypeChecker.atExpr(TypeChecker.java:504)

           at javassist.compiler.ast.Expr.accept(Expr.java:67)

           at
javassist.compiler.TypeChecker.fieldAccess(TypeChecker.java:759)

           at
javassist.compiler.TypeChecker.atFieldRead(TypeChecker.java:702)

           at javassist.compiler.TypeChecker.atExpr(TypeChecker.java:504)

           at javassist.compiler.ast.Expr.accept(Expr.java:67)

           at
javassist.compiler.TypeChecker.atCallExpr(TypeChecker.java:586)

           at
javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:156)

           at javassist.compiler.ast.CallExpr.accept(CallExpr.java:45)

           at
javassist.compiler.TypeChecker.atCallExpr(TypeChecker.java:586)

           at
javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:156)

           at javassist.compiler.ast.CallExpr.accept(CallExpr.java:45)

           at javassist.compiler.CodeGen.doTypeCheck(CodeGen.java:235)

           at javassist.compiler.CodeGen.compileExpr(CodeGen.java:222)

           at javassist.compiler.CodeGen.atReturnStmnt2(CodeGen.java:591)

           at
javassist.compiler.JvstCodeGen.atReturnStmnt(JvstCodeGen.java:424)

           at javassist.compiler.CodeGen.atStmnt(CodeGen.java:356)

           at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)

           at javassist.compiler.CodeGen.atMethodBody(CodeGen.java:285)

           at javassist.compiler.Javac.compileBody(Javac.java:208)

           at javassist.CtBehavior.setBody(CtBehavior.java:188)

           at javassist.CtBehavior.setBody(CtBehavior.java:163)

           at
org.apache.hivemind.service.impl.ClassFabImpl.addMethod(ClassFabImpl.java:30
2)

           ... 25 more

 

   _____  

From: Howard Lewis Ship [mailto:hlship@gmail.com] 
Sent: 22. januar 2005 22:08
To: hivemind-user@jakarta.apache.org
Subject: Re: Problems using custom ClassLoader

 

That's looking suspiciously like a Javassist bug to me.



 


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.779 / Virus Database: 526 - Release Date: 19-10-2004