我一直在寻找以下要求的解决方案 -
我看了下面的API -
我想通过以下方式设计:
编译器树API似乎在允许访问com.sun.source.tree.MethodTree的位置
但是,编译器树API似乎是只读的.我无法弄清楚如何完成步骤3和4
是否有任何API可用于完成任务
注意:我正在寻找唯一的源代码操作技术.没有运行时字节代码操作/ AOP
环境:Java 6
我的应用程序在运行时生成Java代码,并使用JavaCompiler API对其进行编译.一些生成的文件可能相当大 - 高达几十万行.我发现当我在javac命令行中对生成的代码运行命令时,或者如果我使用通过JavaCompiler API进行编译的应用程序时,我可以编译许多这些文件(~500),即使它们是非常大,不到两分钟.但是,如果我在Tomcat服务器上运行时通过我的应用程序调用API,则编译时间会超过12分钟(!!!).
我将不胜感激任何有关如何提高编译性能的建议.
谢谢!
我正在尝试编写一个自定义的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) 我想用来JavaCompiler动态创建一些类.
我找到了javax.tools包的源代码,但是没有实现; 互联网上的一些帖子说它依赖于tools.jar,我不确定是否tools.jar与JRE有关.
那么,我可以在没有安装JDK的JRE环境中运行程序吗?
另一个问题,即实现细节JavaCompiler是什么,是创建一个新的进程来调用javac命令?
谢谢
我知道你不能改变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 中是非法的: …
我的用例是使用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学习编写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动态代码生成并且还支持泛型?
例如,Javassist是我需要的工具,但它不支持泛型.
我写了一个使用Java 6 Compiler API的小型lib,但据我所知它依赖于JDK.有没有办法指定另一个编译器?或者只向我的应用程序提供我需要使用Java Compiler API调用的部分?
嗨,我要求创建,编译和加载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
我使用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编译器来编译多个文件?
java ×8
annotations ×2
classloader ×2
javac ×2
apt ×1
classpath ×1
dynamic-code ×1
eclipse ×1
eclipse-jdt ×1
java-9 ×1
java-api ×1
javacompiler ×1
jsr199 ×1
tomcat ×1