ProGuard breaks JavaFX application - java

I'm trying to obfuscate my JavaFX application but it fails. The generated result does not work and I do not understand why. The resulting jar just fails because the fxml file cannot load all imports anymore (ClassNotFoundException).
The Deployment workflow:
Build runnable jar (in IntelliJ knwon as an artifact)
Obfuscate that jar with ProGuard
Fix some issues in that jar that ProGuard fails to do
1) The minimal example application
The example application 'GuardTest' is a IntelliJ project that consists of 3 classes.
sample.Main: contains the application entry point and loads the GUI fxml file 'sample.fxml'
sample.Controller: the controller class for 'sample.fxml'
controls.CustomControl: A simple javafx control that inherits from HBox. This is used in 'sample.fxml'
The contents of 'sample.fxml':
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>
<?import controls.CustomControl?>
<VBox fx:controller="sample.Controller"
xmlns:fx="http://javafx.com/fxml">
<children>
<CustomControl>
<children>
<Button text="Test"></Button>
</children>
</CustomControl>
</children>
</VBox>
2) Obfuscation
Now I use ProGuard for the resulting jar file that is generated from the above project. I use the following settings:
-target 8
-injars ./out/artifacts/JavaFXApp/JavaFXApp.jar
-outjars ./out/obfuscated/Obfuscated.jar
-ignorewarnings
-printmapping ./out/obfuscated/proguard.map
-dontusemixedcaseclassnames
-dontshrink
-dontoptimize
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
#-flattenpackagehierarchy
-repackageclasses 'p'
-allowaccessmodification
-libraryjars "<java.home>/lib/rt.jar"
-libraryjars "<java.home>/lib/javaws.jar"
-libraryjars "<java.home>/lib/ext/jfxrt.jar"
-adaptresourcefilecontents **.fxml,**.properties,META-INF/MANIFEST.MF,images/*.jar,publicCerts.store,production.version
-keepattributes javafx.fxml.FXML,Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
-keepclassmembers class * {
#javafx.fxml.FXML *;
}
-keepclassmembernames public class com.javafx.main.Main, com.nywelt.sharkload.application.Main {
public static void main(java.lang.String[]);
}
-keepclasseswithmembers public class com.javafx.main.Main, com.product.main.EntryFX, net.license.LicenseEntryPoint {
public *; public static *;
}
3) Fixing some (obvious) ProGuard failures
The resulting jar file 'Obfuscated.jar' has the following structure:
**Obfuscated.jar**
- META-INF
--> MANIFEST.MF
- p
--> a.class
--> b.class
--> c.class
- sample
--> sample.fxml
The main class starts the GUI by loading the 'sample.fxml' file with the following line:
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Because of that I have to move the 'sample.fxml' file to the folder p as well to make the above line work again. I also fix some issue in the fxml file where ProGuard forgets to change a (now obfuscated) class name.
Now the structure looks like this:
**Obfuscated_fixed.jar**
- META-INF
--> MANIFEST.MF
- p
--> a.class
--> b.class
--> c.class
--> sample.fxml
The sample.fxml file now looks like this:
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>
<?import p.a?>
<VBox fx:controller="p.b"
xmlns:fx="http://javafx.com/fxml">
<children>
<a>
<children>
<Button text="Test"></Button>
</children>
</a>
</children>
</VBox>
The Problem
Now this jar should really work again because everything is ok again. But it DOESN'T! The fxml loader fails to load the CustomControl (now named/obfuscated 'a.class'). Why is that?
I get the following error output when starting the jar file (I'm running java version 1.8.0_40):
E:\Eigene Programme\GuardTest\out\obfuscated>java -jar Obfuscated_fixed.jar
Exception in Application start method
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown So
urce)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$152(
Unknown Source)
at com.sun.javafx.application.LauncherImpl$$Lambda$49/849460928.run(Unkn
own Source)
at java.lang.Thread.run(Unknown Source)
Caused by: javafx.fxml.LoadException:
file:/E:/Eigene%20Programme/GuardTest/out/obfuscated/Obfuscated_fixed.jar!/p/sam
ple.fxml
at javafx.fxml.FXMLLoader.constructLoadException(Unknown Source)
at javafx.fxml.FXMLLoader.importClass(Unknown Source)
at javafx.fxml.FXMLLoader.processImport(Unknown Source)
at javafx.fxml.FXMLLoader.processProcessingInstruction(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.load(Unknown Source)
at p.c.start(Main.java:13)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159
(Unknown Source)
at com.sun.javafx.application.LauncherImpl$$Lambda$52/663980963.run(Unkn
own Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(Unknown
Source)
at com.sun.javafx.application.PlatformImpl$$Lambda$46/410424423.run(Unkn
own Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(Unknown Sourc
e)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/1149216748.run(Unk
nown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(Unknown S
ource)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/1963387170.run(Unk
nown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(Unknown Source)
at com.sun.glass.ui.win.WinApplication$$Lambda$36/237061348.run(Unknown
Source)
... 1 more
Caused by: java.lang.ClassNotFoundException
at javafx.fxml.FXMLLoader.loadType(Unknown Source)
... 26 more
E:\Eigene Programme\GuardTest\out\obfuscated>Pause
Drücken Sie eine beliebige Taste . . .
Setting the default class loader in the main class with
FXMLLoader.setDefaultClassLoader(this.getClass().getClassLoader());
does not help either.
Project Files
Here you can find the example project (IntelliJ):
https://www.dropbox.com/s/ot51spvwk6lzo4k/GuardTest.zip?dl=0
The generated jar artifact by IntelliJ is compiled to:
./out/artifacts/JavaFXApp/JavaFXApp.jar
The obfuscated Jar is found under:
./out/obfuscated/Obfuscated.jar
The obfuscated but fixed (at least it should be) jar as described above:
./out/obfuscated/Obfuscated_fixed.jar
And to show that the import statement in the 'sample.fxml' file causes the problem I removed my custom control from the fxml file and saved that to the (working) jar:
./out/obfuscated/Obfuscated_fixed_work.jar
I'm sorry for the long question. I hope you will help me anyway :)

I have found the solution! The problem is that FXML cannot import classes that do not start with an upper case letter. Therefore one has to provide an own list of available names that ProGuard uses for obfuscating. This is done by:
-classobfuscationdictionary obfuscationClassNames.txt
With obfuscationClassNames.txt containing the line seperated list of available class names:
A
B
C
D
...

I used the same steps. I can see imports are updated into fxml file but their use is not.
Getting the exception:
javafx.fxml.LoadException: MenuBarControl is not a valid type.
But If I see the fxml file imports are updated but not their use.
< ? import q.A ? >
< ? import r.A ? >
<VBox fx:id="top">
<MenuBarControl fx:id="menuBarControl"/>
</VBox>

Related

why FXMLLoader giving error when used to load a FXML file? [duplicate]

This question already has answers here:
Module error when running JavaFx media application
(2 answers)
Closed 2 years ago.
I was following a JavaFX tutorial and wrote the following code.
All the required header files are imported.
Main.java
public class Main extends Application {
#Override
public void start(Stage primaryStage){
try {
Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.setTitle("Random Number Generator");
primaryStage.show();
}catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Main.fxml (created using SceneBuilder)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane minHeight="100.0" minWidth="100.0" prefHeight="300.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
<children>
<Button id="button_generateRandomNumber" layoutX="171.0" layoutY="212.0" mnemonicParsing="false" onAction="#generateRandom" text="Generate Random Number" textAlignment="CENTER" textFill="#1e4d0e" />
<Label fx:id="message" layoutX="112.0" layoutY="143.0" prefHeight="45.0" prefWidth="258.0" textAlignment="CENTER" />
</children>
</AnchorPane>
StackTrace
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(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module #0x5d85fddd) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util to unnamed module #0x5d85fddd
at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38)
at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056)
at application.Main.start(Main.java:20)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
... 1 more
Exception running application application.Main
I have tried every combination with getResource("Main.fxml") including relative and absolute path in every way possible still I am getting the error.
code is 100% same as of that tutorial.
In order to javafx work, you need to either download and import javafx sdk to your project or specify dependency, if you are using build tool like Maven or Gradle.
Moreover you need to add required modules (in this case javafx's .jars) either by using module-info.java and specifying required modules there, or adding modules to VM arguments - https://openjfx.io/openjfx-docs/#install-javafx.
Bonus:
Note that javafx was present in JDK up to version 10. Since version 11, they removed it. That is why you need to import javafx somehow to your project.

JavaFX FXML application wont start

I have problems creating and running a JavaFX FXML application in Netbeans. Im running Netbeans 8.1. Below is code and errormessages. I guess its something wrong with the way netbeans write the path:
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
But I cant figure out in what way ...
Main
public class JavaFXApplication6 extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
FXML
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication6.FXMLDocumentController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
ErrorMessage
ant -f /Users/MyAccount/NetBeansProjects/ExempelJavaFX1 -Djavac.includes=JavaFXTheNewBoston/Ex031fxml.java -Dnb.internal.action.name=run.single -Drun.class=JavaFXTheNewBoston.Ex031fxml run-single
init:
Deleting: /Users/MyAccount/NetBeansProjects/ExempelJavaFX1/build/built-jar.properties
deps-jar:
Updating property file: /Users/MyAccount/NetBeansProjects/ExempelJavaFX1/build/built-jar.properties
Compiling 1 source file to /Users/MyAccount/NetBeansProjects/ExempelJavaFX1/build/classes
compile-single:
run-single:
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:483)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:363)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:303)
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:483)
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:875)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$147(LauncherImpl.java:157)
at com.sun.javafx.application.LauncherImpl$$Lambda$49/589873731.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException: Location is required.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3201)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3169)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3142)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3118)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3098)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3091)
at JavaFXTheNewBoston.Ex031fxml.start(Ex031fxml.java:22)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
at com.sun.javafx.application.LauncherImpl$$Lambda$52/1759200495.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
at com.sun.javafx.application.PlatformImpl$$Lambda$46/340870931.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/861248623.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/1530388690.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Exception running application JavaFXTheNewBoston.Ex031fxml
/Users/MyAccount/NetBeansProjects/ExempelJavaFX1/nbproject/build-impl.xml:1051: The following error occurred while executing this line:
/Users/MyAccount/NetBeansProjects/ExempelJavaFX1/nbproject/build-impl.xml:805: Java returned: 1
BUILD FAILED (total time: 2 seconds)
Here is my folder layout:
UPDATE
Also got this shorter errormessage:
ant -f /Users/MyAccount/NetBeansProjects/JavaFXApplication7 -Djavac.includes=javafxapplication7/JavaFXApplication7.java -Dnb.internal.action.name=run.single -Drun.class=javafxapplication7.JavaFXApplication7 run-single
init:
deps-jar:
Created dir: /Users/MyAccount/NetBeansProjects/JavaFXApplication7/build
Updating property file: /Users/MyAccount/NetBeansProjects/JavaFXApplication7/build/built-jar.properties
Created dir: /Users/MyAccount/NetBeansProjects/JavaFXApplication7/build/classes
Created dir: /Users/MyAccount/NetBeansProjects/JavaFXApplication7/build/empty
Created dir: /Users/MyAccount/NetBeansProjects/JavaFXApplication7/build/generated-sources/ap-source-output
Compiling 1 source file to /Users/MyAccount/NetBeansProjects/JavaFXApplication7/build/classes
compile-single:
run-single:
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.DelegatingMet/Users/MyAccount/NetBeansProjects/JavaFXApplication7/nbproject/build-impl.xml:1051: The following error occurred while executing this line:
/Users/MyAccount/NetBeansProjects/JavaFXApplication7/nbproject/build-impl.xml:805: Java returned: 1
BUILD FAILED (total time: 15 seconds)
UPDATE - here is my build.xml
<?xml version="1.0" encoding="UTF-8"?><!-- You may freely edit this file. See commented blocks below for --><!-- some examples of how to customize the build. --><!-- (If you delete it and reopen the project it will be recreated.) --><!-- By default, only the Clean and Build commands use this build script. --><project name="JavaFXApplication1" default="default" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant">
<description>Builds, tests, and runs the project JavaFXApplication1.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. Those of them relevant for JavaFX project are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-jfx-jar: called before FX SDK specific <fx:jar> task
-post-jfx-jar: called after FX SDK specific <fx:jar> task
-pre-jfx-deploy: called before FX SDK specific <fx:deploy> task
-post-jfx-deploy: called after FX SDK specific <fx:deploy> task
-pre-jfx-native: called just after -pre-jfx-deploy if <fx:deploy> runs in native packaging mode
-post-jfx-native: called just after -post-jfx-deploy if <fx:deploy> runs in native packaging mode
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting a HTML postprocessor after javaFX SDK deployment:
<target name="-post-jfx-deploy">
<basename property="jfx.deployment.base" file="${jfx.deployment.jar}" suffix=".jar"/>
<property name="jfx.deployment.html" location="${jfx.deployment.dir}${file.separator}${jfx.deployment.base}.html"/>
<custompostprocess>
<fileset dir="${jfx.deployment.html}"/>
</custompostprocess>
</target>
Example of calling an Ant task from JavaFX SDK. Note that access to JavaFX SDK Ant tasks must be
initialized; to ensure this is done add the dependence on -check-jfx-sdk-version target:
<target name="-post-jfx-jar" depends="-check-jfx-sdk-version">
<echo message="Calling jar task from JavaFX SDK"/>
<fx:jar ...>
...
</fx:jar>
</target>
For more details about JavaFX SDK Ant tasks go to
http://docs.oracle.com/javafx/2/deployment/jfxpub-deployment.htm
For list of available properties check the files
nbproject/build-impl.xml and nbproject/jfx-impl.xml.
-->
</project>
Try to Clean and Build,
Run File

File Not Found when using Java Web Start

I'm trying to use Java Web Start to replace a Java applet, but every time I run the .jnlp file either directly from the web server or directly from my computer it gives me an error.
I see the Java Web Start splash screen, and then the default progress bar appears. It downloads, and then verifies my jar, but shortly afterwards the following error message appears "Unable to launch the application".
CouldNotLoadArgumentException[ Could not load file/URL specified: C:\Users\[username]\AppData\Local\Temp\tmp_cache9015150161909242571.tmp]
at com.sun.javaws.Main.launchApp(Unknown Source)
at com.sun.javaws.Main.continueInSecureThread(Unknown Source)
at com.sun.javaws.Main.access$000(Unknown Source)
at com.sun.javaws.Main$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.io.FileNotFoundException: C:\Users\[username]\AppData\Local\Temp\tmp_cache9015150161909242571.tmp (The system cannot find the file specified)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at com.sun.javaws.jnl.LaunchDescFactory.buildDescriptor(Unknown Source)
at com.sun.javaws.Main.launchApp(Unknown Source)
at com.sun.javaws.Main.continueInSecureThread(Unknown Source)
at com.sun.javaws.Main.access$000(Unknown Source)
at com.sun.javaws.Main$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I see no files in the Temp folder that look anything like tmp_cache.
Here is my JNLP file:
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+"
codebase="http://localhost:2020/MyServer/applets"
href="basicTest.jnlp">
<information>
<title>JWS Test</title>
<vendor>My Company</vendor>
</information>
<resources>
<j2se version="1.7+"
href="http://java.sun.com/products/autodl/j2se"/>
<jar href="basicTest.jar" main="true" />
</resources>
<application-desc
name="Test Name"
main-class="main.Entry">
</application-desc>
<update check="background"/>
</jnlp>
Things I've tried:
Downloading the JNLP file and the JAR from my web server (Works as expected)
Using a brand new, bare-bones jar with nothing but a main method and a System.out.print() statement (Same result)
Changing the href inside the .jnlp file (Different error message, can't find .jar, as expected. My server logs show this correctly as a 404)
Changing the value of the main-class attribute (Same result, suggests that the JVM never starts)
Running other example apps from Sun (These work correctly, either when running through the browser or when running downloaded .jnlp files)
Clearing my java cache and temp files (Same results)
I did wonder if the jars not being fully signed would matter (my jar is currently self-signed while in development) but I would expect a different error in that case.
It seems as though the jar file is downloaded into one location, and verified, but then can't be found when the JVM tries to start it. Could there be a cache location conflict?
One of the reason can be JRE 7 onwards security is high .Signing jar is required.

Can't run a simple JavaFX in a Browser packaged by Netbeans IDE

I created the standard NetBeans JavaFX application and I tried to run it in a browser but I had no luck. I have followed every instruction out there with no luck. I am not doing anything special, standard JavaFX and built it with NetBeans IDE.
Here is the error message I am getting:
CacheEntry[file:/Users/mo/NetBeansProjects/WebAppTest/dist/WebAppTest.jar]: updateAvailable=false,lastModified=Fri Mar 04 07:03:31 EST 2016,length=19089
java.security.AccessControlException: access denied ("java.util.PropertyPermission" "user.dir" "read")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
at java.security.AccessController.checkPermission(AccessController.java:884)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at sun.plugin2.applet.FXAppletSecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1294)
at java.lang.System.getProperty(System.java:717)
at java.io.UnixFileSystem.resolve(UnixFileSystem.java:133)
at java.io.File.getAbsolutePath(File.java:556)
at webapptest.WebAppTest.start(WebAppTest.java:24)
at com.sun.javafx.applet.FXApplet2$2.run(FXApplet2.java:134)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "user.dir" "read")
at com.sun.javafx.applet.FXApplet2$2.run(FXApplet2.java:150)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "user.dir" "read")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
at java.security.AccessController.checkPermission(AccessController.java:884)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at sun.plugin2.applet.FXAppletSecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1294)
at java.lang.System.getProperty(System.java:717)
at java.io.UnixFileSystem.resolve(UnixFileSystem.java:133)
at java.io.File.getAbsolutePath(File.java:556)
at webapptest.WebAppTest.start(WebAppTest.java:24)
at com.sun.javafx.applet.FXApplet2$2.run(FXApplet2.java:134)
... 4 more
JavaFX application:
FXML File
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="webapptest.FXMLDocumentController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
Controller:
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
main method
public class WebAppTest extends Application {
#Override
public void start(Stage stage) throws Exception {
File f = new File("FXMLDocument.fxml");
String filePath = f.getAbsolutePath();
Parent root = FXMLLoader.load(getClass().getResource(filePath));
System.out.println(filePath);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Due to the Certificate signing issues: I manually trusted the dist\ directory:
Regarding the FXML File, If I didn't do getAbsolutePath(); and I get the resources using the line code below. I get a different error message:
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
if I didn't use getAbsolutePath() I get the following error:
updateAvailable=true,lastModified=Fri Mar 04 09:12:56 EST 2016,length=19089
java.lang.NullPointerException: Location is required.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3207)
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 webapptest.WebAppTest.start(WebAppTest.java:26)
at com.sun.javafx.applet.FXApplet2$2.run(FXApplet2.java:134)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.NullPointerException: Location is required.
at com.sun.javafx.applet.FXApplet2$2.run(FXApplet2.java:150)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Caused by: java.lang.NullPointerException: Location is required.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3207)
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 webapptest.WebAppTest.start(WebAppTest.java:26)
at com.sun.javafx.applet.FXApplet2$2.run(FXApplet2.java:134)
... 4 more
Here is the content of the Jar file:
Since you updated your answer, it's now clear what you actually want to do. Instead of converting a classpath resource (as retrieved with getClass().getResource()) to a file, you should just use the resource directly:
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
You do not want to deal with the File class at all, since the resource is coming from inside of a JAR file. Ditch all of that code.
Also, make sure you have the FXMLDocument.fxml placed inside of the webapptest package. If you have it placed at the root of the classpath, use .getResource("/FXMLDocument.fxml") instead.
To include what has been mentioned in comments: You might need to clean and rebuild your project in order for the resources to show up properly.
The problem is that you are denied permission to the filesystem.
In order for your applet to receive file system permissions, it must either be signed with a code certificate (which costs money) or you need to add a security exception in the Java applet policy file.
Also see:
Allow Java applet to file system access and recording without modifying java policy file?
Default Policy Implementation and Policy File Syntax
Creating a Trusted Applet with Local File System Access Rights
What Applets Can and Cannot Do

How do I create a custom JavaFX component library?

I've been toying with JavaFX for a while now and now I wanted to share some of the components I have built. For ease of use, I would like to be able to distribute the components as libraries, so another user can just import my libraries into JavFX project. However, building a a library file to import into SceneBuilder (SB) proved to be much harder than I had expected. I tried following this blog post but I must be doing something wrong. I want to create my own custom component, using a .fxml file and a .jar file.
I tried building this component:
TestPane.java
package pack;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.AnchorPane;
import java.io.IOException;
public class TestPane extends AnchorPane {
public TestPane(){
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("TestPane.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
#FXML protected void onClick(ActionEvent ae){
System.out.println("Click");
}
}
TestPane.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<fx:root type="AnchorPane" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<Button fx:id="button" layoutX="6.0" layoutY="10.0" mnemonicParsing="false" text="Button" onAction="#onClick" />
</fx:root>
I use Eclipse Mars, created a new JavaFX Library project, created a new package called pack. In that package, I created the two components from above. I then right-clicked the project and selected "Export... -> Jar-file", and made no changes in the export dialogue.
I then created a new FXML project. I opened the .fxml file in SB and imported my exported .jar file, using the Import JAR/FXML File..." dialogue, and then dragged it into my view.
Here is the code for the test project I've created.
LibTest.java
package test;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class LibTest extends Application {
#Override
public void start(Stage primaryStage) throws IOException {
Parent root = FXMLLoader.load( getClass().getResource("LibTest.fxml") );
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
LibTest.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import pack.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="199.0" prefWidth="126.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.40">
<children>
<TestPane layoutX="34.0" layoutY="82.0" />
</children>
</AnchorPane>
I thought I had followed all the online guides and tutorials by now but there is something I must be missing. When I then try to launch my test project, I get the error bellow. I understand that Caused by: javafx.fxml.LoadException: TestPane is not a valid type. is the "key message", but what does it mean, and how do I fix this problem?
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:497)
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:497)
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$152(LauncherImpl.java:182)
at com.sun.javafx.application.LauncherImpl$$Lambda$50/1645995473.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: javafx.fxml.LoadException: TestPane is not a valid type.
/D:/WorkspaceDir/ProjectDir/bin/test/LibTest.fxml:11
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.createElement(FXMLLoader.java:2778)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2708)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2531)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3218)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3128)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3108)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3101)
at test.LibTest.start(LibTest.java:15)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159(LauncherImpl.java:863)
at com.sun.javafx.application.LauncherImpl$$Lambda$53/198061478.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl$$Lambda$45/186276003.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/1079803749.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/237061348.run(Unknown Source)
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$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$36/2117255219.run(Unknown Source)
... 1 more
Exception running application test.LibTest
What is it that I am missing? What causes this problem and how do I fix it?
The problem is caused by the compiler (or the VM, I don't know the proper timing) does not know how to create an object of type TestPane.
Note from the error log that it says that the error occurred at D:/WorkspaceDir/ProjectDir/bin/test/LibTest.fxml:11. If we look at the LibTest.fxml, row 11, we see that this is the row that tries to create the TestPane.
The solution to the problem is to add the library file into the build path of the Java project. This will give your project the proper knowledge of how to create an object of type TestPane. Right-click the project -> Build Path -> Configure Build Path... Then, under the Libraries-tab, click Add JARs... (or Add External JARs..., if the .jar file is not located within your workspace) and find your exported .jar file.

Categories

Resources