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 溫少的日志 閱讀(8646) 評論(7)  編輯  收藏
          Comments

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


          網站導航:
           
           
          主站蜘蛛池模板: 永仁县| 沿河| 兴安县| 文安县| 炉霍县| 莱芜市| 榆中县| 泰州市| 通海县| 甘孜| 鸡东县| 沈阳市| 威信县| 保山市| 兴安县| 云霄县| 宣城市| 正蓝旗| 化隆| 甘谷县| 马山县| 邹平县| 嫩江县| 九寨沟县| 绵竹市| 尚志市| 嘉黎县| 鄂伦春自治旗| 茂名市| 新绛县| 拉萨市| 宁晋县| 仪陇县| 昌平区| 宁波市| 定安县| 丰顺县| 大悟县| 宾阳县| 南澳县| 台山市|