我的Java 6中动态编译被正常使用。不过,我想改变输出路径。我曾尝试吨的东西(我就不告诉你),都无济于事。总之,这里的工作代码

String[] filesToCompile = { "testFiles/Something.java" };
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(filesToCompile);
CompilationTask task = compiler.getTask(null, fileManager, null,null, null, compilationUnits);
System.out.println("Good? " + task.call());

但输出为源目录,这不是我想要的。

我怀疑,答案可能在于compiler.getTask但是API并不像什么的一些参数可能意味着非常明确的。或许一些与文件管理器。我已经试过

fileManager.setLocation(StandardLocation.locationFor("testFiles2"), null);

但同样,猜测可能不是一个好主意。

谢谢!

编辑:我一直使用期权试过了,太像这种(抱歉,如果有一个更紧凑的方式):

    final List<String> optionsList = new ArrayList<String>();
    optionsList.add("-d what");
    Iterable<String> options = new Iterable<String>() {         
        public Iterator<String> iterator() {
            return optionsList.iterator();
        }
    };

和然后使选项getTask,但错误信息为“无效标志。”

有帮助吗?

解决方案

在第一篇文章代码的工作,但下面的错误提示的抛出:

java.lang.IllegalArgumentException: invalid flag: -d folder

这是因为通过传递"-d folder"使得解析器认为它解析一个选项。该选项必须分开像"-d", "folder"

工作示例如下:

JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager sjfm = javaCompiler.getStandardFileManager(null, null, null); 

String[] options = new String[] { "-d", "output" };
File[] javaFiles = new File[] { new File("src/gima/apps/flip/TestClass.java") };

CompilationTask compilationTask = javaCompiler.getTask(null, null, null,
        Arrays.asList(options),
        null,
        sjfm.getJavaFileObjects(javaFiles)
);
compilationTask.call();

其他提示

我今天面临同样的问题。

答案(使用常规方法getTask代替`运行)是指定在文件管理输出DIR:

fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(outputDir));

这就是它! :)

该文档是有点误导,我的意思是,样品可以来非常方便。但最终我花了那里。

修改

下面是一个运行示例:

    // write the test class
    File sourceFile   = new File("First.java");
    FileWriter writer = new FileWriter(sourceFile);

    writer.write(
            "package load.test;\n" +
            "public class First{}"
    );
    writer.close();

    // Get the java compiler for this platform
    JavaCompiler compiler    = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(
            null,
            null,
            null);

    //--           H E R E    --// 
    // Specify where to put the genereted .class files
    fileManager.setLocation(StandardLocation.CLASS_OUTPUT, 
                            Arrays.asList(new File("/tmp")));
    // Compile the file
    compiler
        .getTask(null,
                fileManager,
                null,
                null,
                null,
                fileManager.getJavaFileObjectsFromFiles(Arrays.asList(sourceFile)))
        .call();
    fileManager.close();

    // delete the file
    sourceFile.deleteOnExit();

我对Java 6的动态编译工具0经验。但没有人回答了:)

在编译任务得到一个FileManager对象。如果您使用标准之一,那么类是在源目录树中产生。你可以做的是提供自己的文件管理器子与重写getFileForOutput方法。 getFileForOutput的API描述表明这会影响您的输出(=类)文件将去。

<强>更新

如何挂钩文件管理器

  

ForwardingJavaFileManager,ForwardingFileObject和ForwardingJavaFileObject   子类不可用于,不通过调用构造函数重载标准的文件管理器的行为,因为它是通过调用编译器的方法创建的。相反,转发(或委托)应该被使用。这些类可以很容易地转发最来电的给定文件管理器或文件对象,同时允许自定义行为。例如,考虑如何登录到JavaFileManager.flush()的所有呼叫:

   final Logger logger = ...;
   Iterable<? extends JavaFileObject> compilationUnits = ...;
   JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
   StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
   JavaFileManager fileManager = new ForwardingJavaFileManager(stdFileManager) {
       public void flush() {
           logger.entering(StandardJavaFileManager.class.getName(), "flush");
           super.flush();
           logger.exiting(StandardJavaFileManager.class.getName(), "flush");
       }
   };
   compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();

<强>更新2

我的动态编译阅读并建立了自己的应用程序来做到这一点。该代码包含有点过分仪式(即,它可以简化),但它的作品!

package yar;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

public class DynamicCompiler {

   JavaCompiler compiler;

   public DynamicCompiler() {
      this.compiler = ToolProvider.getSystemJavaCompiler();
      if (this.compiler == null) {
         throw new NullPointerException("Cannot provide system compiler.");
      }
   }

   public void compile() {
      this.compiler.run(null, System.out, System.err, 
            "-d", "testFiles2", 
            "testFiles/Hello1.java", "testFiles/Hello2.java");
   }

   /**
    * @param args
    */
   public static void main(String[] args) {
      try {
         DynamicCompiler dc = new DynamicCompiler();
         dc.compile();
      } catch (Exception e) {
         System.err.println(e.getMessage());
      }
   }

}

我不知道如何得到这个代码的Java文件动态生成的列表工作;我可能只是为每个源文件做compiler.run分开。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top