JavaCompiler called from JPMS module

Alex Sviridov ooo_saturn7 at mail.ru
Sat May 16 16:53:16 UTC 2020


Hi all,
 
I am working with H2 java database that allows to create triggers from java source code.
To compile the trigger the following code is used:
 
    JavaCompiler JAVA_COMPILER = ToolProvider.getSystemJavaCompiler();
    String fullClassName = packageName + "." + className;
    StringWriter writer = new StringWriter();
    try (JavaFileManager fileManager = new
            ClassFileManager(JAVA_COMPILER
                .getStandardFileManager(null, null, null))) {
        ArrayList<JavaFileObject> compilationUnits = new ArrayList<>();
        compilationUnits.add(new StringJavaFileObject(fullClassName, source));
        // cannot concurrently compile
        final boolean ok;
        synchronized (JAVA_COMPILER) {
            ok = JAVA_COMPILER.getTask(writer, fileManager, null, null,
                    null, compilationUnits).call();
        }
        String output = writer.toString();
        handleSyntaxError(output, (ok? 0: 1));
        return fileManager.getClassLoader(null).loadClass(fullClassName);
    } catch (ClassNotFoundException | IOException e) {
        throw DbException.convert(e);
    }
 
Trigger `fullClassName` = `org.h2.dynamic.trigger.SOME_TRIGGER`.

And the trigger `source` =
    package org.h2.dynamic.trigger;
    import java.util.*;
    import java.math.*;
    import java.sql.*;
    public class SOME_TRIGGER {
        public static org.h2.api.Trigger create() {
    
        return new org.h2.api.Trigger() {
            
            @Override
            public void init(Connection conn, String schemaName, String triggerName,
                    String tableName, boolean before, int type) throws SQLException { }
            
            @Override
            public void fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException { }
    
            @Override
            public void close() throws SQLException { }
    
            @Override
            public void remove() throws SQLException { }
    
        };
    }
    }
 
 
When H2 is on classpath I don't have any problems - trigger is compiled. However, when H2 is on
module path (H2 has in manifest Automatic-Module-Name: com.h2database) on some of child layers
(not boot layer) I get the following `output`:
 
    /org/h2/dynamic/trigger/SOME_TRIGGER.java:6: error: package org.h2.api does not exist
        public static org.h2.api.Trigger create() {
                                ^
    1 error
 
As I understand the problem is with classloader and JavaCompiler. Could anyone say how it can be fixed?
 
Best regards, Alex


More information about the jigsaw-dev mailing list