黑马程序员技术交流社区

标题: 编写自己的类加载器ClassLoader [打印本页]

作者: 血马雄风    时间: 2015-8-28 10:14
标题: 编写自己的类加载器ClassLoader


技术要求:编写自己的类加载器ClassLoader
          对原有的class文件加密

技术要点:1、使用ClassLoader
          2、

public class MyClass extends Date{
    public MyClass(){System.out.prionln("my class");}
    public String toString(){ return "my class is running"}
}


public class Cypher{
    //.class文件目录
    private String classFrom = null;  //MyClass.class的路径
    private String classTo = null;    //加密MyClass.class后的保存路径
    public Cypher(){}
    public Cypher(String classFrom, String classTo){
        this.classFrom = classFrom;
        this.classTo = classTo;
    }

    //将输入流数据读到输出流:加密与解密一体
    private void cypher(InputStream input, OutputStream output){
        int b = -1;
        while((b = input.read()) != -1){
            output.write(b ^ 0xff)  //异或
        }      
    }

    private void doWork(){
        try{
            FileInputStream fileInput = new FileInputStream(classFrom);
            FileOutputStrem fileOutput = new FileOutputStrem (classTo);
            ypher(fileInput, fileOutput);  //加密
            fileInput.close();             //一定要记住
            fileOutput.close();
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

//若现在将加密后的class文件覆盖原来好的class文件将会出错,因为原有的加载器无法识别加密文件的内容

public class MyClassLoader extends ClassLoader{
    public String classDir = null;  //加密后的class文件所在的目录
    private MyClassLoader(){}
    public MyClassLoader(String classPath){this.classDir = classDir;}


    //加载文件
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException{
        String classFilePath = classDir + "\\" + name + ".class";
        try{
            FileInputStream fis = new FileInputStream(classFilePath);
            ByteArrayOutputStream bos= new ByteArrayOutputStream();
            new Cypher().cypher(fis, bos);     //解密
            fis.close();
            byte[] bytes = bos.toByteArray();
            //bos.close(); //无效
            return defineClass(null, bytes, 0, bytes.length);
        }cath(IOException e){
            e.printStackTrace();
        }      
        return null;
    }   
}


//main
MyClassLoader myClassLoader = new MyClassLoader(...); //加密后的class文件所在的目录
Class class = myClassLoader.loadClass("MyClass");     //不能包含包名
Date date = (Date)class.newInstance();                //不能使用MyClass,因为MyClass还没有加载
System.out.println(date);


//确保父加载器所加载的目录下没有MyClass.class文件
//需要重启eclipse
//window -- shou view -- problem
//完善:谁对Cypher.class进行加密,如果加密后,如何处理
        加载器应该不能加密吧?







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2