JavaFX desktop app won't start in a specific machine (works in others)

心不动则不痛 提交于 2019-12-24 18:15:12

问题


I have a java desktop app using Swing which I rewrote in JavaFX using SceneBuilder.

The Swing app works fine on all users machines (35 Machine). After rewriting the app in JavaFX, on one specific machine the app won't start and gives the below error message.

I couldn't figure out the issue. I appreciate if someone can give any help. Thank you.

Exception in Application start method
java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(Unknown Source)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(Unknown Source)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at java.base/sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown Source)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: com/sun/javafx/css/converters/PaintConverter
        at com.jfoenix.controls.JFXPasswordField$StyleableProperties.<clinit>(JFXPasswordField.java:205)
        at com.jfoenix.controls.JFXPasswordField.<init>(JFXPasswordField.java:156)
        at idehmis.controller.LoginController.<init>(LoginController.java:51)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
        at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
        at java.base/java.lang.Class.newInstance(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processAttribute(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader$Element.processStartElement(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
        at javafx.fxml/javafx.fxml.FXMLLoader.load(Unknown Source)
        at idehmis.IDEHMIS.start(IDEHMIS.java:30)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(Unknown Source)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(Unknown Source)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(Unknown Source)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(Unknown Source)
        at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(Unknown Source)
        ... 1 more
Caused by: java.lang.ClassNotFoundException: com.sun.javafx.css.converters.PaintConverter
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
        at java.base/java.lang.ClassLoader.loadClass(Unknown Source)

回答1:


it looks like the JVM is finding it difficult to locate the com.sun.javafx.css.converters.PaintConverter at runtimewhich causes the ClassNotFoundException Exception error, and which in turn causes the JFoenix library to throw java.lang.NoClassDefFoundError meaning the class was not found on the classpath. This indicates that we were trying to load the class definition, and the class did not exist on the classpath so first make sure you have the right version of java which is Java 8 to support JFoenix, them make sure The JFoenix library is located in you classpath.




回答2:


The stack trace, because it prefaces each fully-qualified class name (for example java.lang.ClassLoader) with a module name (e.g. java.base) indicates that the machine is trying to run the application using Java 9.

The CSS converter classes, such as PaintConverter, were promoted from private API, where they were located in Java 8 and earlier, to public API in Java 9. So the class com.sun.javafx.css.converters.PaintConverter no longer exists, and has been replaced by javafx.css.converter.PaintConverter. Hence, when running your application in Java 9, you get a ClassNotFoundException.

The bottom line here is that using any API that is not public, or using third party libraries that do so, is liable to make your application fail if the user updates their JVM. The possible solutions to this problem are:

  • Avoid using private API, or libraries that use private API
  • Create and maintain different versions of your code that are for specific JVM versions. In the case of the third-party JFoenix library you are using, there is a separate version for Java 9, so you could create a Java 9 version of the application that uses that version of the library. Note that not only does this create an additional burden on the developer, but it also can potentially create issues for the end user, who will be forced to update the version of your application they use in sync with updating their JVM.
  • Create a "Self-Contained Application Bundle" for your application. This bundles a specific JVM with your code, so you essentially control the JVM the user uses to run your application. The downsides to this are that you need to create a different bundle for each platform (Windows 32 bit, Windows 64 bit, Mac, Linux) that you want to support, and that the size of the application will increase substantially (to include the JVM).

I would generally recommend the first option when possible, and the third when not.



来源:https://stackoverflow.com/questions/48827678/javafx-desktop-app-wont-start-in-a-specific-machine-works-in-others

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!