Apache的BCEL庫,文檔很少,例子也很簡單。動態構建類的工作,要求的只是并不是熟練使用BCEL類庫本身,而是要對java的class結構了解。我對java的pcode也不熟悉,但是我曾經做過大量的.NET的反編譯工作,兩者類似,所以我用BCEL也不覺得困難。

          我提供一個例子,這里例子是使用BCEL創建類的實例,而不是使用反射。

          如下:

          IFactory.java

          public interface IFactory {
              
          public Object newInstance();    
          }

          FileClassLoader.java
          import java.io.ByteArrayOutputStream;
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.IOException;

          public class FileClassLoader extends ClassLoader {
              
          public FileClassLoader() {
                  super();
              }


              
          public FileClassLoader(ClassLoader parent) {
                  super(parent);
              }


              
          public Class getClass(String className, String filePath) {
                  FileInputStream fileInputStream 
          = null;
                  
          byte[] data = null;
                  
          try {
                      fileInputStream 
          = new FileInputStream(new File(filePath));

                      ByteArrayOutputStream byteArrayOutputStream 
          = new ByteArrayOutputStream();
                      
          int ch = 0;
                      
          while ((ch = fileInputStream.read()) != -1{
                          byteArrayOutputStream.write(ch);
                      }

                      data 
          = byteArrayOutputStream.toByteArray();
                      
          return defineClass(className, data, 0, data.length);
                  }
           catch (IOException e) {
                      e.printStackTrace();
                      
          throw new Error(e.getMessage(), e);
                  }

              }

          }

          buildFactory方法:
          public static IFactory buildFactory(String procductClassName)
                  throws Exception 
          {
              InstructionList il 
          = new InstructionList();
              String className 
          = "HelloWorld";
              ClassGen class_gen 
          = new ClassGen(className, "java.lang.Object",
                      
          "", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null);
              ConstantPoolGen cons_pool 
          = class_gen.getConstantPool();
              class_gen.addInterface(IFactory.
          class.getName());

              InstructionFactory il_factory 
          = new InstructionFactory(class_gen);

              
          // 創建構造函數
              {
                  String methodName 
          = "";

                  Type returnType 
          = Type.VOID;
                  Type[] arg_Types 
          = new Type[] {};
                  String[] arg_names 
          = new String[] {};
                  MethodGen method_gen 
          = new MethodGen(Constants.ACC_PUBLIC,
                          returnType, arg_Types, arg_names, methodName, className,
                          il, cons_pool);

                  
          // super();
                  il.append(InstructionFactory.createLoad(Type.OBJECT, 0));
                  il.append(il_factory.createInvoke(
          "java.lang.Object""",
                          Type.VOID, 
          new Type[0], Constants.INVOKESPECIAL));
                  il.append(InstructionFactory.createReturn(Type.VOID));

                  method_gen.setMaxStack();
                  class_gen.addMethod(method_gen.getMethod());
                  il.dispose(); 
          // Reuse instruction handles of list
              }


              
          {
                  String methodName 
          = "newInstance";
                  Type returnType 
          = Type.OBJECT;
                  Type[] arg_Types 
          = new Type[] {};
                  String[] arg_names 
          = new String[] {};
                  MethodGen method_gen 
          = new MethodGen(Constants.ACC_PUBLIC,
                          returnType, arg_Types, arg_names, methodName, className,
                          il, cons_pool);
                  il.append(il_factory.createNew(procductClassName));
                  il.append(InstructionConstants.DUP);
                  il.append(il_factory.createInvoke(procductClassName, 
          "",
                          Type.VOID, 
          new Type[0], Constants.INVOKESPECIAL));
                  il.append(InstructionFactory.createReturn(Type.OBJECT));
                  method_gen.setMaxStack();

                  class_gen.addMethod(method_gen.getMethod());
                  il.dispose(); 
          // Reuse instruction handles of list
              }


              
          // 保存到文件中
              JavaClass clazz = class_gen.getJavaClass();
              String path 
          = "e:\\temp\\" + className + ".class";
              class_gen.getJavaClass().dump(path);

              
          // 使用ClassLoader裝載class
              FileClassLoader classLoader = new FileClassLoader();
              Class factoryClass 
          = classLoader.getClass(className, path);
              Object newInst 
          = factoryClass.newInstance();

              
          return (IFactory) newInst;
          }

          測試用例:
          String className = "java.lang.Object";
          IFactory factory 
          = buildFactory(className);
          Object inst 
          = factory.newInstance();
          posted on 2005-04-14 23:59 溫少的日志 閱讀(8638) 評論(7)  編輯  收藏
          Comments

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
           
          主站蜘蛛池模板: 班玛县| 涡阳县| 遵义县| 莎车县| 从化市| 澄城县| 运城市| 保定市| 苏尼特右旗| 莎车县| 青铜峡市| 宾川县| 中卫市| 丹江口市| 广德县| 达日县| 罗江县| 阿拉善右旗| 灌南县| 台东县| 宁阳县| 墨竹工卡县| 南京市| 江山市| 南郑县| 黑龙江省| 兴义市| 阿荣旗| 扶绥县| 瓮安县| 景宁| 通海县| 昌都县| 瑞丽市| 苍溪县| 德格县| 乐安县| 井冈山市| 成武县| 丹棱县| 浦城县|