2016-09-26 8 views
0

私が取り組んでいるプロジェクトでは、いくつかのメソッドをpackageoneに実装して抽象クラスを定義する必要があります。パッケージでは、抽象メソッドの残りの部分は、クラスがインスタンス化されるときに実装されます。その後、インスタンスはJavaFX WebviewでJavascriptコードに公開されます。 (Oracleのオンライン例 - https://blogs.oracle.com/javafx/entry/communicating_between_javascript_and_javafxJavafx WebViewは修飾子 "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とは、ページがロードされたと言う<p>タグを正常にロードだけで、標準のHTMLページです。

Javascript環境がpackagetwoに実装されたメソッドを呼び出せない理由は何ですか?

EDIT:

私はオンラインビットを調査し、このStackOverflowの質問が見つかりました:

を私はpackagetwo法にsetAccessible(true)を呼び出して(そこに記載されているソリューションを試みましたインスタンス)、エラーはスローされました。

また、packageoneからJavascriptメソッドを初期化して呼び出すことも試みましたが、まだエラーが発生しています。

答えて

0

Callsの匿名の実装はパブリッククラスとして利用できないため、javascriptエンジンはアクセスできません。

パブリック実装をpackagetwoで作成する場合は、内部クラスがMainWindowであっても、そのインスタンスを作成して渡すと期待通りに機能します。

+0

今や意味をなさない。答えてくれてありがとう。 – MrJman006

関連する問題