In einem Projekt, an dem ich arbeite, muss ich eine abstrakte Klasse mit einigen in packageone implementierten Methoden definieren. Im Paket wird der Rest der abstrakten Methoden implementiert, wenn die Klasse instanziiert wird. Die Instanz wird dann in einer JavaFX-Webansicht mit JavaScript-Code konfrontiert. (Ein Online-Beispiel von Oracle - https://blogs.oracle.com/javafx/entry/communicating_between_javascript_and_javafx)Javafx WebView kann nicht auf ein Mitglied der Klasse ... mit Modifikatoren "public" zugreifen
Mein Problem ist, die Methoden in PacketTwo implementiert sind nicht aus der Javascript-Umgebung aufrufbar. Ich erhalte den folgenden Fehler:
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
Obwohl Aufrufmethoden implementiert in packageone funktioniert gut. Das Aufrufen beider Methodengruppen aus Java funktioniert ebenfalls einwandfrei. Im Folgenden finden Sie meine Klassen und Javascript-Aufrufe.
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 nur eine Standard-HTML-Seite, die Last erfolgreich mit einem <p>
-Tag, das sagt die Seite geladen.
Eine Idee, warum die Javascript-Umgebung kann nicht meine Methoden in PacketTwo implementiert aufrufen?
EDIT:
ich ein wenig Online recherchiert und fanden diese Stackoverflow Frage:
ich die Lösung dort aufgelistet versucht (setAccessible (true) auf der packagetwo Methode aufrufen Instanz) und der Fehler wurde weiterhin ausgelöst.
Ich habe auch versucht, die Javascript-Methoden von packageone zu initialisieren und aufzurufen, aber das hat immer noch den Fehler.
Macht jetzt Sinn. Danke für die Antwort. – MrJman006