标签: java-compiler-api

使用javax.tools.JavaCompiler在内存中完全编译代码

我正在使用javax.tools包(JDK 1.7)中的JavaCompiler来动态编译一些东西,如下所示:

compiler.run(null, null, "-cp", paths, "path/to/my/file.java");
Run Code Online (Sandbox Code Playgroud)

它可以工作,但我想在内存中完成所有操作(例如,传递带代码的字符串,而不是源文件,并获取字节代码而不是.class文件).我发现扩展InputStreamOutputStream参数是没有用的,因为它可能与控制台中的相同.你知道一种让run方法像这样工作的方法吗?或者您是否知道使用该getTask()方法确认的方法?(扩展FileManager看起来很简单但不是那么容易:)

java compilation javac java-compiler-api

42
推荐指数
4
解决办法
3万
查看次数

当我使用javax.tools.JavaCompiler编译源代码时如何设置classpath?

我使用类javax.tools.JavaCompiler(jdk6)来编译源文件,但源文件依赖于某些jar文件.如何设置类路径javax.tools.JavaCompiler

java jdk1.6 jsr199 java-compiler-api

39
推荐指数
2
解决办法
2万
查看次数

使用javac和javax.tools.JavaCompiler有什么区别?

Maven编译器插件文档说明:

Compiler Plugin用于编译项目的源代码.从3.0开始,默认编译器是javax.tools.JavaCompiler(如果您使用的是java 1.6)并且用于编译Java源代码.如果要使用javac强制插件,则必须配置插件选项forceJavacCompilerUse

事实上,当forceJavacCompilerUse我们的构建中没有指定时,会出现一些构建错误,例如当代码引用com.sun.包时(遗产,我们知道这是一个坏主意......)

这两种编译模式与maven有什么区别?是否应该知道任何产出差异?

java jvm javac maven java-compiler-api

34
推荐指数
1
解决办法
4682
查看次数

是否有可能以编程方式仅在内存中编译java源代码?

我找到了许多参考资料,解释了如何使用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)

谢谢你的帮助.

java code-generation java-compiler-api

28
推荐指数
2
解决办法
1万
查看次数

android studio with Java compiler error:字符串太大,无法使用UTF-8编写而不是'STRING_TOO_LARGE'

当我在android studio中清理android项目时,错误发生了,我已经支持到之前的提交或不同的分支,它可以在几天前查找,但现在有这个错误.我已经检查了这个问题,并没有为我的项目添加大图像或字符串.STRING_TOO_LARGE Kothlin中的字符串

java android java-compiler-api android-studio

21
推荐指数
10
解决办法
3万
查看次数

使用Java Compiler API时出现空指针异常

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 nullpointerexception java-compiler-api

11
推荐指数
2
解决办法
1万
查看次数

为什么Java在语句结尾处不显示双分号错误?

我不小心写了一个带有两个分号的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将分号和其他字符视为不同?

java java-compiler-api

11
推荐指数
3
解决办法
9174
查看次数

JavaCompiler具有自定义ClassLoader和FileManager

我希望在没有机器上存在依赖关系的情况下编译源代码.
示例:文件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并分析缺失符号的错误消息.这样我就会知道需要哪些符号,获取它们并重新编译.
还有其他解决方法/解决方案吗?

java classloader java-compiler-api

10
推荐指数
1
解决办法
2325
查看次数

访问注释处理器中的常量字段

假设一个类定义了一个常量字段:

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 annotations annotation-processing java-compiler-api

9
推荐指数
1
解决办法
1010
查看次数

JavaCompiler API - 在tomcat中运行时编译速度慢

我的应用程序在运行时生成Java代码,并使用JavaCompiler API对其进行编译.一些生成的文件可能相当大 - 高达几十万行.我发现当我在javac命令行中对生成的代码运行命令时,或者如果我使用通过JavaCompiler API进行编译的应用程序时,我可以编译许多这些文件(~500),即使它们是非常大,不到两分钟.但是,如果我在Tomcat服务器上运行时通过我的应用程序调用API,则编译时间会超过12分钟(!!!).

我将不胜感激任何有关如何提高编译性能的建议.

谢谢!

java tomcat javac java-compiler-api javacompiler

9
推荐指数
1
解决办法
201
查看次数