本帖最后由 谢洋 于 2013-3-15 08:00 编辑
- public class ClassLoaderTest {
- public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
- //通过自定义的类加载器MyClassLoader,将在itcast目录下加载名称为ClassLoaderAttachment的类,老父找得着.
- <FONT style="BACKGROUND-COLOR: yellow">//注意:我这里我是新建一的个包,测试时,记得根据实际来修改
- </FONT>Class clazz = new MyClassLoader<FONT style="BACKGROUND-COLOR: yellow">("itcastlib2").</FONT>loadClass<FONT style="BACKGROUND-COLOR: yellow">("cn.classloader.ClassLoaderAttachment");
- </FONT>
- //打印加载该类是那个加载器。
- System.out.println(clazz.getClassLoader().getClass().getName());
- System.out.println(clazz.getName());//被加载的类
- System.out.println("xxxxxxxx");
- }
- }
复制代码- public class MyClassLoader extends ClassLoader {
- public static void main(String[] args) throws Exception {
- String srcPath = args[0];
- String destDir = args[1];
- FileInputStream fis = new FileInputStream(srcPath);
- System.out.println(srcPath);
- System.out.println(destDir);
- //得到输入文件名称
- String destFileName = srcPath.substring(srcPath.lastIndexOf("\\")+1);
- System.out.println(destFileName);
- //得到文件要存入到的路径
- String destPath = destDir +"\\"+destFileName;
- System.out.println(destPath);
- //生产一个文件输出流,并关联到destPath
- FileOutputStream fos = new FileOutputStream(destPath);
- <FONT style="BACKGROUND-COLOR: yellow">//copy(fis,fos);//复制文件到itcastlib2中不加密,采用没解密的加载,不行,解
- cypher(fis,fos);//采用加密的加载</FONT>
- fis.close();
- fos.close();
- }
- //复制
- private static void copy(InputStream ips,OutputStream ops) throws Exception{
- int b = -1;
- System.out.println("copy");
- while((b=ips.read())!=-1){
- ops.write(b);
- }
- }
- //加密方法///
- private static void cypher(InputStream ips,OutputStream ops) throws Exception{
- int b = -1;
- while((b=ips.read())!=-1){
- ops.write(b^0xff);
- }
- }
- private String classDir;
- //构造这个类时,把指定的目录itcastlib传入,这样就指定了该classLoader那那个目录上去找要加载的类了。
- public MyClassLoader(String classDir){
- this.classDir = classDir;
- }
- /**
- * loadClass()方法会调用该方
- * 自定义的加载器必须复写
- * findClass()
- */
- @Override//<FONT style="BACKGROUND-COLOR: yellow">当父类找不到才会执行这里</FONT>
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- //目录加上类的名称
- //把classFileName改为itcastlib\ClassLoaderAttachment,子类才能找到
- String classFileName=classDir +"\\"+ name.substring(name.lastIndexOf('.')+1) + ".class"; //itcast\ClassLoaderAttachment
- //String classFileName=classDir +"\\"+ name + ".class";
- <FONT style="BACKGROUND-COLOR: yellow">System.out.println(classFileName);//打印被加载的类,走到这能看到正确找到所要加载的了
- System.out.println("zi zhao");//查看是否是子类找,</FONT>
- try{
- //把要加载的类关联到流上
- FileInputStream fis = new FileInputStream(classFileName);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- <FONT style="BACKGROUND-COLOR: yellow">//因为本例中itcastlib2中的类是过加载必的,所以在此要解密
- //cypher(fis,bos);//注释传入一个不加密的,不行,FormatError
- cypher(fis,bos);//传入不加密的且时行解密也不行,Incompatible magic value 889275713 in class file
- //为什么一旦采用加载不加密的类时,不管解不解密,都运行不了?
- </FONT>//直接把父类能正常加载那一份(没加密过的)给子类(通过不解密的方式)加载也是不行?
- fis.close();
- byte[] bytes = bos.toByteArray();
- //得到一个Class 实例
- return defineClass(bytes,0,bytes.length);
- //return defineClass(name,bytes,0,bytes.length);
- }catch(Exception e){
- e.printStackTrace();
- }
- return null;
- }
- }
复制代码 上面代码如果和张老师那样,父类加载不加密的类,子类加载经过加密后再解密的方式加载都可以执行,
但我直接把不加密的类copy给子类加载时(所加载类没有加密所以不解密,即使解密也不行),就发生异常了FormatError和Incompatible magic value 889275713 in class file,懂得帮忙解决一下,搞了一天都没搞懂问题出现在哪?
|