在我正在開發的一個項目中,我需要使用packageone中實現的一些方法定義一個抽象類。在包2中,抽象方法的其餘部分將在類實例化時實現。然後該實例在JavaFX webview中暴露給Javascript代碼。 (來自Oracle的在線示例 - https://blogs.oracle.com/javafx/entry/communicating_between_javascript_and_javafx)Javafx WebView無法訪問class ...的成員,並帶有修飾符「public」
我的問題是,在packagetwo中實現的方法不能從Javascript環境調用。我得到以下錯誤:
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
儘管在packageone中實現的調用方法正常工作。從Java調用這兩套方法也可以。以下是我的課程和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
package packageone;
public abstract class Calls()
{
public abstract void aMethod1();
public void method2()
{
System.out.printf("Calls: Method 1 Called.\n");
}
}
的index.html僅僅是一個標準的HTML頁面一個<p>
標籤,上面寫着頁面加載成功是負載。
任何想法爲什麼Javascript環境不能調用我的方法在packagetwo中實現?
編輯:
我研究了一下網上,發現這個StackOverflow的問題:
我試圖(對packagetwo方法調用setAccessible(真)那裏列出的解決方案實例),錯誤仍然拋出。
我也嘗試初始化並從packageone調用Javascript方法,但仍然有錯誤。
現在有意義。謝謝你的答案。 – MrJman006