aws lambda java:如何在动态编译时设置 class 路径
aws lambda java : How to set the class path while compiling on the fly
我正在构建一个 AWS Lambda 函数,它可以即时编译 class。但是 lambda 函数会抛出错误,因为它无法定位依赖项,即动态编译的 class 的导入语句。我已经给出了所遵循步骤的示例代码。
请指导我如何找到依赖项,即设置 class 路径,以便动态创建的 class 编译时没有任何错误
Sample Code being compiled
private String constructTestCode(String methodCode) throws Exception{
StringBuffer strMethod = new StringBuffer();
strMethod.append("import org.json.simple.JSONObject;");
strMethod.append("public class TestJavaFile {");
strMethod.append("public void testSample() {");
strMethod.append("JSONObject j = new JSONObject();");
strMethod.append("}");
strMethod.append("}");
return strMethod.toString();
}
JavaCompilerCode
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
List<String> optionList = new ArrayList<String>();
optionList.addAll(Arrays.asList("-
classpath",System.getProperty("java.class.path")));
if (compiler == null) {
try {
Class<?> javacTool =
Class.forName("com.sun.tools.javac.api.JavacTool");
Method create = javacTool.getMethod("create");
compiler = (JavaCompiler) create.invoke(null);
compiler.getTask(null, null, null, optionList, null, null);
} catch (Exception e) {
throw new AssertionError(e);
}
}
try {
compiler.run(null, null, null,
javaFile.toFile().getAbsolutePath());
} catch (Exception e) {
context.getLogger().log("Exception " + e + "\n");
}
return javaFile.getParent().resolve(fileName + ".class");
Gradle one fat jar
task customFatJar(type: Jar) {
manifest {
attributes
'Class-Path': configurations.runtime.files.collect { it.name }.join('
')
}
baseName = 'all-in-one-jar'
from { configurations.compile.collect { it.isDirectory() ? it :
zipTree(it)
} }
with jar
}
Error while executing the lambda function
/tmp/TestJavaFile.java:1: error: package org.json.simple does not exist
编译文件保存在/tmp目录下。我无法确定依赖 jar 文件所在的路径以及如何在 classpath 中设置它。请指导这一点。
非常感谢!
通过将类路径设置为
解决了这个问题
try {
StandardJavaFileManager standardJavaFileManager =
compiler.getStandardFileManager(null, null, null);
standardJavaFileManager.setLocation(StandardLocation.CLASS_PATH,
listFilePaths(folder, context));
File[] javaFiles = new File[] { javaFile.toFile(),
Paths.get("/tmp/JUnitTest.java").toFile() };
Iterable<? extends JavaFileObject> compilationUnits1 =
standardJavaFileManager
.getJavaFileObjectsFromFiles(Arrays.asList(javaFiles));
CompilationTask task = compiler.getTask(null, standardJavaFileManager, null,
optionList, null,
compilationUnits1);
task.call();
} catch (Exception e) {
context.getLogger().log("Exception " + e + "\n");
}
我正在构建一个 AWS Lambda 函数,它可以即时编译 class。但是 lambda 函数会抛出错误,因为它无法定位依赖项,即动态编译的 class 的导入语句。我已经给出了所遵循步骤的示例代码。
请指导我如何找到依赖项,即设置 class 路径,以便动态创建的 class 编译时没有任何错误
Sample Code being compiled
private String constructTestCode(String methodCode) throws Exception{ StringBuffer strMethod = new StringBuffer(); strMethod.append("import org.json.simple.JSONObject;"); strMethod.append("public class TestJavaFile {"); strMethod.append("public void testSample() {"); strMethod.append("JSONObject j = new JSONObject();"); strMethod.append("}"); strMethod.append("}"); return strMethod.toString(); }
JavaCompilerCode
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); List<String> optionList = new ArrayList<String>(); optionList.addAll(Arrays.asList("- classpath",System.getProperty("java.class.path"))); if (compiler == null) { try { Class<?> javacTool = Class.forName("com.sun.tools.javac.api.JavacTool"); Method create = javacTool.getMethod("create"); compiler = (JavaCompiler) create.invoke(null); compiler.getTask(null, null, null, optionList, null, null); } catch (Exception e) { throw new AssertionError(e); } } try { compiler.run(null, null, null, javaFile.toFile().getAbsolutePath()); } catch (Exception e) { context.getLogger().log("Exception " + e + "\n"); } return javaFile.getParent().resolve(fileName + ".class");
Gradle one fat jar
task customFatJar(type: Jar) { manifest { attributes 'Class-Path': configurations.runtime.files.collect { it.name }.join(' ') } baseName = 'all-in-one-jar' from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } with jar }
Error while executing the lambda function
/tmp/TestJavaFile.java:1: error: package org.json.simple does not exist
编译文件保存在/tmp目录下。我无法确定依赖 jar 文件所在的路径以及如何在 classpath 中设置它。请指导这一点。
非常感谢!
通过将类路径设置为
解决了这个问题 try {
StandardJavaFileManager standardJavaFileManager =
compiler.getStandardFileManager(null, null, null);
standardJavaFileManager.setLocation(StandardLocation.CLASS_PATH,
listFilePaths(folder, context));
File[] javaFiles = new File[] { javaFile.toFile(),
Paths.get("/tmp/JUnitTest.java").toFile() };
Iterable<? extends JavaFileObject> compilationUnits1 =
standardJavaFileManager
.getJavaFileObjectsFromFiles(Arrays.asList(javaFiles));
CompilationTask task = compiler.getTask(null, standardJavaFileManager, null,
optionList, null,
compilationUnits1);
task.call();
} catch (Exception e) {
context.getLogger().log("Exception " + e + "\n");
}