先写个java类的:
allen.java
import java.util.Date;
/**
* 加载类
* @author Administrator
*/
public class allen extends Date{
private static final long serialVersionUID = 8627644427315706176L;
//打印数据
@Override
public String toString(){
return "Hello ClassLoader!";
}
}
然后把编译的.class文件放到 其它 目录下
新建一个class_temp用于保存加密的class文件
防止冲突修改下名字
编写自定义加载器:
//MyClassLoader.java
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 自定义的类加载器
* @author Administrator
*/
public class MyClassLoader extends ClassLoader{
//需要加载类.class文件的目录
private String classDir;
//无参的构造方法,用于class.newInstance()构造对象使用
public MyClassLoader(){
}
public MyClassLoader(String classDir){
this.classDir = classDir;
}
@SuppressWarnings("deprecation")
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
//class文件的路径
String classPathFile = classDir + "/" + name + ".class";
try {
//将class文件进行解密
FileInputStream fis = new FileInputStream(classPathFile);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
encodeAndDecode(fis,bos);
byte[] classByte = bos.toByteArray();
//将字节流变成一个class
return defineClass(classByte,0,classByte.length);
} catch (Exception e) {
e.printStackTrace();
}
return super.findClass(name);
}
//测试,先将ClassLoaderAttachment.class文件加密写到工程的class_temp目录下
public static void main(String[] args) throws Exception{
//配置运行参数
//String srcPath = args[0];//ClassLoaderAttachment.class原路径
String srcPath = "/Users/liuhailong/IdeaProjects/testjava/allen.class";
//String desPath = args[1];//ClassLoaderAttachment.class输出的路径
String desPath ="/Users/liuhailong/IdeaProjects/testjava/class_temp";
String desFileName = srcPath.substring(srcPath.lastIndexOf("/")+1);
String desPathFile = desPath + "/" + desFileName;
FileInputStream fis = new FileInputStream(srcPath);
FileOutputStream fos = new FileOutputStream(desPathFile);
//将class进行加密
encodeAndDecode(fis,fos);
fis.close();
fos.close();
}
/**
* 加密和解密算法
* @param is
* @param os
* @throws Exception
*/
private static void encodeAndDecode(InputStream is,OutputStream os) throws Exception{
int bytes = -1;
while((bytes = is.read())!= -1){
bytes = bytes ^ 0xff;//和0xff进行异或处理
os.write(bytes);
}
}
}
添加俩个参数 也可以直接写死
先运行自定义的加载器(因为有 main 函数 用于加密)
运行完后就多了个加密后的类
编写测试类
//ClassLoaderTest.java
import java.util.Date;
import java.util.List;
/**
* 测试类
* @author Administrator
*/
public class ClassLoaderTest {
@SuppressWarnings("rawtypes")
public static void main(String[] args){
//输出ClassLoaderText的类加载器名称
System.out.println("ClassLoaderText类的加载器的名称:"+ClassLoaderTest.class.getClassLoader().getClass().getName());
System.out.println("System类的加载器的名称:"+System.class.getClassLoader());
System.out.println("List类的加载器的名称:"+List.class.getClassLoader());
System.out.println("默认的类加载器:"+ClassLoaderTest.class.getClassLoader().getSystemClassLoader());
ClassLoader cl = ClassLoaderTest.class.getClassLoader();
while(cl != null){
System.out.print(cl.getClass().getName()+"->");
cl = cl.getParent();
}
System.out.println(cl);
try {
Class classDate = new MyClassLoader("/Users/liuhailong/IdeaProjects/testjava/class_temp").loadClass("allen");
Date date = (Date) classDate.newInstance();
//输出ClassLoaderAttachment类的加载器名称
System.out.println("ClassLoader:"+date.getClass().getClassLoader().getClass().getName());
System.out.println(date);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
ClassLoaderText类的加载器的名称:sun.misc.Launcher$AppClassLoader
System类的加载器的名称:null
List类的加载器的名称:null
默认的类加载器:sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$AppClassLoader->sun.misc.Launcher$ExtClassLoader->null
ClassLoader:MyClassLoader
Hello ClassLoader!
运行