微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用javax.tools.JavaCompiler编译循环依赖类

我一直在尝试使用 java在String中编译一些 Java类.
我使用javax.tools.JavaCompiler来编译字符串中的类.

我用SimpleJavaFileObject制作的Subclass创建了SimpleJavaFileObject的实例.

import javax.tools.SimpleJavaFileObject;
import java.net.URI;

public class JavaSourceFromString extends SimpleJavaFileObject {
     final String code;

    public JavaSourceFromString(String name,String code) {
        super( URI.create("string:///" + name.replace('.','/') + Kind.soURCE.extension),Kind.soURCE);
        this.code = code;
    }

    @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
        return code;
    }
}

我已经创建了这个类的实例,将它添加到ArrayList,然后得到了

ToolProvider.SystemJavaCompiler();

添加了编译选项.然后编译

Iterable<? extends JavaFileObject> fileObjects = jsfsList;

JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
if (jc == null) throw new Exception("Compiler unavailable");

List<String> options = new ArrayList<>();
options.add("-d");
options.add(Config.getProperty("DESTINATION_PATH"));
options.add("-classpath");

urlclassloader urlclassloader = (urlclassloader)Thread.currentThread().getContextClassLoader();
StringBuilder sb = new StringBuilder();
for (URL url : urlclassloader.getURLs()) {
    sb.append(url.getFile()).append(File.pathSeparator);
}
sb.append(PiranhaConfig.getProperty("DESTINATION_PATH"));
options.add(sb.toString());

StringWriter output = new StringWriter();
boolean success = jc.getTask(output,null,options,fileObjects).call();
if (success) {
    LOG.info("Class [" + compiledClasses + "] has been successfully compiled");
} else {
    throw new Exception("Compilation Failed :" + output);
}

我用3个具有循环依赖性的类测试了这个.它给出了错误,它无法找到引用的符号.似乎与javac不同,这个编译器单独查看列表中的每个项目并尝试单独编译每个项目.

如何使用这个编译器实现与Javac相同的结果?
有人请指出我正确的方向:)
谢谢.

解决方法

以下代码为我成功运行(与OP的代码几乎相同,只是用合理的替代品替换未定义的符号):

import java.io.File;
import java.io.StringWriter;
import java.net.URL;
import java.net.urlclassloader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;

class CircularDeps {
  public static void main(String[] args) throws Exception {
    Iterable<? extends JavaFileObject> fileObjects = Arrays.asList(
        new JavaSourceFromString(
            "A","package packageA; public class A { packageB.B b; }"),new JavaSourceFromString(
            "B","package packageB; public class B { packageC.C c; }"),new JavaSourceFromString(
            "C","package packageC; public class C { packageA.A a; }")
        );

    JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
    if (jc == null) throw new Exception("Compiler unavailable");

    List<String> options = new ArrayList<>();
    options.add("-d");
    options.add(args[0]);
    options.add("-classpath");

    urlclassloader urlclassloader = (urlclassloader)Thread.currentThread().getContextClassLoader();
    StringBuilder sb = new StringBuilder();
    for (URL url : urlclassloader.getURLs()) {
          sb.append(url.getFile()).append(File.pathSeparator);
    }
    sb.append("output");
    options.add(sb.toString());

    StringWriter output = new StringWriter();
    boolean success = jc.getTask(output,fileObjects).call();
    if (success) {
          System.out.println("Classes has been successfully compiled");
    } else {
          throw new Exception("Compilation Failed :" + output);
    }
  }
}

输出

Classes has been successfully compiled

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐