请教bang老师关于自定义classloader的一些问题

10-03-26 acerow
    

您好bang老师,由于项目需要,我需要自定义一个classloader,去加载几个特殊的class,之前对classloader的了解并不深入,我在网上查了很多资料,自己写了一个Mycalssloader(其实就是复制过来的),然后做测试,

类似于这样的class

public class Test {

public void aaa(){

}

}

load这样简档的class都没问题,但是一旦要load一些引用许多第三方组件的,包括读取数据库的class就会报错,但是这些class用java的反射也没问题,不知自定义的classloader还缺少了那些东西,请您指点!

以下是些报错信息:

root cause

java.lang.reflect.InvocationTargetException

sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

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

root cause

java.lang.NoClassDefFoundError: org/apache/cayenne/query/Query

java.lang.Class.getDeclaredMethods0(Native Method)

java.lang.Class.privateGetDeclaredMethods(Unknown Source)

java.lang.Class.privateGetPublicMethods(Unknown Source)

java.lang.Class.getMethods(Unknown Source)

    

1
banq
2010-03-26 20:25

如果把JVM看成一个容器,classloader相当于容器中的容器,JVM就是由大量嵌套的classloader组成的,既然是容器,就有边界问题,有父子关系,大概是子能加载父classloader里的类,但不能加载子,反正关系比较复杂。

一般使用Thread.xxx.getClassLoader能获得当前运行场景的classloader,从而正确加载你要加载的类。

OSGI可以帮助你简化复杂的classloader问题。

具体查查相关资料。

xmuzyu
2010-03-26 22:36

2010年03月26日 15:55 "acerow"的内容
您好bang老师,由于项目需要,我需要自定义一个classloader,去加载几个特殊的class,之前对classloader的了解并不深入,我在网上查了很多资料,自己写了一个Mycalssloader(其实就是复制过来的),然后做测试, ...

你好,请问你的classloader是重写了哪个方法,loadClass还是findClass方法,一般只需要重写findClass即可,因为loadClass方法默认有委托模型的。如果依赖第三方库话,你要保证第三方库在classpath,或者第三方库在jre/lib/ext目录下。

acerow
2010-03-29 09:58

谢谢banq老师及xmuyu的帮助!果然是边界路径的问题,我把lib下相关的jar释放到web-inf 下的classes下就可以了! 再次感谢!

另外向banq老师道歉,不好意思将您的名字写错了,见谅!