6

Hi I have requirement to create ,compile and load java classes run time. Using FTL i am creating java source files , and able to compile the source if there is no dynamic dependency.

To elaborate with an instance, I have two java source file, one interface and its implementation class. I am able to compile the interface using java compiler api as follows

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();

I set class path for static classes which are already in the classpath , but this approach do not work for dynamically created classes? Any custom class loader will do the fix? My final implementation will be in web/app server

Any feedback will be highly appreciated

Satheesh

1 Answer 1

6

I was able to solve this issue by compiling all the java files together. Using FTL I generate the java classes, and then compile it using java compiler api and load classes with custom class loader

Java Complier

private  void compile(File[] files) throws IOException{
        String classpath=System.getProperty("java.class.path");
        String rootPath=getServletContext().getRealPath("/");
        System.out.println("--> root Path "+rootPath);
        String testpath=classpath+";.;xx.jar;yy.jar";
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        List<String> optionList = new ArrayList<String>();
        optionList.addAll(Arrays.asList("-classpath",testpath));
//      optionList.addAll(Arrays.asList("-d",rootPath+"/target"));
        StandardJavaFileManager sjfm = compiler.getStandardFileManager(null, null, null);
        Iterable fileObjects = sjfm.getJavaFileObjects(files);
        JavaCompiler.CompilationTask task = compiler.getTask(null, null, null,optionList,null,fileObjects);
        task.call();
        sjfm.close();

    }

Below code snippet shows how to use custom class loader

class CustomClassLoader extends ClassLoader {

     public CustomClassLoader(ClassLoader parent) {
            super(parent);
     }

    public Class findClass(String className,String path) {
        byte[] classData = null;
        try {
            FileInputStream f = new FileInputStream(path);
            int num = f.available();
            classData = new byte[num];

            f.read(classData);
        } catch (IOException e) {
            System.out.println(e);
        }
        Class x = defineClass(className, classData, 0, classData.length);
        return x;
    }
}

thanks Satheesh

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.