简体   繁体   English

Javafx WebView无法访问带有修饰符“ public”的类的成员。

[英]Javafx WebView can not access a member of class … with modifiers “public”

In a project I am working on, I need to define an abstract class with some methods implemented in packageone. 在我正在从事的项目中,我需要定义一些抽象类,并在packageone中实现一些方法。 In packagetwo the remainder of the abstract methods will be implemented when the class is instantiated. 在packagetwo中,将在实例化该类时实现其余的抽象方法。 The instance is then exposed to Javascript code in a JavaFX webview. 然后,该实例在JavaFX Web视图中公开给Javascript代码。 (An online example from Oracle - https://blogs.oracle.com/javafx/entry/communicating_between_javascript_and_javafx ) (来自Oracle的在线示例-https: //blogs.oracle.com/javafx/entry/communicating_between_javascript_and_javafx

My problem is, the methods implemented in packagetwo are not callable from the Javascript environment. 我的问题是,在packagetwo中实现的方法无法从Javascript环境中调用。 I get the following error: 我收到以下错误:

Exception in thread "JavaFX Application Thread" netscape.javascript.JSException: java.lang.IllegalAccessException: Class sun.reflect.misc.Trampoline can not access a member of class packagetwo.MainWindow$1 with modifiers "public"
    at com.sun.webkit.dom.JSObject.fwkMakeException(JSObject.java:128)
    at com.sun.webkit.WebPage.twkExecuteScript(Native Method)
    at com.sun.webkit.WebPage.executeScript(WebPage.java:1439)
    at javafx.scene.web.WebEngine.executeScript(WebEngine.java:982)
    at packagetwo.MainWindow.makeUpCall(MainWindow.java:130)
    at packagetwo.MainWindow.access$000(MainWindow.java:22)
    at packagetwo.MainWindow$2.changed(MainWindow.java:83)
    at packagetwo.MainWindow$2.changed(MainWindow.java:68)
    at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.beans.property.ReadOnlyObjectPropertyBase.fireValueChangedEvent(ReadOnlyObjectPropertyBase.java:74)
    at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:102)
    at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
    at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
    at javafx.scene.web.WebEngine$LoadWorker.updateState(WebEngine.java:1260)
    at javafx.scene.web.WebEngine$LoadWorker.dispatchLoadEvent(WebEngine.java:1371)
    at javafx.scene.web.WebEngine$LoadWorker.access$1200(WebEngine.java:1253)
    at javafx.scene.web.WebEngine$PageLoadListener.dispatchLoadEvent(WebEngine.java:1240)
    at com.sun.webkit.WebPage.fireLoadEvent(WebPage.java:2400)
    at com.sun.webkit.WebPage.fwkFireLoadEvent(WebPage.java:2244)
    at com.sun.webkit.network.URLLoader.twkDidFinishLoading(Native Method)
    at com.sun.webkit.network.URLLoader.notifyDidFinishLoading(URLLoader.java:838)
    at com.sun.webkit.network.URLLoader.lambda$didFinishLoading$96(URLLoader.java:829)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalAccessException: Class sun.reflect.misc.Trampoline can not access a member of class packagetwo.MainWindow$1 with modifiers "public"
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
    at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
    at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
    at java.lang.reflect.Method.invoke(Method.java:491)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at com.sun.webkit.Utilities.lambda$fwkInvokeWithContext$55(Utilities.java:94)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.webkit.Utilities.fwkInvokeWithContext(Utilities.java:94)
    ... 29 more

Though calling methods implemented in packageone works fine. 尽管在packageone中实现的调用方法可以正常工作。 Calling both sets of methods from Java also works fine. 从Java调用这两组方法也可以正常工作。 Below are My classes and Javascript calls. 以下是我的课程和Javascript调用。

Packagetwo 套餐二

package packagetwo;

import packageone.Calls;



import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;


public class MainWindow implements Initializable
{

     @FXML
    private BorderPane mainWindow;

    @FXML
    private WebView mainWebView;

    @FXML
    private AnchorPane mainWebViewLayout;

    @Override
    public void initialize(URL url, ResourceBundle rb)
    {           
        Calls jc = new Calls()
        {
            @Override
            public void aMethod1()
            {
                System.out.printf("Calls: Abstract Method Impl 1 Called.\n");
            }
        };

        // Add new load complete listener.
        ChangeListener<Worker.State> onLoadComplete = buildOnLoadCompleteListener(mainWebView, jc);
        mainWebView.getEngine()
                .getLoadWorker()
                .stateProperty()
                .addListener(
                    onLoadComplete);


        // Attempt to load the current web package.
        mainWebView.getEngine().load("file:///" + new File("index.html").getAbsolutePath());

    }

    private ChangeListener<Worker.State> buildOnLoadCompleteListener(
            WebView webview, Calls javaUpCalls)
    {
        return new ChangeListener<Worker.State>()
        {
            @Override
            public void changed(
                    ObservableValue<? extends Worker.State> ov,
                    Worker.State lastState, Worker.State currentState)
            {
                if (currentState == Worker.State.SUCCEEDED)
                {                       
                    // Hook up Java up calls in the Javascript environment.
                    JSObject jsEnvironment = (JSObject) webview.getEngine().executeScript("window");
                    jsEnvironment.setMember("JavaUpCalls", javaUpCalls);

                    makeUpCall(webview);
                }
            }
        };
    }

    private void makeUpCall(WebView webview)
    {           
        String setUpUpCall = 
            "function makeAnUpCall()" +
            "{" +
                "if(typeof JavaUpCalls !== \"undefined\")" +
                "{" + 
                    "JavaUpCalls.method2();" +
                    "JavaUpCalls.aMethod1();" +
                "}" +
            "}";


        webview.getEngine().executeScript(setUpUpCall);
        webview.getEngine().executeScript("makeAnUpCall()");
    }
}

Packageone Packageone

package packageone;

public abstract class Calls()
{
    public abstract void aMethod1();
    public void method2()
    {
        System.out.printf("Calls: Method 1 Called.\n");
    }
}

Index.html is just a standard html page that load successfully with a <p> tag that says the page loaded. Index.html只是一个标准的html页面,可以成功加载,并带有<p>标记,该页面表示已加载页面。

Any idea why the Javascript environment can't call my methods implemented in packagetwo? 知道为什么Javascript环境不能调用我在packagetwo中实现的方法吗?

EDIT: 编辑:

I researched a bit online and found this StackOverflow question: 我在网上进行了一些研究,发现了这个StackOverflow问题:

I attempted the solution listed there (calling setAccessible(true) on the packagetwo method instance) and the error was still thrown. 我尝试了那里列出的解决方案(在packagetwo方法实例上调用setAccessible(true))并且仍然引发错误。

I also tried initializing and calling the Javascript methods from packageone, but the still got the error. 我还尝试从packageone初始化和调用Javascript方法,但仍然收到错误。

The anonymous implementation of Calls isn't available as a public class, so the javascript engine can't get to it. Calls的匿名实现无法作为公共类使用,因此javascript引擎无法实现。

If you create a public implementation in packagetwo, even as an inner class within MainWindow and then create an instance of that to pass through it will work as you expect. 如果您在packagetwo中创建一个公共实现,即使作为MainWindow一个内部类,然后创建要通过它的实例,它也会按预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM