标签: java-compiler-api

使用源代码操作进行Java注释处理

我一直在寻找以下要求的解决方案 -

  • 源文件使用自定义注释在方法上编写
  • 方法体需要基于注释的一点变化.
  • 源文件不应更改,但输入到编译器应修改源文件

我看了下面的API -

  • javax.annotation.processing - 注释处理.
  • javax.lang.model.* - 注释处理和编译器树API中使用的语言模型
  • com.sun.source.* - 编译器树API.

我想通过以下方式设计:

  1. 编写注释处理器
  2. 生成编译器树
  3. 在运行时编辑编译器树而不影响原始源文件
  4. 将树提供给编译器

编译器树API似乎在允许访问com.sun.source.tree.MethodTree的位置

但是,编译器树API似乎是只读的.我无法弄清楚如何完成步骤3和4

是否有任何API可用于完成任务

注意:我正在寻找唯一的源代码操作技术.没有运行时字节代码操作/ AOP

环境:Java 6

java apt annotations java-compiler-api

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

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

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

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

谢谢!

java tomcat javac java-compiler-api javacompiler

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

注释处理器 - 如何获取正在处理的类

我正在尝试编写一个自定义的Anntoation处理器.注释处理器将在编译时处理每个类文件以检查注释,但是我如何才能获得它当前正在处理的类?我只能在以下代码中获取类名.

public class AnnotationProcessor extends AbstractProcessor {
  ......
    @Override
     public boolean process(Set<? extends TypeElement> annotations,
        RoundEnvironment roundEnv) {

     Set<? extends Element> rootE=roundEnv.getRootElements();
       for(Element e: rootE) {
        if(e.getKind()==ElementKind.CLASS) {
            String className= e.getSimpleName().toString();
            processingEnv.getMessager().printMessage( javax.tools.Diagnostic.Kind.WARNING,className, e); 
        }
     }
}
Run Code Online (Sandbox Code Playgroud)

java annotations annotation-processing java-compiler-api

8
推荐指数
2
解决办法
8259
查看次数

javax.tools是否依赖于JDK?

我想用来JavaCompiler动态创建一些类.

我找到了javax.tools包的源代码,但是没有实现; 互联网上的一些帖子说它依赖于tools.jar,我不确定是否tools.jar与JRE有关.

那么,我可以在没有安装JDK的JRE环境中运行程序吗?

另一个问题,即实现细节JavaCompiler是什么,是创建一个新的进程来调用javac命令?

谢谢

java jsr199 java-compiler-api

7
推荐指数
1
解决办法
2084
查看次数

如何在 Java 9 的类路径中获取 jar 文件和文件夹的列表?

我知道你不能改变Java 9 中的类路径,因为我读到了这个:Add jar to classpath at runtime under java 9

我只想列出当前在类路径上的 jar 文件和文件夹,以便我可以为 Java 编译器构建命令行参数。

// Construct compile command options
// According to: http://java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/javac.html
// The directory specified by -d is not automatically added to your
// classpath, so we'll add it manually.
String[] args = new String[] {"-d", classDir,
                              "-classpath", classPath,
                              "-encoding", "UTF-8",
                              srcFile};

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int ret = compiler.run(null, out, err, args);
Run Code Online (Sandbox Code Playgroud)

为了在 Java 8 中构建类路径,我将其强制转换为 URLClassLoader,这在 Java 9 中是非法的: …

java classpath java-compiler-api java-9

7
推荐指数
1
解决办法
2429
查看次数

如何将JDK6 ToolProvider和JavaCompiler与上下文类加载器一起使用?

我的用例是使用JDK 6中提供的ToolProvider和JavaCompiler类从java程序编译生成的源文件.源文件包含对上下文类加载器中的类的引用(它在J2EE容器中运行),但不包含在系统类加载器中.我的理解是,默认情况下,ToolProvider将使用系统类加载器创建JavaCompiler实例.

有没有办法为JavaCompiler指定一个类加载器?

我尝试了这种方法,从IBM DeveloperWorks上的某些东西进行了修改:

FileManagerImpl fm = 
    new FileManagerImpl(compiler.getStandardFileManager(null, null, null););
Run Code Online (Sandbox Code Playgroud)

将FileManagerImpl定义为:

static final class FileManagerImpl 
    extends ForwardingJavaFileManager<JavaFileManager> {

   public FileManagerImpl(JavaFileManager fileManager) {
      super(fileManager);
   }

   @Override
   public ClassLoader getClassLoader(JavaFileManager.Location location) {
      new Exception().printStackTrace();
      return Thread.currentThread().getContextClassLoader();
   }

}
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪表明它仅在注释处理期间调用一次.我验证了要编译的源文件中引用的类不在系统类路径中,但可以从上下文类加载器中获得.

java javac classloader java-compiler-api

6
推荐指数
2
解决办法
6288
查看次数

使用JavaCompiler和ClassLoader编译和运行用户代码

我正在为java学习编写web应用程序.使用哪些用户可以在我的服务器上编译他们的代码+运行该代码.使用JavaCompiler进行编译很容易:

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
    CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, prepareFile(nazwa, content));

    task.call();

    List<String> returnErrors = new ArrayList<String>();
    String tmp = new String();
    for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
        tmp = String.valueOf(diagnostic.getLineNumber());
        tmp += " msg: " + diagnostic.getMessage(null);
        returnErrors.add(tmp.replaceAll("\n", " "));
    }
Run Code Online (Sandbox Code Playgroud)

我设法用代码加载类:

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);

    try {
        URL[] urls = {new URL("file:///root/"), new URL("file://C:\\serv\\Apache Tomcat 6.0.20\\bin\\")};
        ClassLoader cl_old = Thread.currentThread().getContextClassLoader();
        ClassLoader cl_new = …
Run Code Online (Sandbox Code Playgroud)

java classloader java-compiler-api

6
推荐指数
1
解决办法
2860
查看次数

Java动态代码生成,支持泛型

是否有任何工具可以提供Java动态代码生成并且还支持泛型?

例如,Javassist是我需要的工具,但它不支持泛型.

我写了一个使用Java 6 Compiler API的小型lib,但据我所知它依赖于JDK.有没有办法指定另一个编译器?或者只向我的应用程序提供我需要使用Java Compiler API调用的部分?

java java-api dynamic-code java-compiler-api

6
推荐指数
1
解决办法
2440
查看次数

使用Java Compiler API编译多个java文件

嗨,我要求创建,编译和加载java类运行时.使用FTL我正在创建java源文件,并且如果没有动态依赖,则能够编译源代码.

为了详细说明一个实例,我有两个java源文件,一个接口及其实现类.我能够使用java编译器api编译接口,如下所示

String classpath=System.getProperty("java.class.path");
        String testpath =classpath+";"+rootPath+"/lib/is_wls_client.jar;"+rootPath+"/rtds_wls_proxyclient.jar;.;";
        File javaFile =  new File(javaFileName+".java");
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        List<String> optionList = new ArrayList<String>();
        optionList.addAll(Arrays.asList("-classpath",testpath));
        StandardJavaFileManager sjfm = compiler.getStandardFileManager(null, null, null);
        Iterable fileObjects = sjfm.getJavaFileObjects(javaFile);
        JavaCompiler.CompilationTask task = compiler.getTask(null, null, null,optionList,null,fileObjects);
        task.call();
        sjfm.close();
Run Code Online (Sandbox Code Playgroud)

我为已经在类路径中的静态类设置类路径,但这种方法不适用于动态创建的类?任何自定义类加载器都会修复?我的最终实现将在web/app服务器中

任何反馈都将受到高度赞赏

Satheesh

dynamic-class-loaders java-compiler-api

6
推荐指数
1
解决办法
4541
查看次数

如何以编程方式使用JDT编译器?

我使用JDT来编译我的java类.BatchCompiler返回一个字符串,但我需要一系列问题/错误及其列和行信息.compiler.compile(单位); 将错误打印到其printwriter,compiler.resolve(unit)正是我想要的,但它只能编译一个java文件.

我用这种方式创建了一个编译器对象:

Compiler compiler = new Compiler(env, DefaultErrorHandlingPolicies.exitAfterAllProblems(), new CompilerOptions(), requestor, new DefaultProblemFactory());
Run Code Online (Sandbox Code Playgroud)

并创建包含文件名和文件内容的CompilationUnits到编译器.

CompilationUnit[] units = project.toCompilationUnit();
Run Code Online (Sandbox Code Playgroud)

AFAIK,有两种编译方式,其中一种是返回void并将错误和问题打印到其PrintWriter的编译(单位)方法,因为它不返回对我没用的列信息.另一种方法是resolve(unit)方法,但它只能使用一个CompilationUnit.

compiler.resolve(units[index], true, true, true);
Run Code Online (Sandbox Code Playgroud)

有谁知道如何以编程方式使用JDT编译器来编译多个文件?

eclipse eclipse-plugin eclipse-jdt java-compiler-api

6
推荐指数
1
解决办法
1683
查看次数