JavaFX WebView加载网页时出现NoSuchMethodError问题求助
JavaFX WebView 重复抛出NoSuchMethodError问题排查
问题情况
我是JavaFX新手,使用IntelliJ和Maven开发了包含WebView的JavaFX应用。应用启动初期无报错,但WebView加载网页后,终端会重复出现10-15次java.lang.NoSuchMethodError。目前WebView功能正常,但想明确报错原因。已尝试为VM堆分配更多内存、在VM参数中指定WebView模块,均未解决问题。
错误信息
Exception in thread "JavaFX Application Thread" java.lang.NoSuchMethodError: 'com.sun.javafx.iio.ImageStorage com.sun.javafx.iio.ImageStorage.getInstance()' at javafx.web@20-ea/com.sun.javafx.webkit.prism.WCImageDecoderImpl.loadFrames(WCImageDecoderImpl.java:179) at javafx.web@20-ea/com.sun.javafx.webkit.prism.WCImageDecoderImpl.loadFrames(WCImageDecoderImpl.java:192) at javafx.web@20-ea/com.sun.javafx.webkit.prism.WCImageDecoderImpl.addImageData(WCImageDecoderImpl.java:109) at javafx.web@20-ea/com.sun.webkit.network.URLLoaderBase.twkDidReceiveData(Native Method) at javafx.web@20-ea/com.sun.webkit.network.HTTP2Loader.notifyDidReceiveData(HTTP2Loader.java:566) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) at javafx.web@20-ea/com.sun.webkit.network.HTTP2Loader.lambda$didReceiveData$17(HTTP2Loader.java:549) at javafx.web@20-ea/com.sun.webkit.network.HTTP2Loader.lambda$callBackIfNotCanceled$10(HTTP2Loader.java:441) at javafx.graphics@18.0.1/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at javafx.graphics@18.0.1/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456) at javafx.graphics@18.0.1/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) at javafx.graphics@18.0.1/com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at javafx.graphics@18.0.1/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184) at java.base/java.lang.Thread.run(Thread.java:833)
相关代码
LoginApplication类
public class LoginApplication extends Application { @Override public void start(Stage stage) throws IOException { FXMLLoader fxmlLoader = new FXMLLoader(LoginApplication.class.getResource("Login.fxml")); Scene scene = new Scene(fxmlLoader.load(), 1440, 900); stage.setTitle("Login"); stage.setResizable(false); //Humble urself stage.setHeight(600); stage.setWidth(1000); stage.setScene(scene); stage.show(); Repository repo = new Repository(); }
LoginController类
public class LoginController implements Initializable { @FXML private Label welcomeText; @FXML private TextField txtUsername; @FXML private TextField txtPassword; @FXML private Button btnLogin; @FXML private WebView webViewNews; @FXML private Button btnCreateAccount; @FXML private Text txtPrompt; private WebEngine webEngine; @FXML protected void onLoginClicked() throws SQLException { Repository repo = new Repository(); if(txtUsername.getText() != "") { if(txtPassword.getText() != "") { //Stop user input while query is processed btnLogin.setDisable(true); btnCreateAccount.setDisable(true); txtPrompt.setText("Checking credentials... please wait."); //Check query and do stuff... if(repo.authenticateUser(txtUsername.getText(), txtPassword.getText())) { txtPrompt.setText("Login Success Welcome!"); txtUsername.setVisible(false); txtPassword.setVisible(false); btnLogin.setVisible(false); } else { txtPrompt.setText("Login Failed! Invalid credentials."); btnLogin.setDisable(false); btnCreateAccount.setDisable(false); txtPassword.clear(); } } else txtPrompt.setText("Password blank! Please enter a password."); } else txtPrompt.setText("Username blank! Please enter a username."); } @Override public void initialize(URL url, ResourceBundle resourceBundle) { webEngine = webViewNews.getEngine(); webEngine.load("https://www.forums.blacksunstudios.us/index.php?pages/hideNews/"); }
原因分析
从错误栈可以清晰看到:
javafx.web模块使用的是20-ea(早期访问预览版)javafx.graphics模块使用的是18.0.1(稳定版)
JavaFX的各个核心模块版本必须完全一致,不同版本的模块内部API存在差异:20-ea版本的javafx.web尝试调用javafx.graphics中的ImageStorage.getInstance()方法,但该方法在18.0.1版本的javafx.graphics中不存在(或方法签名已变更),从而抛出NoSuchMethodError。
解决方案建议
- 统一JavaFX依赖版本:确保
pom.xml中所有JavaFX相关依赖(javafx-web、javafx-graphics、javafx-controls、javafx-fxml等)使用完全相同的版本号,且避免混合使用早期访问版(ea)和稳定版,推荐使用最新稳定版。 - 检查模块声明:如果是模块化项目,确保
module-info.java中requires语句对应的模块版本与依赖版本一致。 - 清理依赖缓存:执行Maven的
clean和install命令,清理本地缓存中可能存在的版本冲突依赖。
内容的提问来源于stack exchange,提问作者HaltPotato
相关产品推荐
相关产品推荐

