Java 指定动态编译的输出路径
我在Java6中的动态编译工作得非常好。但是,我想更改输出路径。我试过很多东西(我饶了你)都没有用。不管怎样,这是工作代码Java 指定动态编译的输出路径,java,java-6,dynamic-compilation,Java,Java 6,Dynamic Compilation,我在Java6中的动态编译工作得非常好。但是,我想更改输出路径。我试过很多东西(我饶了你)都没有用。不管怎样,这是工作代码 String[] filesToCompile = { "testFiles/Something.java" }; JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManage
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());
但同样,猜测可能不是一个好主意
谢谢
编辑:我也尝试过使用选项,如下所示(如果有更简洁的方法,请原谅):
final List options List=new ArrayList();
选项列表。添加(“-d what”);
Iterable options=新的Iterable(){
公共迭代器迭代器(){
返回optionsList.iterator();
}
};
然后将选项传递给getTask,但错误消息是“Invalid Flag”。我没有使用Java 6动态编译器工具的经验。但没有人回答:) 编译任务获取一个
FileManager
对象。如果使用标准类,则在源目录树中生成类。您可以做的是为自己的FileManager子类提供一个重写的getFileForOutput
方法。getFileForOutput的API描述表明,这将影响输出(=类)文件的去向
更新
如何连接文件管理器
ForwardingJavaFileManager、ForwardingFileObject和ForwardingJavaFileObject
子类化不可用于重写标准文件管理器的行为,因为它是通过调用编译器上的方法而不是通过调用构造函数创建的。相反,应该使用转发(或委托)。这些类可以轻松地将大多数调用转发到给定的文件管理器或文件对象,同时允许自定义行为。例如,考虑如何将所有调用记录到JavaFiMeMaGras.FrHuSH():
我不知道如何让这段代码处理动态生成的Java文件列表;我可能只需要做
编译器。分别为每个源文件运行。我今天也面临同样的问题
答案(使用常规的getTask
方法而不是“run”)是在FileManager中指定输出目录:
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.lang.IllegalArgumentException: invalid flag: -d folder
这是因为通过传递“-d文件夹”
使解析器认为它在解析一个选项。选项必须分开,如“-d”、“folder”
工作实例如下:
JavaCompiler-JavaCompiler=ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager sjfm=javaCompiler.getStandardFileManager(null,null,null);
字符串[]选项=新字符串[]{“-d”,“输出”};
File[]javaFiles=new File[]{new File(“src/gima/apps/flip/TestClass.java”)};
CompilationTask CompilationTask=javaCompiler.getTask(null,null,null,
Arrays.asList(选项),
无效的
sjfm.getJavaFileObjects(javaFiles)
);
compilationTask.call();
+1让我意识到现在存在动态编译!一直都有,现在它是内置的!这可能是真的,但不幸的是getJavaFileObjects仅在StandardJavaFileManager上。。。。我会看看能做些什么。如果这是Ruby,那么您的答案就足以让您使用monkey patch并完成:)在Java中,方法是子类化ForwardingJavaFileManager
实现了StandardJavaFileManager
,这就是您要使用的。事实上,它有一个构造函数,您可以将从编译器中获得的FileManager包装起来。当然,您希望在派生类中公开该构造函数。谢谢Carl,刚刚尝试过(将fileManager包装在ForwardingJavaFileManager的子类中,然后将其传递给任务)。问题是,从未调用getFileForOutput。但是,ForwardingJavaFileManager没有实现StandardFileManager.Ack,恐怕你是对的。对不起,这是白费力气!我已经有一段时间没有研究这个问题了。那么您是说您的答案实际上解决了整个问题?效果很好-与在getTask()选项参数中使用“-d”相同,但更干净。像“c:\\foo bar\\foo”或“c:/foo bar/foo”这样的路径如何?空格或斜杠可以正确解析吗?我不知道,但我猜不需要转义,因为参数现在被正确传递(并且因为原始问题的本质就是参数没有被单独解析)。试着回去报到?
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());
}
}
}
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.lang.IllegalArgumentException: invalid flag: -d folder