2017-12-22 2 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 : 이들은 Controller.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(); 
    } 
} 

하고 있습니다 :

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

두 개의 다른 ClassLoader에 의해로드 된 Webview의 두 버전이있을 가능성이 높습니다. 적어도이 경우에만 이러한 예외가 예상됩니다.

참고와 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

관련 문제