我正在使用javax.tools包(JDK 1.7)中的JavaCompiler来动态编译一些东西,如下所示:
compiler.run(null, null, "-cp", paths, "path/to/my/file.java");
Run Code Online (Sandbox Code Playgroud)
它可以工作,但我想在内存中完成所有操作(例如,传递带代码的字符串,而不是源文件,并获取字节代码而不是.class文件).我发现扩展InputStream和OutputStream参数是没有用的,因为它可能与控制台中的相同.你知道一种让run方法像这样工作的方法吗?或者您是否知道使用该getTask()方法确认的方法?(扩展FileManager看起来很简单但不是那么容易:)
我使用类javax.tools.JavaCompiler(jdk6)来编译源文件,但源文件依赖于某些jar文件.如何设置类路径javax.tools.JavaCompiler?
Maven编译器插件文档说明:
Compiler Plugin用于编译项目的源代码.从3.0开始,默认编译器是javax.tools.JavaCompiler(如果您使用的是java 1.6)并且用于编译Java源代码.如果要使用javac强制插件,则必须配置插件选项
forceJavacCompilerUse
事实上,当forceJavacCompilerUse我们的构建中没有指定时,会出现一些构建错误,例如当代码引用com.sun.包时(遗产,我们知道这是一个坏主意......)
这两种编译模式与maven有什么区别?是否应该知道任何产出差异?
我找到了许多参考资料,解释了如何使用JavaCompiler该类以编程方式编译Java 类:
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int result = compiler.run(null, null, null, "a_file_name");
Run Code Online (Sandbox Code Playgroud)
但是,我想知道是否有一个开源库让我编译以编程方式生成的源代码(因此不涉及src文件)并在输出流中生成一些字节代码(不在文件系统中生成类文件) ).
例如,我正在寻找能够写这样的东西:
InputStream input = generateSourceCode();
OutputStream output = getByteCode(input);
doCoolStuffWithByteCode(output);
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助.
当我在android studio中清理android项目时,错误发生了,我已经支持到之前的提交或不同的分支,它可以在几天前查找,但现在有这个错误.我已经检查了这个问题,并没有为我的项目添加大图像或字符串.STRING_TOO_LARGE Kothlin中的字符串
MyClass.java:
package test;
public class MyClass {
public void myMethod(){
System.out.println("My Method Called");
}
}
Run Code Online (Sandbox Code Playgroud)
列出编译MyClass.java文件的SimpleCompileTest.java.
SimpleCompileTest.java:
package test;
import javax.tools.*;
public class SimpleCompileTest {
public static void main(String[] args) {
String fileToCompile = "test" + java.io.File.separator +"MyClass.java";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int compilationResult = compiler.run(null, null, null, fileToCompile);
if(compilationResult == 0){
System.out.println("Compilation is successful");
}else{
System.out.println("Compilation Failed");
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在执行SimpleCompileTest类并获得NullPointerException.ToolProvider.getSystemJavaCompiler()返回null.有人能告诉我代码有什么问题
我不小心写了一个带有两个分号的java语句.java编译器没有显示任何错误,它运行.
码:
System.out.println("Length after delete the text is "+name.length());;
Run Code Online (Sandbox Code Playgroud)
出于学习目的,我尝试在分号后添加不同的字符,并且java编译器已将编译时错误显示为令牌")"上的语法错误,删除此标记.
这个说法:
System.out.println("Length after delete the text is "+name.length());)
Run Code Online (Sandbox Code Playgroud)
为什么java将分号和其他字符视为不同?
我希望在没有机器上存在依赖关系的情况下编译源代码.
示例:文件A.java:
import some.pkg.B;
public class A extends B {...}
Run Code Online (Sandbox Code Playgroud)
我没有B源存在,我希望挂钩JavaFileManager或自定义ClassLoader以获取有问题的符号(包'some.package'和B类)然后使用我有的服务检索源串.
编译代码:(inputFiles有A.java)
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
CustomClassLoader classLoader = new CustomClassLoader();
StandardJavaFileManager standardfileManager = compiler.getStandardFileManager(this, null, null);
JavaFileManager fileManager = new CustomFileManager(standardfileManager, output, classLoader);
CompilationTask task = compiler.getTask(null, fileManager, this, null, null, inputFiles);
boolean result = task.call();
Run Code Online (Sandbox Code Playgroud)
JavaFileManager(getFileForInput ..)和我的类加载器(findClass,loadClass ..)上的钩子在编译时没有触发,我收到错误消息:
A.java:#: package some.pkg does not exist
A.java:#: cannot find symbol
symbol: class B
Run Code Online (Sandbox Code Playgroud)
编辑
在使用API之后,浏览JavaCompiler(旧版本)源代码并阅读编译概述我仍然找不到可以用来向语法树提供符号的API钩子.似乎API需要根据kschneid建议的包名获取所有资源.
我想到的一个解决方法是运行JavaCompiler并分析缺失符号的错误消息.这样我就会知道需要哪些符号,获取它们并重新编译.
还有其他解决方法/解决方案吗?
假设一个类定义了一个常量字段:
public class Foo {
public static final int CONSTANT_FIELD = 3;
}
Run Code Online (Sandbox Code Playgroud)
并假设注释接口声明如下:
public @interface Something {
int value();
}
Run Code Online (Sandbox Code Playgroud)
最后,假设注释使用如下:
@Something(Foo.CONSTANT_FIELD)
Run Code Online (Sandbox Code Playgroud)
问题:在注释处理器中,如何CONSTANT_FIELD从设置值中获取元素@Something?
编辑:在问题本身中包含一个具体的例子.
我有一个像这样使用的注释:
@RuleDependency(recognizer = BQLParser.class,
rule = BQLParser.RULE_statement,
version = 0)
Run Code Online (Sandbox Code Playgroud)
注释处理器需要知道这RULE_statement是在BQLParser类中定义的常量.如果我可以直接从设置注释的属性访问Elementfor ,它将消除对属性的需要.这个注解用来数千次实际应用中,并且是永远只是的声明类型不变.解决这个问题会简化注释用法:BQLParser.RULE_statementrulerecognizerrecognizerrule
@RuleDependency(rule = BQLParser.RULE_statement, version = 0)
Run Code Online (Sandbox Code Playgroud) 我的应用程序在运行时生成Java代码,并使用JavaCompiler API对其进行编译.一些生成的文件可能相当大 - 高达几十万行.我发现当我在javac命令行中对生成的代码运行命令时,或者如果我使用通过JavaCompiler API进行编译的应用程序时,我可以编译许多这些文件(~500),即使它们是非常大,不到两分钟.但是,如果我在Tomcat服务器上运行时通过我的应用程序调用API,则编译时间会超过12分钟(!!!).
我将不胜感激任何有关如何提高编译性能的建议.
谢谢!
java ×10
javac ×3
android ×1
annotations ×1
classloader ×1
compilation ×1
javacompiler ×1
jdk1.6 ×1
jsr199 ×1
jvm ×1
maven ×1
tomcat ×1