ninia / jep

Embed Python in Java
Other
1.3k stars 147 forks source link

Access my own Java classes from Graal JS #424

Closed Daniel-Alievsky closed 1 year ago

Daniel-Alievsky commented 1 year ago

I have very simple test:

package net.algart.bridges.graalvm.tests;
import org.graalvm.polyglot.Context;
public class GraalVMFullAccessToJava {
    public void test() {
        System.out.println("test");
    }

    public static void testStatic() {
        System.out.println("testStatic");
    }

    public static void main(String[] args) {
        Context context = Context.newBuilder("js")
                .allowAllAccess(true)
                .build();

        context.eval("js","java.lang.System.out.println('Hello')");
        context.getBindings("js").putMember("test", new GraalVMFullAccessToJava());
        context.eval("js","test.test()");
        context.eval("js","Java.type('net.algart.bridges.graalvm.tests.GraalVMFullAccessToJava').testStatic()");
        context.eval("js","net.algart.bridges.graalvm.tests.GraalVMFullAccessToJava.testStatic()");
    }
}

GraalVM after allowAllAccess, really, allows to access to any standard Java classes and also to an instance of my class, added to bindings. Also it works via Java.type(). But the last line does not work! Results:

Hello test testStatic Exception in thread "main" ReferenceError: net is not defined at :program(Unnamed:1:0-2) at org.graalvm.polyglot.Context.eval(Context.java:425) at net.algart.bridges.graalvm.tests.GraalVMFullAccessToJava.main(GraalVMFullAccessToJava.java:47)

What is the reason? What is the difference between standard "java.lang.System" class and my own class?

Daniel-Alievsky commented 1 year ago

Moreover, I notices other problem. While I call context.eval("js","Java.type('net.algart.bridges.graalvm.tests.GraalVMFullAccessToJava').testStatic()"); (or access to any other my class by Java.type) from IntelliJ IDEA, it works normally. However, when I try to use the similar code from our external program, which initializes JavaVM from C++ (JNI), it does not work!

org.graalvm.polyglot.PolyglotException: TypeError: Access to host class .... is not allowed or does not exist.

The main difference is that Thread.currentThread().getContextClassLoader() is null in this case. However, an attempt to set it manually does not help:

    static {
        correctClassLoader(Thread.currentThread());
    }
    static void correctClassLoader(Thread thread) {
        ClassLoader contextClassLoader = thread.getContextClassLoader();
        if (contextClassLoader == null) {
            thread.setContextClassLoader(GraalClassLoaderCorrection.class.getClassLoader());
            // - attempt to avoid a problem: GraalVM uses getContextClassLoader, but
            // it can be null while calling from JNI
        }
    }

Do you have any ideas?

ndjensen commented 1 year ago

It appears you opened this ticket in the wrong project.

Daniel-Alievsky commented 1 year ago

You are absolutely right, sorry... It is another project, Graal. Could you remove this wrong issue, please?