java自定义类加载器

Posted 王南辉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java自定义类加载器相关的知识,希望对你有一定的参考价值。

package lucene.baidu.tets;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class WriteByte {
	/**
	 * 转换四字节,此处主要加密使用可以自己使用加密算法,最后揭秘即可
	 * @param iValue
	 * @return
	 */
	public static byte[] Int2Bytes_LE(int iValue) {
		byte[] rst = new byte[4];
		// 先写int的最后一个字节
		rst[0] = (byte) (iValue & 0xFF);
		// int 倒数第二个字节
		rst[1] = (byte) ((iValue & 0xFF00) >> 8);
		// int 倒数第三个字节
		rst[2] = (byte) ((iValue & 0xFF0000) >> 16);
		// int 第一个字节
		rst[3] = (byte) ((iValue & 0xFF000000) >> 24);
		return rst;
	}

	public static void main(String[] args) throws IOException {

		File file = new File("D:/资料/I盘/MyEclipse 10/Lucene_index/bin/lucene/baidu/tets/Application.class");//读class文件转换字节然后加密使用
		FileChannel fout = new FileOutputStream("D:/资料/I盘/MyEclipse 10/Lucene_index/bin/lucene/baidu/tets/Application.class").getChannel();//写入文件
		RandomAccessFile accessFile = new RandomAccessFile(file, "rw");
		ByteBuffer bf = ByteBuffer.allocate((int) file.length() * 4);
		bf.clear();
		int read = -1;
		while ((read = accessFile.read()) != -1) {
			byte[] bytes = Int2Bytes_LE(read);
			bf.put(bytes);
		}
		System.out.println(bf.limit());
		bf.flip();
		fout.write(bf);
		fout.close();
	}
}

 application.java

package lucene.baidu.tets;

/**
 *    只返回一个句话 
 * @author wangnanhui
 *
 */
public class Application {
    public static String getArr(){
        return "MyClassLoad hello world";
    }
    public static void main(String[] args) {
        System.out.println(Application.getArr());
    }
}

运行后得到加密后的文件,已经反编译不过来了

 

解密代码

package lucene.baidu.tets;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

class MyclassLoad extends ClassLoader {
	/**
	 * 解密方法
	 * @param bytes
	 * @return
	 */
	public int Bytes2Int_LE(byte[] bytes) {
		if (bytes.length < 4)
			return -1;
		int iRst = (bytes[0] & 0xFF);
		iRst |= (bytes[1] & 0xFF) << 8;
		iRst |= (bytes[2] & 0xFF) << 16;
		iRst |= (bytes[3] & 0xFF) << 24;

		return iRst;
	}

	/**
	 * 返回一个class 
	 * @param filePath
	 * @return
	 */
	public Class<?> getMyClass(String filePath) {
		try {
			File file = new File(filePath);
			int length = (int) file.length();
			FileChannel channel = new FileInputStream(file).getChannel();
			ByteBuffer bytes = ByteBuffer.allocate(length);
			ByteBuffer loader = ByteBuffer.allocate(length / 4);
			byte[] read4 = new byte[4];
			bytes.clear();
			loader.clear();
			channel.read(bytes);
			bytes.flip();//开始读取 四个byte的读 , 然后解密到原来的byte
			for (int i = 0; i < length; i += 4) {
				bytes.get(read4);
				loader.put((byte) Bytes2Int_LE(read4));
			}
		return super.defineClass(loader.array(), 0, length / 4);

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		
		MyclassLoad loader = new MyclassLoad();
		Class<?> cls = loader.getMyClass("Application.class");
		System.out.println(cls.getName());
		Method method = cls.getMethod("getArr");
		System.out.println(method.invoke(cls));
		
		
		
		
	}
}

  运行后

 

以上是关于java自定义类加载器的主要内容,如果未能解决你的问题,请参考以下文章

面试必看-Java类加载器(自定义类加载器)

java 自定义类加载器

java自定义类加载器

java类加载器的层次结构,自定义类加载器的步骤

双亲委派模型-java自定义类加载器

深入理解Java虚拟机——类加载器