我是靠谱客的博主 坚定人生,最近开发中收集的这篇文章主要介绍VM中不同ClassLoader权限的限制,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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权限的限制所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部