代码之家  ›  专栏  ›  技术社区  ›  George Armhold

jdk 1.6中的javacompiler:如何将类字节直接写入byte[]数组?

  •  7
  • George Armhold  · 技术社区  · 15 年前

    所以我最近才知道 JavaCompiler API JDK 1.6中提供。这使得编译 String 到A .class 直接来自运行代码的文件:

    String className = "Foo";
    String sourceCode = "...";
    
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    
    List<JavaSourceFromString> unitsToCompile = new ArrayList<JavaSourceFromString>() 
        {{ 
             add(new JavaSourceFromString(className, sourceCode)); 
        }};
    
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    compiler.getTask(null, fileManager, null, null, null, unitsToCompile).call();
    fileManager.close();    
    
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    FileInputStream fis = new FileInputStream(className + ".class");
    IOUtils.copyStream(fis, bos);
    
    return bos.toByteArray();
    

    您可以将源抓取到 JavaSourceFromString Javadoc .

    这将非常容易编译 sourceCode Foo.class 在当前工作目录中。

    我的问题是 :是否可以直接编译为 byte[] 排列,避免处理混乱 File 输入输出?

    3 回复  |  直到 15 年前
        1
  •  2
  •   Turing    15 年前

    也许你可以创造你自己的 javax.tools.JavaFileManager 实现类,在该类中,您将返回自己的 javax.tools.FileObject 然后把它写进内存而不是磁盘。所以对于你的子类 javax.tools.fileobject文件对象 Writer openWriter() throws IOException 方法返回 java.io.StringWriter . 所有方法都应转换为 String 相对应的人。

        2
  •  2
  •   Stephen C    15 年前

    不存在将字节码写入字节数组的标准API的原因是编译单个Java源文件可能导致多字节代码文件。例如,任何具有嵌套/内部/匿名类的源文件都将导致多个字节码文件。

    如果您使用自己的JavaFileManager,则需要处理这种情况。

        3
  •  2
  •   Community PPrice    7 年前

    JSR199 API附带的演示应用程序有一个从字符串示例编译的内存中编译的示例(它确实使用了 MemoryFileManager )也许看看吧 here here (尽管这些样品有点过时,但需要稍作改动)。也可以检查 How to compile on the fly? 关于java.net的文章。

    附:我没有看所有的细节,但我不认为它能处理 Stephen C .