4

I have a program I want to be able to be installed easily by any user, and I thought creating a native installer was the way to go. I used Netbeans 8.0's functionalities (Project properties > Enable native packaging, and Package as). I was able to create a working native installer. After installation, I have the following file tree:

+-- Project
    \+-- app
         \+--lib (containing all the jars used by the project)
         \---Project.jar
         \---package.cfg
    \+--runtime
        \+--jre (contains the current jre)
    \---Project.exe

Executing the program from Project.jar works. However, when I try to launch Project.exe, I get the following error message on a window pop-up with no details whatsoever:

Failed due to exception from main class

To identify the source of the problem, I have used basic standard outputs and redirected them into a file thanks to the Windows command prompt. I got outputs until the first call to an external library. So it seems the library linking is not done. However, here's the content of my package.cfg file:

app.mainjar=Project.jar
app.mainclass=project/Main
app.classpath=lib/firstlibrary.jar lib/secondlibrary.jar 

The classpath is specified but does not seem to be recognized. I have tried inverting the slash (\) and changing whitespaces for , or ; to no avail.

There is an easy way to reproduce the bug (Netbeans 8.0 and JDK 1.8u11):

  • Create a new Java project in Netbeans
  • Link any external library (.jar): right click on Libraries > Add jar/folder
  • In the main method, instantiate an object referencing that library.
  • Right click on the project's name > Properties > Deployment > Enable Native Packaging actions in project menu
  • Right click on your project > Package as > EXE installer
  • After build, go to the directory where the installer has been created, and launch the installer.
  • At the end of the installation, go to the installation directory, and start the .exe. The error should occur.

Any idea how to fix this?

Koln
  • 307
  • 1
  • 4
  • 11
  • Can you provide the complete output for the **library linking is not done**? – Jean Waghetti Aug 15 '14 at 21:19
  • The outputs correspond to calls to System.out.println(). Since there were no details on the error message, I had to debug somehow. Obviously when you launch the exe, it won't print the messages anywhere. So I redirected stdout in a file using ``>`` operator, and got print messages until an object using an external library was instantiated. – Koln Aug 16 '14 at 00:01
  • Can anyone confirm this bug happens on their machine? – Koln Aug 18 '14 at 09:59
  • Hi @Koln, could you please explain how you did this "To identify the source of the problem, I have used basic standard outputs and redirected them into a file thanks to the Windows command prompt". I don't see anything at command line, and would like to trace a similar problem – ZiglioUK Jun 14 '15 at 21:39
  • @ZiglioNZ It is all explained in the previous comment. I added a good deal of `System.out.println()` where I knew the bug had good chances to occur, launched my exe through the terminal and redirected the output. Something like `file.exe > mystacktrace.txt` – Koln Jun 15 '15 at 07:11
  • Thanks @koln, I've figured it out: you can run the executable using a /Debug option, that prints out an exception stack trace. When the exception goes away, the output is printed out and can be piped to a file as you suggested – ZiglioUK Jun 15 '15 at 07:22
  • @Koln Can we configure the build somehow so that `file.exe` renders its output to the stdout? I have found scarce info on this subject and can't imagine why the stdout would be suppressed in the first place? EDIT: I'll answer myself as this hasn't been covered anywhere so far. The short answer is: no and, I am almost certain that will never will be supported. The reason is the resulting exe file is specified as a non-console application during linking. The only way to get stdout is by redirection to file. – quantum Jan 18 '16 at 21:52

3 Answers3

2

I just had a similar issue with a native-packaged JavaFX application where I was getting the "Failed due to exception from main class" error. My package.cfg looked the same as yours.

What I did to diagnose it was just to manually run the jar file (e.g. Project.jar) from the command line and see what the stacktrace was, e.g. if your Main class was in org.project.Project

java -cp Project.jar org.project.Project

Turns out for me that the URLs I had been using to load various files (e.g. the FXML files for JavaFX) packaged in the jar were causing issues - I was using relative URLs (e.g. "./blah.ext" or "../foo.txt" etc), but once I had changed the URLs to be absolute based on how the files were laid out in the jar it worked fine (e.g. "/org/project/blah.ext" and "/org/foo.txt").

matt1
  • 1,175
  • 7
  • 14
2

Same problem here, using these:

  • Java SE Version 8 Update 31 (build 1.8.0_31-b13)
  • NetBeans 8.0.2 (Patch 1)
  • Windows 7 Enterprise SP1 on Intel Core i7 (64-bit)
  • Inno Setup Compiler 5.5.5 (u) - Unicode

I also traced output by redirecting printlns, and it blew up the first time it called for an external library. I thought maybe I had the same problem as matt1 so I fixed all the relative paths, but no joy. I finally figured out that the installer was not creating the /app/lib folder with the external jar files. After manually copying the lib folder to the target installation folder it worked fine, even on a machine with no JRE installed (I'm working on a self-contained app).

The fix was to add a line to the build.xml:

   <target name="-post-jfx-deploy">
   <fx:deploy width="${javafx.run.width}" height="${javafx.run.height}" 
             nativeBundles="all"
             outdir="${basedir}/${dist.dir}" outfile="${application.title}">
      <fx:application name="${application.title}" mainClass="${javafx.main.class}"/>
      <fx:resources>
          <fx:fileset dir="${basedir}/${dist.dir}" includes="*.jar"/>
          <!--below is the magic bit that copies all the dependency jar files to the native package output-->
          <fx:fileset dir="${basedir}/${dist.dir}" includes="lib/*.jar"/>
      </fx:resources>
      <fx:info title="MyApp" vendor="MyVendor"/>
  </fx:deploy>          
</target>

The second fileset directive forces a copy of the jar dependencies from the lib folder, which fixed everything when deploying either as an EXE or an MSI.

TxF
  • 61
  • 4
  • hi @TxF, could you please explain how you did this "I also traced output by redirecting printlns'? Thanks! – ZiglioUK Jun 14 '15 at 21:40
  • I see, one only needs to call from the command line with redirection >, well it only outputs to a file, which is slightly inconvenient. Also I can't see any exception stack trace, perhaps I need to redirect stderr somehow – ZiglioUK Jun 14 '15 at 22:01
  • Yeah, but it's better than getting nothing. :) You can always do a "e.printStackTrace();" inside a catch block that pushes the output to standard out, which should end up in the redirection file (you could force an error condition if needed). – TxF Jun 16 '15 at 12:49
  • Thank you, I've discovered how to print the exception stack trace: >executable /Debug – ZiglioUK Jun 16 '15 at 12:52
0

I thinks your main class is not correctly set to package. Instead of using Netbeans you can make exe from your jar file using exe4J.(please make sure main class is set from project > properties > run > main class

download exe4J from here

Harsha
  • 377
  • 1
  • 8
  • 21