作者del680202 (HANA)
看板java
标题[问题] ClassLoader的一个问题
时间Mon Dec 14 15:00:16 2009
今天在写程式的时候
我希望让我程式有类似plug-in的功能
所以我试着用URLClassLoader去实作这个功能
首先我测试了一下
先用eclipse开了一个project A
里面一个interface
interface CLI2 {
public String say();
}
而存在一个class 去实作他
public class CLTest implements CLI2 {
static{
System.out.println("Now!Class Load!");
}
@Override
public String say() {
System.out.println("Hello I am a happy boy!");
return "Hello";
}
}
我把他输出成tester.jar
之後我再开了一个project B
里面是引用他的程式码
URL url1 = new URL("file:c:/TC/");
URLClassLoader urlClassLoader1 =
new URLClassLoader(new URL[] {url1}
,Thread.currentThread().getContextClassLoader());
Class c2 = urlClassLoader1.loadClass("CLTest");
Object o=c2.newInstance();
CLI2 ci=(CLI2)o;
ci.say();
-----------------------------
Project B里面有只相同的inteface CLI2,他是希望用来转型
跑下去後出现了error
Exception in thread "main" java.lang.IllegalAccessError:
class CLTest cannot access its superinterface CLI2
上网查了一下原因,似乎是因为当前的classLoader没办法存取他的interface
我把程式作了修改,URLClassLoader第二个参数改成null
URL url1 = new URL("file:c:/TC/");
URLClassLoader urlClassLoader1 =
new URLClassLoader(new URL[] {url1}
,null);
Class c2 = urlClassLoader1.loadClass("CLTest");
Object o=c2.newInstance();
CLI2 ci=(CLI2)o;
ci.say();
虽然解决了第一个问题却延伸出另一个问题
在CLI2 ci=(CLI2)o;的地方出现转型错误的exception
Exception in thread "main" java.lang.ClassCastException:
CLTest cannot be cast to CLI2
後来上网查了一下资料 才知道他型别判定是除了class name跟package name
还包括ClassLoader,我的CLI2是AppClassLoader载入的
o则是我创造的URLClassLoader载入的
我的问题是,我要如何在Project B保有inteface CLI2的情况下
可以让他跟我用URLClassLoade载入的CLTest物件相容
或是用Thread.currentThread().getContextClassLoader()
让他可以抓到CLT2的interface部出现error
请高手指教
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 122.126.48.73
※ 编辑: del680202 来自: 122.126.48.73 (12/14 15:03)
1F:推 PsMonkey:不太懂.. 为甚麽需要两个 CLI2? 12/14 15:24
一个是我Project A实作用到到 一个是Project B产生实体拿来转型用
因为是不同的Project,或许有更好的方法吧
※ 编辑: del680202 来自: 122.126.48.73 (12/14 15:30)
2F:推 snowlike:PA和PB实作的CLI2要同个,这也是为什麽需import避免撞名 12/14 15:55
PA跟PB有的CLI2是同样的内容
我有试着PA只输出CLTest的.class档
但是会出现NoClassDefFoundError的错误 没有CLI2的定义
因为我希望是说,我主程式放一个地方 plug-in可以放另一个地方
以後只要更新plug-in就能更新程式,而我plug-in只需要实作相同介面就可以了
※ 编辑: del680202 来自: 122.126.48.73 (12/14 16:07)
//////////////////////////////////////////////////////////////////////
问题解决了,snowlike大的话给了我一点启示
我Project A原先两只程式都是放在default package
我把interface的部分放在另一个package org.cusano
而Project B同样维护着一份interface,而我在同样的创造一个package org.cusano在PB
之後PA的实作部分跟PB的引用部分都去import org.cusano.*;
这样就解决了冲突的问题
感激不尽
※ 编辑: del680202 来自: 122.126.48.73 (12/14 16:24)
※ 编辑: del680202 来自: 122.126.48.73 (12/14 16:25)
3F:→ sbrhsieh:在两个地方维护必须相同的两份码是给自己找麻烦... 12/14 16:26
4F:→ del680202:只维护相同的interface 主要是想针对interface就好 12/14 16:27
5F:→ del680202:不过或许有更好的方法吧 暂时没想到 12/14 16:30