概述
package com.wy.classloader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import sun.reflect.Reflection;
public class DiffClassLoderSamePackage {
public static class Bean {
String defaultFiled ;
public String publicFiled ;
protected String protectedFiled ;
void defaultMethod(Bean b) {
}
protected void protectedMethod(Bean b) {
}
public void publicMethod(Bean b) {
}
public void publicMethod() {
}
}
public static class ClassLader extends ClassLoader {
/**
* 实现优先于父类加载类文件
*/
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
Class<?> c = findLoadedClass(name);
if (c != null) {
return c;
}
byte[] b = getClassBytes(name);
if (b != null) {
return defineClass(name, b, 0, b.length);
} else {
return super.loadClass(name);
}
}
/**
* 读取class文件的内容
*
* @param className
* qualified类名
* @return 文件的字节内容, 异常或者找不到文件时返回null
*/
private byte[] getClassBytes(String className) {
String path = System.getProperty("java.class.path") + File.separator
+ className.replace('.', File.separatorChar) + ".class";
FileInputStream fis = null;
try {
fis = new FileInputStream(path);
byte[] bs = new byte[fis.available()];
fis.read(bs);
return bs;
} catch (Exception e) {
return null;
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
// ignore
}
}
}
}
public static void main(String[] args) throws Exception {
// 由app ClassLoader加载
Bean appB = new Bean();
// 由自定义 ClassLoader加载
ClassLader cust = new ClassLader();
Class<?> custC = cust.loadClass("com.wy.classloader.DiffClassLoderSamePackage$Bean");
// Object custB = (Bean)custC.newInstance(); //1. 不同类加载器加载的类,无法强制类型转换
Object custB = custC.newInstance();
// default
// Method custDefaultM = custC.getDeclaredMethod("defaultMethod", Bean.class); //2. 参数类型判定为不一致
Method custDefaultM = custC.getDeclaredMethod("defaultMethod", custC);
// protected
// Method custProtectedM = custC.getDeclaredMethod("protectedMethod", Bean.class); //2. 参数类型判定为不一致
Method custProtectedM = custC.getDeclaredMethod("protectedMethod", custC);
// public
// Method custPublicM = custC.getDeclaredMethod("publicMethod", Bean.class); //2. 参数类型判定为不一致
Method custPublicM = custC.getDeclaredMethod("publicMethod", custC);
Method custPublicMethodNoArg= custC.getDeclaredMethod("publicMethod");
// 非public成员,当调用者的ClassLoader与加载Method所在Class的ClassLoader不一致时,无法访问 . Reflection.ensureMemberAccess()
// custDefaultM.invoke(custB, custB); //3. can not access a member of class with modifiers ""
// custProtectedM.invoke(custB, custB); //3. can not access a member of class with modifiers "protected"
// public方法通过调用者ClassLoader检测,但对于接收者要进行ClassLoader类型检测.
// custPublicM.invoke(appB, custB);// 4. object is not an instance of declaring class
// custPublicM.invoke(appB, appB);// 4. object is not an instance of declaring class
// custPublicMethodNoArg.invoke(appB);// 4. object is not an instance of declaring class
// custPublicM.invoke(custB, appB);// 5. argument type mismatch
custPublicMethodNoArg.invoke(custB); //ok
custPublicM.invoke(custB, custB);// ok
// 非public成员,当调用者的ClassLoader与加载Method所在Class的ClassLoader不一致时,无法访问 .Reflection.ensureMemberAccess()
custC.getDeclaredField("defaultFiled").get(custB); //6. can not access a member of class with modifiers ""
// custC.getDeclaredField("protectedFiled").get(custB); //6. can not access a member of class with modifiers "protected"
// custC.getDeclaredField("publicFiled").get(appB); //7. Can not set java.lang.String field defaultFiled to Bean
custC.getDeclaredField("publicFiled").get(custB); //ok
}
}
3-6
Exception in thread "main" java.lang.IllegalAccessException:
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
at java.lang.reflect.Method.invoke(Method.java:588)
at com.wy.classloader.DiffClassLoderSamePackage.main
4.
Exception in thread "main" java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.wy.classloader.DiffClassLoderSamePackage.main
5.
Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.wy.classloader.DiffClassLoderSamePackage.main(DiffClassLoderSamePackage.java:121)
7.
Exception in thread "main" java.lang.IllegalArgumentException: Can not set java.lang.String field publicFiled to Bean
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:18)
at java.lang.reflect.Field.get(Field.java:358)
at com.wy.classloader.DiffClassLoderSamePackage.main
最后
以上就是坚定人生为你收集整理的VM中不同ClassLoader权限的限制的全部内容,希望文章能够帮你解决VM中不同ClassLoader权限的限制所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复