Skip to content
Muhammad Hammad edited this page May 18, 2020 · 5 revisions

Dynamic Loader

Dynamic Loader is In Memory Java Compiler and classpath loader which enables compile both java file and code string in memory and also provides support to load supportive jars in classpath which need to compile the dynamic code.

JAVA module support

Version 3.0

The dynamic compiler needs java module libraries which can be export with javac params. java.base/java.langis by default exposed. for more detail see java.base packages.

   DynamicCompiler dynamicCompiler = new DynamicCompiler();
   dynamicCompiler.addOption("--add-exports", "java.base/java.net=ALL-UNNAMED"); // java.base package
   dynamicCompiler.addOption("--add-exports", "java.sql/java.sql=ALL-UNNAMED");  // java.sql package 

Version 3.1

In version 3.1 java.base/java.util and java.base/java.io are also exported by default.

Example

String source
public class SourceTest {

    @Test
    public void sourceCodeTest() throws Exception {
        
        String sourceCode = "package org.dvare.dynamic;" +
                "public class SourceClass {" +
                "   public String hello() { return \"Hello, World\"; }" +
                "}";

        DynamicCompiler dynamicCompiler = new DynamicCompiler();
        dynamicCompiler.addSource("org.dvare.dynamic.SourceTestClass", sourceCode);
        Map<String, Class<?>> compiled = dynamicCompiler.build();
        Class<?> aClass = compiled.get("org.dvare.dynamic.SourceTestClass");
        Assert.assertNotNull(aClass);
        Assert.assertEquals(1, aClass.getDeclaredMethods().length);
        }
    }
Java file source
public class JavaFileTest {

    @Test
    public void javaFileTest() throws Exception {

        DynamicCompiler dynamicCompiler = new DynamicCompiler();
        URL url = getClass().getClassLoader().getResource("JavaFile.java");
        Assert.assertNotNull(url);
        dynamicCompiler.addSource(new File(url.getPath()));

        Map<String, Class<?>> compiled = dynamicCompiler.build();
        Class<?> aClass = compiled.get("org.dvare.dynamic.JavaFile");
        Assert.assertNotNull(aClass);
        Assert.assertEquals(1, aClass.getDeclaredMethods().length);

    }
}
Java Module
public class SourceTest {

    @Test
    public void localDate_test() throws Exception {

        String sourceCode = "package org.dvare.dynamic;" +
                "import java.time.LocalDate;" +
                "public class DateUtil {" +
                "   public static String getTestDate() { return LocalDate.of(2020,5,15).toString(); }" +
                "}";

        DynamicCompiler dynamicCompiler = new DynamicCompiler();

        try {
            Class.forName("com.sun.tools.sjavac.Module"); //if java module present
            dynamicCompiler.addOption("--add-exports", "java.base/java.time=ALL-UNNAMED");
        } catch (Exception ignored) {}

        dynamicCompiler.addSource("org.dvare.dynamic.DateUtil", sourceCode);
        Map<String, Class<?>> compiled = dynamicCompiler.build();
        Class<?> dateUtilClass = compiled.get("org.dvare.dynamic.DateUtil");
        Assert.assertNotNull(dateUtilClass);
        Assert.assertEquals(1, dateUtilClass.getDeclaredMethods().length);

        Object dateUtil = dateUtilClass.newInstance();
        Object result = dateUtilClass.getMethod("getTestDate").invoke(dateUtil);
        Assert.assertEquals("2020-05-15", result);
    }
Clone this wiki locally