您的位置:首页 > 其它

【自己动手写类加载器2】覆盖findClass(String name)方法,删除bin目录下的加密的class文件

2014-03-30 11:04 615 查看
1、要想实现自己的类加载器能够加载类,需要覆盖findClass(String name)方法,类加载器的loadClass(String name)方法最终调用的还是findClass(String name)。

2、由于类加载器使用的委托机制,先看父类AppClassLoader能不能加载再看自己的类加载器能不能加载,所以要把bin目录下的class文件删掉。

下面是自己写的类加载器,具有加密功能

package com.xiaozhi.myclassloader;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class MyClassLoader extends ClassLoader{

public static void main(String[] args) throws Exception{//生成加密字节码文件
String srcPath = args[0];
String destPah = args[1];
String fileName = srcPath.substring(srcPath.lastIndexOf("\\") + 1);
destPah = destPah +"\\"+fileName;

FileInputStream fileInputStream = new FileInputStream(srcPath);
FileOutputStream fileOutputStream = new FileOutputStream(destPah);
encrypt(fileInputStream, fileOutputStream);
fileInputStream.close();
fileOutputStream.close();
}

private String classDir;

public MyClassLoader(){

}
public MyClassLoader(String classDir){
this.classDir=classDir;
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
String classFileName =classDir+"\\"+name.substring(name.lastIndexOf('.')+1)+".class";
try {
FileInputStream fileInputStream = new FileInputStream(classFileName);
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
encrypt(fileInputStream, arrayOutputStream);
fileInputStream.close();
byte[] bytes = arrayOutputStream.toByteArray();
return defineClass(bytes, 0, bytes.length);
} catch (Exception e) {
e.printStackTrace();
}
return super.findClass(name);
}

public static void encrypt(InputStream inputStream,OutputStream outputStream) throws Exception
{
int b = 0;
while((b=inputStream.read())!=-1)
{
outputStream.write(b^0xff);
outputStream.flush();
}
}
}
类加载器需要加载的类,继承于Date,

package com.xiaozhi.myclassloader;

import java.util.Date;

public class ClassLoaderAttachment extends Date{
@Override
public String toString() {
return "hello heima";
}
}
测试类

package com.xiaozhi.testmyclassloader;

import java.util.Date;

import com.xiaozhi.myclassloader.MyClassLoader;

public class Test {

public static void main(String[] args) throws Exception{
Class clazz=new MyClassLoader("mylib").loadClass("com.xiaozhi.myclassloader.ClassLoaderAttachment");
//		ClassLoaderAttachment loaderAttachment= (ClassLoaderAttachment) clazz.newInstance();//这里不能这样写,因为class文件已经删除,编译器找不到Class文件。
Date date=(Date) clazz.newInstance();
System.out.println(date);

}
}

运行结果



把加密的class复制到原class目录下





运行程序:



找到需要类加载器需要加载的类,敲一个回车,保存一下,生成新的class文件



再次运行



再次把这个新生出的class文件删了



再次运行




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐