6 Replies Latest reply: Feb 12, 2013 11:13 PM by 945099 RSS

    Add Class-Path to JAR manifest by JDK 8

    945099
      I use ant task
      <fx:application id="mobibook"
           name="MobiBook QwertoGenerator"
           mainClass="com.qwertovsky.mobibook.generator.Main"
           />
      
      <fx:jar destfile="${jarDir}/mobibook_generator-${git_ver}.jar">
           <fx:application refid="mobibook"/>
           
           <manifest>
                <attribute name="Class-Path" value="${manifest.classpath}" />
                <attribute name="Built-Date" value="${application.build.date}"/> 
                <attribute name="Implementation-Version" value="${git_ver} ${git_date}" />
           </manifest>
       
           <fileset dir="${classesDir}/main" />
      </fx:jar>
      But Class-Path attribute is not added to manifest.

      I try javapackager with -classpath option. It add my path to JavaFX-Class-Path attribute. But it not work.
      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(NativeMethodAccessorImpl.java:57)
           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:751)
      Caused by: java.lang.RuntimeException: Exception in Application start method
           at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:548)
           at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:48)
           at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:134)
           at java.lang.Thread.run(Thread.java:722)
      Caused by: java.lang.NoClassDefFoundError: org/ini4j/InvalidFileFormatException
           at java.lang.Class.getDeclaredConstructors0(Native Method)
           at java.lang.Class.privateGetDeclaredConstructors(Class.java:2437)
           ...............
      I need run
      java -cp "lib/ini4j-0.5.2.jar:mobibook_generator-0.jar" com.javafx.main.Main
      or add Class-Path to manifest.

      What is wrong?

      Edited by: Valery Qwertovsky on 11.02.2013 21:07
        • 1. Re: Add Class-Path to JAR manifest
          jsmith
          I try javapackager with -classpath option. It add my path to JavaFX-Class-Path attribute. But it not work.
          I tried this and it worked for me (jdk7u11 + win7).
          I used an old sample project I created long ago (http://code.google.com/p/willow-browser/) and updated it's build script to use the current directory structure for the jdk+javafx for jdk7u11.
          The created MANIFEST.MF file in the jar ended up as:
          C:\dev\javafx\clone\willow-browser\dist-signed\temp\META-INF>type MANIFEST.MF
          Manifest-Version: 1.0
          Created-By: JavaFX Packager
          Main-Class: com/javafx/main/Main
          JavaFX-Version: 2.2
          JavaFX-Application-Class: org.jewelsea.willow.Willow
          JavaFX-Class-Path: lib/image4j.jar lib/PDFRenderer-0.9.1.jar
          The script I used to package the application (generating the above manifest was):
          rem Windows build script
          
          rem cleanup the output directories
          rd /S /Q out
          rd /S /Q dist
          rd /S /Q dist-signed
          
          rem create the compile output directory
          mkdir out
          
          set JDK_HOME=C:\Program Files\Java\jdk1.7.0_11
          
          rem compile the source
          "%JDK_HOME%\bin\javac"^
           src\main\java\org\jewelsea\willow\*.java^
           -classpath "%JDK_HOME%\jre\lib\jfxrt.jar;lib\*"^
           -d out
          
          rem copy the resources to the output
          xcopy /S src\main\resources\* out\*
          
          rem package the app as a click to run jar
          "%JDK_HOME%\bin\javafxpackager"^
           -createjar^
           -appclass org.jewelsea.willow.Willow^
           -classpath lib/image4j.jar;lib/PDFRenderer-0.9.1.jar^
           -nocss2bin^
           -srcdir out^
           -outdir dist^
           -runtimeversion 2.2^
           -outfile willow.jar^
           -v
          
          rem copy the lib files to the distribution
          mkdir dist\lib
          xcopy /S lib dist\lib
          
          rem use this if you want a self signed app
          "%JDK_HOME%\bin\javafxpackager" -signjar -outdir dist-signed -keyStore keys\willow.jks -storePass willow -alias willow -keypass willow -srcdir dist
          The directory structure of the packaged application binaries is:
          C:\dev\javafx\clone\willow-browser\dist-signed>dir /s *
           Volume in drive C has no label.
           Volume Serial Number is 94A3-EF45
          
           Directory of C:\dev\javafx\clone\willow-browser\dist-signed
          
          02/11/2013  02:31 PM    <DIR>          .
          02/11/2013  02:31 PM    <DIR>          ..
          02/11/2013  01:45 PM    <DIR>          lib
          02/11/2013  01:45 PM           255,469 willow.jar
                         1 File(s)        255,469 bytes
          
           Directory of C:\dev\javafx\clone\willow-browser\dist-signed\lib
          
          02/11/2013  01:45 PM    <DIR>          .
          02/11/2013  01:45 PM    <DIR>          ..
          02/11/2013  01:45 PM            58,013 image4j.jar
          02/11/2013  01:45 PM         2,116,427 PDFRenderer-0.9.1.jar
                         2 File(s)      2,174,440 bytes
          
               Total Files Listed:
                         3 File(s)      2,429,909 bytes
                         5 Dir(s)  126,595,747,840 bytes free
          
          C:\dev\javafx\clone\willow-browser\dist-signed>
          The command I used to run the resulting application was:
          C:\dev\javafx\clone\willow-browser\dist-signed>"\Program Files\Java\jdk1.7.0_11\jre\bin\java.exe" -jar willow.jar
          Note in the above command I do not have to specify the JavaFX runtime location, nor do I need to specify the locations of the jars which my application depends on.

          It's all windows batch files and dos command prompts - how uncool ;-)

          Edited by: jsmith on Feb 11, 2013 3:29 PM

          Change classpath entries input to javafxpackager to use / rather than \ as per EJP's suggestion.
          Compiletime classpath for javac left as is as it works OK during the build on Windows and does not affect packaging output.
          • 2. Re: Add Class-Path to JAR manifest
            EJP
            Items in the Class-Path are relative URLs. They should use forward slashes, not backslashes.
            • 3. Re: Add Class-Path to JAR manifest
              945099
              John, I rebuilt my project with JDK 7u6. It works. And attribute Class-Path was added to manifest beside JavaFX-Class-Path. It works without Class-Path too.

              But when I build with JDK 8(b76), Class-Path attribute is not added. And Jar, that was built with JDK 7 and contains JavaFX-Class-Path, doesn't work.

              What has happened with JDK 8?
              • 4. Re: Add Class-Path to JAR manifest
                jsmith
                What has happened with JDK 8?
                Probably Oracle broke it ;-)

                I'll try a late jdk 8 build out later and see if I can get it to work or otherwise.
                • 5. Re: Add Class-Path to JAR manifest
                  jsmith
                  Yep, I tried jdk 8 and it's broken in this respect - JavaFX programs packaged with the javafxpackager tool don't load classes from the JavaFX-Class-Path entry added to the manifest of the packaged jar by the packaging tool.

                  I suggest you log a jira request against the runtime project at http://javafx-jira.kenai.com.
                  Place a link in the jira back to this forum thread.

                  There is an existing related jira: http://javafx-jira.kenai.com/browse/RT-27054 "Finish implementing changes to JavaFX launcher implementation", which states: "Full launcher feature support, including Class-Path and other manifest entries not currently handled by the launcher", but it is probably a good idea to still log explicit jiras for the issues uncovered in this thread.

                  The generated manifest for the jdk 8 toolset is:
                  C:\dev\javafx\clone\willow-browser\dist\temp\META-INF>type MANIFEST.MF
                  Manifest-Version: 1.0
                  JavaFX-Application-Class: org.jewelsea.willow.Willow
                  JavaFX-Class-Path: lib/image4j.jar lib/PDFRenderer-0.9.1.jar
                  JavaFX-Version: 8.0
                  Main-Class: com/javafx/main/Main
                  Created-By: JavaFX Packager
                  And the batch file I used to generate it (using the same code base as I did for the previous jdk 7 build which worked):
                  rem Windows build script (requires Java JDK 8b76 or later)
                  
                  rem cleanup the output directories
                  rd /S /Q out
                  rd /S /Q dist
                  
                  rem create the compile output directory
                  mkdir out
                  
                  set JDK_HOME=C:\Program Files\Java\jdk1.8.0
                  
                  rem compile the source
                  "%JDK_HOME%\bin\javac"^
                   src\main\java\org\jewelsea\willow\*.java^
                   -classpath "lib\*"^
                   -d out
                  
                  rem copy the resources to the output
                  xcopy /S src\main\resources\* out\*
                  
                  rem package the app as a click to run jar
                  "%JDK_HOME%\bin\javafxpackager"^
                   -createjar^
                   -appclass org.jewelsea.willow.Willow^
                   -classpath lib/image4j.jar;lib/PDFRenderer-0.9.1.jar^
                   -nocss2bin^
                   -srcdir out^
                   -outdir dist^
                   -runtimeversion 8.0^
                   -outfile willow.jar^
                   -v
                  
                  rem copy the lib files to the distribution
                  mkdir dist\lib
                  xcopy /S lib dist\lib
                  When the application is run from the dist directory using java8 with the following command:
                  java -jar willow.jar
                  it fails to find the dependent libs classes (in the above examples this can be checked by trying to open the pdf file file linked from the first web page displayed - jdk7 will display the pdf viewer, but jdk8 will generate a class not found exception).

                  If I instead use a command like below, explicitly setting the classpath and the main class (as you suggest in your question), then the dependent libs are found:
                  java -cp "willow.jar;lib/*" com.javafx.main.Main
                  • 6. Re: Add Class-Path to JAR manifest
                    945099
                    I created bug issue http://javafx-jira.kenai.com/browse/RT-28372 .