2017-12-22 9 views
4

私はJavaFX WebViewクラスto make it render even when not visibleの手術を受ける必要があります。これを達成するために私の探求では、私はJavassistを見つけましたが、私はそれを使用しようとすると、私はこのエラーを取得する:クラスをロードする前にクラスを変更するにはどうすればよいですか?

java.lang.IllegalArgumentException: Can not set javafx.scene.web.WebView field sample.Controller.webView to javafx.scene.web.WebView 

私はそれを修正しまった前にメンバーが定義されたので、それはだと思いますか?よく分かりません。現時点では、私は、コードを使用することにより、クラスで何かを変更するだけでロードし、それを解凍し、それを保存していないよ(?):

CtClass webViewClass = ClassPool.getDefault().get("javafx.scene.web.WebView"); 
webViewClass.defrost(); 
webViewClass.toClass(); 

これは私の最小再現性の一例です。まず、Main.java

package sample; 

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 
import javassist.CannotCompileException; 
import javassist.ClassPool; 
import javassist.CtClass; 
import javassist.NotFoundException; 

public class Main extends Application { 
    public static void main(String[] args) { 
     try { 
      CtClass webViewClass = ClassPool.getDefault().get("javafx.scene.web.WebView"); 
      webViewClass.defrost(); 
      webViewClass.toClass(); 
     } catch (NotFoundException | CannotCompileException e) { 
      e.printStackTrace(); 
     } 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); 
     primaryStage.setScene(new Scene(root, 800, 600)); 
     primaryStage.show(); 
    } 
} 

これらはController.javaファイルの内容です:

package sample; 

import javafx.fxml.FXML; 
import javafx.scene.web.WebView; 

public class Controller { 
    @FXML 
    private WebView webView; 

    @FXML 
    private void initialize() { 
     webView.getEngine().load("http://stackoverflow.com"); 
    } 
} 

と、これはビュー、sample.fxmlです:完全な例外はある

<?xml version="1.0" encoding="UTF-8"?> 
<?import javafx.scene.layout.AnchorPane?> 
<?import javafx.scene.web.WebView?> 
<AnchorPane xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" 
      fx:controller="sample.Controller"> 
    <WebView fx:id="webView" minHeight="-Infinity" minWidth="-Infinity"/> 
</AnchorPane> 

Exception in Application start method 
java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389) 
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767) 
Caused by: java.lang.RuntimeException: Exception in Application start method 
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917) 
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$154(LauncherImpl.java:182) 
    at java.lang.Thread.run(Thread.java:748) 
Caused by: javafx.fxml.LoadException: 
/C:/Users/pupeno/Documents/Dashman/code/experiments/webviewwoes/out/production/webviewwoes/sample/sample.fxml:8 

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104) 
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097) 
    at sample.Main.start(Main.java:27) 
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863) 
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326) 
    at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(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$147(WinApplication.java:177) 
    ... 1 more 
Caused by: java.lang.IllegalArgumentException: Can not set javafx.scene.web.WebView field sample.Controller.webView to javafx.scene.web.WebView 
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) 
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) 
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) 
    at java.lang.reflect.Field.set(Field.java:764) 
    at javafx.fxml.FXMLLoader.injectFields(FXMLLoader.java:1163) 
    at javafx.fxml.FXMLLoader.access$1600(FXMLLoader.java:103) 
    at javafx.fxml.FXMLLoader$ValueElement.processValue(FXMLLoader.java:857) 
    at javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:765) 
    at javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2823) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2532) 
    ... 17 more 
Exception running application sample.Main 

Process finished with exit code 1 
+0

はこのようなものですか? – GhostCat

+0

@GhostCat:スタックトレース、行番号、ファイルなどを含む完全な例外を追加しました – Pablo

+0

javassistを使用したことはありませんが、webViewClass.toClass();によって 'webViewClass.writeFile() ; '、エラーはなくなりました。 – DVarga

答えて

4

ほとんどの場合、2つの異なるClassLoaderによってロードされたWebviewの2つのバージョンがあります。少なくとも、その場合にのみ、このような例外が予想されます。

注Javassistのtutorialから、この段落:

If the program is running on some application server such as JBoss and Tomcat, the context class loader used by toClass() might be inappropriate. In this case, you would see an unexpected ClassCastException. To avoid this exception, you must explicitly give an appropriate class loader to toClass(). For example, if bean is your session bean object, then the following code:

CtClass cc = ...; Class c = cc.toClass(bean.getClass().getClassLoader()); would work. You should give toClass() the class loader that has loaded your program (in the above example, the class of the bean object).

toClassを呼び出すには、()のスレッドのコンテキストクラスローダがクラスをロードします。私は、FXMLLoaderがビューをロードするときに、別のクラスローダーでクラスをロードすると仮定し、何とかして、この例外で終わるように混乱します。 FXMLLoaderが変更されていないクラスをロードするため、すべてのロードが正常に行われる可能性がありますが、変更は機能しません。ラインアップスロー

ClassPool classPool = ClassPool.getDefault(); 
CtClass webViewClass = classPool.get("javafx.scene.web.WebView"); 
webViewClass.defrost(); 
classPool.toClass(webViewClass, FXMLLoader.class.getClassLoader(), null); 
+0

私は 'webViewClass.toClass(FXMLLoader.getDefaultClassLoader());'を試みましたが、私は同じ例外を受け取ります。 – Pablo

+0

'webViewClass.toClass(FXMLLoader.class.getClassLoader())'はクラッシュしません。 – Pablo

関連する問題