2017-12-22 8 views
4

Ich brauche eine Operation für die JavaFX WebView Klasse to make it render even when not visible. In meiner Suche dies zu erreichen, fand ich Javassist, aber wenn ich versuche, es zu benutzen, ich diesen Fehler:Wie kann ich eine Klasse ändern, bevor sie geladen wurde?

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

Ich denke, das ist, weil das Element definiert wurde, bevor es geändert wurde? Ich bin mir nicht sicher. Im Moment bin Modifizieren mir nichts in der Klasse, nur laden, Auftauen es und speichert es, indem Sie den Code verwenden (?):

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

Dies ist mein kleinstes reproduzierbares Beispiel. Zuerst 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(); 
    } 
} 

und das sind die Inhalte der Controller.java Datei:

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"); 
    } 
} 

und dies ist der Ansicht, 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> 

Die vollständige Ausnahme ist:

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

Welche Linie wirft? – GhostCat

+0

@GhostCat: Ich habe die vollständige Ausnahme hinzugefügt, mit Stack-Trace, Zeilennummern, Dateien usw. – Pablo

+0

Nie benutzt javassist, aber, wenn in Ihrem Code, wenn Sie 'webViewClass.toClass();' durch 'webViewClass.writeFile() austauschen ; ', der Fehler ist weg. – DVarga

Antwort

4

Sehr wahrscheinlich gibt es zwei Versionen Ihres Webview, die von zwei verschiedenen ClassLoadern geladen werden, zumindest würde ich eine solche Ausnahme nur in diesem Fall erwarten.

Hinweis: dieser Absatz aus dem 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).

Aufruf toClass() macht den Kontext-Klassenlader des Fadens die Klasse laden. Ich nehme an, wenn der FXMLLoader die Ansicht lädt, lädt er die Klassen mit einem anderen Klassenlader, und irgendwie werden die Dinge durcheinander gebracht, so dass Sie diese Ausnahme haben. Ein anderes mögliches Ergebnis wäre gewesen, dass alles gut lädt, aber Ihre Änderungen funktionieren nicht, weil der FXMLLoader nicht modifizierte Klassen lädt.

etwas tun:

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

Ich habe versucht 'webViewClass.toClass (FXMLLoader.getDefaultClassLoader());' aber ich bekomme die gleiche Ausnahme. – Pablo

+0

'webViewClass.toClass (FXMLLoader.class.getClassLoader())' stürzt nicht ab, mal sehen, ob das funktioniert. – Pablo

Verwandte Themen