ninia / jep

Embed Python in Java

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Access my own Java classes from Graal JS

Daniel-Alievsky opened this issue · comments

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?

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?

It appears you opened this ticket in the wrong project.

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