0

I am building an AWS Lambda function which compiles a class on the fly. But the lambda function throws the error as it is not able to locate the dependencies i.e the import statements for the class compiled on the fly. I've given sample code for the steps being followed.

Kindly guide on how I can locate the dependencies i.e set class path so that the class created on the fly compiles without any errors

  1. 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();
    }
    
  2. 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");
    
  3. 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
    }
    
  4. Error while executing the lambda function

    /tmp/TestJavaFile.java:1: error: package org.json.simple does not exist
    

File to be compiled is saved in the /tmp directory. I am unable to determine the path where the dependency jar files are present and how to set it in classpath. Kindly guide on this.

Many Thanks!

1 Answers1

0

This was resolved by setting the classpath as

    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");
       }