题
我的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
分开。