--------------------------
如何产生ClassCastException:
--------------------------
AntClassLoader加载HelloWorld.class(它在1.jar),然后new Instance 为HelloWorld1,
URLClassLoader再加载相同的HelloWorld.class(它在2.jar),然后new Instance 为HelloWorld2,
AppClassLoader把HelloWorld1传入到URLClassLoader 加载的ForceConversion.class的instance中,
在ForceConversion的instance中做强制转换 : 将HelloWorld1转换到HelloWorld2.此时出现ClassCastException。
原因:同包名同类名的class被不同的classloader加载,注意这两个classloader不存在parent关系,属于平等地位。
如果将某个classloader的一个class强制转换到另外一个classloader的同名class时候,就会发生ClassCastException。
------------------------
如何制造这个case:
------------------------
1.制作一个HelloWorld.class,打包到c:/1.jar;
2.制作一个ForceConversion.class,将HellWorld和ForceConversion打包到c:/2.jar;
3.此时更改HelloWorld--->HelloWorld1,ForceConversion--->ForceConversion1
4.运行DifferentClassLoader,就会导致ClassCastException。
参考代码:
package com.tools.classloader.data;
public class HelloWorld {
private String name = null;
public HelloWorld(){
System.out.println( this.getClass().getClassLoader()+ " is loading "+ this.getClass().getName()+".class ("+this+")");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.tools.classloader.data;
public class ForceConversion {
HelloWorld helloWorld2= new HelloWorld();
public void setHelloWorld(Object helloWorld1){
//ForceConversion's classloader
System.out.println(this.getClass().getName() + "(" + this + ")" + "'s classloader is " + this.getClass().getClassLoader());
//helloWorld1's classloader
System.out.println("helloWorld1: "+helloWorld1.getClass().getName() + "(" + helloWorld1 + ")" + "'s classloader is " + helloWorld1.getClass().getClassLoader());
//helloWorld2's classloader
System.out.println("helloWorld2: "+helloWorld2.getClass().getName() + "(" + helloWorld2 + ")" + "'s classloader is " + helloWorld2.getClass().getClassLoader());
helloWorld2 = (HelloWorld) helloWorld1;
}
}
package com.tools.classloader;
import java.lang.reflect.Method;
import junit.framework.TestCase;
public class DifferentClassLoader extends TestCase {
public DifferentClassLoader(String name) {
super(name);
}
protected void setUp() throws Exception {
super.setUp();
}
protected void tearDown() throws Exception {
super.tearDown();
}
public void testClassLoader() throws Exception {
//--------------------------------------
// AntClassLoader
//--------------------------------------
String[] jars=new String[]{"C:/1.jar"};
AntClassLoaderUtil util=new AntClassLoaderUtil();
ClassLoader antClassLoader=util.getAntClassLoaderFromJars(jars);
String HelloWorldName = "com.tools.classloader.data.HelloWorld";
Class HelloWorld1Clazz = null;
try {
HelloWorld1Clazz=antClassLoader.loadClass(HelloWorldName);
} catch (ClassNotFoundException e) {
System.out.println("class not found");
}
// new HelloWorld1 instance
Object HelloWorld1=HelloWorld1Clazz.newInstance();
Method method1 = HelloWorld1Clazz.getMethod("setName", new Class[]{String.class});
method1.invoke(HelloWorld1, "HelloWorld1");
method1 = HelloWorld1Clazz.getMethod("getName", new Class[]{});
Object value1 = method1.invoke(HelloWorld1,null);
//check which classloader is used.
System.out.println("HelloWorld1's name:"+value1);
System.out.println("HelloWorld1's classLoader:"+HelloWorld1.getClass().getClassLoader());
//--------------------------------------
// URLClassLoader
//--------------------------------------
String[] jarsLocation= new String[] {"C:/2.jar"};
String className="com.tools.classloader.data.ForceConversion";
Object forceConversion = URLClassLoaderUtil.getInstance(jarsLocation,className);
//将HelloWorld1传入到另外一个classloader的class中去。
Method method2 = forceConversion.getClass().getMethod("setHelloWorld", new Class[]{Object.class});
method2.invoke(forceConversion, HelloWorld1);
}
}
package com.tools.classloader;
import java.io.File;
import java.io.FilenameFilter;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.Path;
public class AntClassLoaderUtil
{
public ClassLoader getAntClassLoaderFromDir(String[] directory)
{
Project project = new Project();
project.init();
Path path = new Path(project, null);
for (int i = 0; i < directory.length; i++) {
File dir = new File(directory[i]);
String[] filePaths = null;
if (dir.isDirectory()&& dir.exists()) {
File[] files = dir.listFiles(new FilenameFilter ()
{
public boolean accept (File file, String name)
{
return name.endsWith (".jar") || name.endsWith (".zip");
}
});
filePaths = new String[files.length];
for (int j = 0; j < files.length; j++) {
filePaths[j] = files[j].getAbsolutePath();
path.setPath(filePaths[j]);
}
}
}
String[] paths=path.list();
for (int i = 0; i < paths.length; i++) {
// System.out.println(paths[i]);
}
AntClassLoader loader = new AntClassLoader(project, path);
return loader;
}
public ClassLoader getAntClassLoaderFromJars(String[] jarspath)
{
Project project = new Project();
project.init();
Path path = new Path(project, null);
for (int i = 0; i < jarspath.length; i++) {
File jar = new File(jarspath[i]);
if (jar.isFile()&& jar.exists()&& (jar.getName().indexOf(".jar")>0)) {
path.setPath(jar.getAbsolutePath());
}
}
String[] paths=path.list();
for (int i = 0; i < paths.length; i++) {
// System.out.println(paths[i]);
}
AntClassLoader loader = new AntClassLoader(project, path);
return loader;
}
public static void main(String[] args) throws Exception
{
String[] directorys=new String[2];
directorys[0]="C:/wasx/lib/";
directorys[1]="C:/wasx/plugins";
AntClassLoaderUtil util=new AntClassLoaderUtil();
ClassLoader antClassLoader=util.getAntClassLoaderFromDir(directorys);
System.out.println(AntClassLoader.class.getClassLoader());
System.out.println(antClassLoader.getParent());
System.out.println(antClassLoader.getParent().getParent());
System.out.println(antClassLoader.getParent().getParent().getParent());
String RecoveryDataContainerName = "com.ibm.wbiserver.manualrecovery.RecoveryDataContainer";
try {
antClassLoader.loadClass(RecoveryDataContainerName);
} catch (ClassNotFoundException e) {
System.out.println("class not found");
}
}
}
package com.tools.classloader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Connection;
import java.sql.Driver;
import java.util.Properties;
public class URLClassLoaderUtil {
public static Object getInstance(String[] jarsLocation,String fullClassName ){
URL[] urls = new URL[jarsLocation.length];
for (int i = 0; i < jarsLocation.length; i++) {
try {
urls[i]= new URL("file:"+jarsLocation[i]);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
URLClassLoader ucl = new URLClassLoader(urls);
Class clazz=null;
try {
clazz = ucl.loadClass(fullClassName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Object instance=null;
try {
instance= clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return instance;
}
}
相关文章
- 如何处理java2d中的ClassCastException (Bug-ID 7172749)
- 关于android使用ksoap2报Caused by: java.lang.ClassCastException: org.ksoap2.SoapFault cannot be cast to or
- 《徐徐道来话Java》(2):泛型和数组,以及Java是如何实现泛型的
- Android 用webService产生java.lang.ClassCastException: org.ksoap2.serialization.SoapPrimitive错误的解决(转)
- Vue Demi是如何让你的库同时支持Vue2和Vue3的
- 双非硕士的辛酸求职回忆录:第 2 篇 谈谈我是如何同时找到Java、Python、Go等开发岗和国企银行的科技岗位Offer(上篇)
- '2'>'10'==true? JS是如何进行隐式类型转换的?
- 详解商业智能“前世今生”,“嵌入式BI”到底是如何产生的?
- 通过3个Hello World应用来了解ASP.NET 5应用是如何运行的(2)
- EC2 AMI和安装的第三方软件 - 这是如何工作的?