问个关于class loader的问题

linhua11 2013-12-05 06:13:35
package com.dotest;

import java.net.URL;
import java.net.URLClassLoader;

public class Test {

private URLClassLoader loader;

public void doTest() {
resetLoader();
try {
Class testClass = Class.forName("com.dotest.test.ScopeTest", true,
loader);
TestIntf test = (TestIntf) testClass.newInstance();
test.doTest();
System.out.println("finished");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void resetLoader() {
loader = null;
try {
System.out.println("url: "
+ this.getClass().getResource("/testA.jar"));
loader = new URLClassLoader(new URL[] { this.getClass()
.getResource("/testA.jar") });
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static void main(String[] args) {
Test test = new Test();
test.doTest();
}
}


package com.dotest;
public interface TestIntf {
public void doTest();
}


以下代码在单独的jar里面
package com.dotest.test;

import com.dotest.TestIntf;

public class ScopeTest implements TestIntf {
@Override
public void doTest() {
System.out.println("doTest 111");
}
}


运行结果:
url: file:/C:/Users/linh/workspace/DynamicClassLoaderTest/bin/testA.jar
Exception in thread "main" java.lang.ClassCastException: com.dotest.test.ScopeTest cannot be cast to com.dotest.TestIntf
at com.dotest.Test.doTest(Test.java:15)
at com.dotest.Test.main(Test.java:51)
...全文
156 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
linhua11 2013-12-06
  • 打赏
  • 举报
回复
重新试下了,居然神奇的好了,可能是我自己乌龙了,分就分给上面的兄弟了。
linhua11 2013-12-06
  • 打赏
  • 举报
回复
我又加了点测试
package com.dotest;

import java.net.URL;
import java.net.URLClassLoader;

public class Test {

	private URLClassLoader loader;

	public void doTest() {
		resetLoader();
		try {
			Class testIntfClass = Class.forName("com.dotest.TestIntf", true,
					loader);
			System.out.println("111: " + testIntfClass.getName());
			Class testClass = Class.forName("com.dotest.test.ScopeTest", true,
					loader);
			System.out.println("222: " + testClass.getName());
			System.out.println("333: " + testClass.getInterfaces().length);
			TestIntf test = (TestIntf) testClass.newInstance();
			test.doTest();
			System.out.println("finished");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void resetLoader() {
		loader = null;
		try {
			System.out.println("url: "
					+ this.getClass().getResource("/testA.jar"));
			loader = new URLClassLoader(new URL[] { this.getClass()
					.getResource("/testA.jar") });
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		Test test = new Test();
		test.doTest();
	}
}
输出: url: file:/C:/Users/linh/workspace/DynamicClassLoaderTest/bin/testA.jar 111: com.dotest.TestIntf 222: com.dotest.test.ScopeTest 333: 0 Exception in thread "main" java.lang.ClassCastException: com.dotest.test.ScopeTest cannot be cast to com.dotest.TestIntf 证明loader是可以load到interface和class的,可是不知道为什么出错了。
linhua11 2013-12-06
  • 打赏
  • 举报
回复
引用 4 楼 zcw20101 的回复:
我重新仔细看了一下,你的loader是有问题的,楼上的解决方法和lz的本意不一样,没有进行重新加载 你定义的loader没有返回值,正常应该返回一个Class类型,你定义的Loader相当于没有起作用 但是在执行 Class testClass = Class.forName("com.dotest.test.ScopeTest", true, loader); loader为空,所以TestInfo这个类没有被加载,所以才会有 Exception in thread "main" java.lang.ClassCastException: com.dotest.test.ScopeTest cannot be cast to com.dotest.TestIntf TestInfo没有被加载进来,只能在当前路径找TestInfo类,但是当前路径是没有的,所以就报上面的错误了 你可以重新定义resetloader方法,并将返回值传递给你定义的成员变量
我补充下我的本意。 假设在某个固定目录下面有个jar包,下面有一系列实现TestIntf的具体class。并且希望这个jar包的更新能动态加载。 楼上的回复说实话我不是很懂。 TestInfo?还是TestIntf? 我觉得应该是说TestIntf, TestIntf和Test(Loader) 所在的class是在一个类里面啊? 或者您是说我自定义的classloader没有加载TestIntf?
zcw_1985 2013-12-05
  • 打赏
  • 举报
回复
我重新仔细看了一下,你的loader是有问题的,楼上的解决方法和lz的本意不一样,没有进行重新加载 你定义的loader没有返回值,正常应该返回一个Class类型,你定义的Loader相当于没有起作用 但是在执行 Class testClass = Class.forName("com.dotest.test.ScopeTest", true, loader); loader为空,所以TestInfo这个类没有被加载,所以才会有 Exception in thread "main" java.lang.ClassCastException: com.dotest.test.ScopeTest cannot be cast to com.dotest.TestIntf TestInfo没有被加载进来,只能在当前路径找TestInfo类,但是当前路径是没有的,所以就报上面的错误了 你可以重新定义resetloader方法,并将返回值传递给你定义的成员变量
桃园闲人 2013-12-05
  • 打赏
  • 举报
回复
借口了实现类我就不写了,给你测试类中的代码,我测试没有问题,可以输出你想要的结果:

public class Test {

	private URLClassLoader loader;

	public void doTest() {
		try {
			Class testClass = Class.forName("com.ScopeTest");
			TestIntf test = (TestIntf) testClass.newInstance();
			test.doTest();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void resetLoader() {
		loader = null;
		try {
			System.out.println("url: "
					+ this.getClass().getResource("/testA.jar"));
			loader = new URLClassLoader(new URL[] { this.getClass().getResource("/testA.jar") });
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Test tt = new Test();
		tt.doTest();
	}

}
zcw_1985 2013-12-05
  • 打赏
  • 举报
回复
我想你的本意是调用实现类ScopeTest的doTest方法吧,为什么还要 TestIntf test = (Te[/b]stIntf) testClass.newInstance(); 我想你代码的本意应该是这样的吧??把强制转换去掉吧 Class testClass = Class.forName("com.dotest.test.ScopeTest", true, loader); TestIntf test = testClass.newInstance(); test.doTest();
wuer0520 2013-12-05
  • 打赏
  • 举报
回复
我只看懂了类型转换错误

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧