2016-09-26 2 views
0

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.

Antwort

0

Die anonyme Implementierung von Calls ist nicht als öffentliche Klasse verfügbar, sodass die JavaScript-Engine nicht darauf zugreifen kann.

Wenn Sie eine öffentliche Implementierung in packagetwo erstellen, auch als innere Klasse innerhalb von MainWindow und dann eine Instanz erstellen, die Sie durchlaufen, wird es wie erwartet funktionieren.

+0

Macht jetzt Sinn. Danke für die Antwort. – MrJman006

Verwandte Themen