本帖最后由 328078121 于 2013-9-2 07:35 编辑
public class ClassLoaderTest { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { //通过自定义的类加载器MyClassLoader,将在itcast目录下加载名称为ClassLoaderAttachment的类, //注意:我这里我是新建一的个包,测试时,记得根据实际来修改 Class clazz = new MyClassLoader("itcastlib2").("cn.classloader.ClassLoaderAttachment"); //打印加载该类是那个加载器。 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); //copy(fis,fos);//复制文件到itcastlib2中不加密,采用没解密的加载,不行,解 cypher(fis,fos);//采用加密的加载 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//当父类找不到才会执行这里 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"; System.out.println(classFileName);//打印被加载的类,走到这能看到正确找到所要加载的了 System.out.println("zi zhao");//查看是否是子类找, try{ //把要加载的类关联到流上 FileInputStream fis = new FileInputStream(classFileName); ByteArrayOutputStream bos = new ByteArrayOutputStream(); //因为本例中itcastlib2中的类是过加载必的,所以在此要解密 //cypher(fis,bos);//注释传入一个不加密的,不行,FormatError cypher(fis,bos);//传入不加密的且时行解密也不行,Incompatible magic value 889275713 in class file //为什么一旦采用加载不加密的类时,不管解不解密,都运行不了? //直接把父类能正常加载那一份(没加密过的)给子类(通过不解密的方式)加载也是不行? 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,懂得帮忙解决一下,搞了一天都没搞懂问题出现在哪?
|