0

I have successfully created a Java program that runs fine on my development computer, both in Netbeans and with the .jar file (double clicking). The problem is that it won't start on computers without JDK or without starting via command line with java -jar jarfile.jar (note that it won't start without the -jar flag).

Neither on the development computer the jar file runs without the -jar flag on command line.

The error I'm getting in all the situations where the program doesn't start is the following.

S:\Folder>Program.jar
Exception in thread "main" java.lang.NoClassDefFoundError: S:\Folder\Program/jar
Caused by: java.lang.ClassNotFoundException: S:\Folder\Program.jar
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: S:\Folder\Program.jar. Program will exit.

The file structure of Program.jar looks this:

Program.jar
    binlib
        build.xml
        manifest.mf
        onejar.mf
        one-jar-ant-task.xml
    com
        simontuffs
            onejar
                a lot of classes related to OneJar
    doc
        one-jar-license.txt
    lib
        itextpdf-5.3.3.jar
    main
        main.jar
            my
                package
                    all the classes related to my program
            META-INF
                manifest.mf
            Resources
                all my programs resources
            txt
                more resources
    META-INF
        MANIFEST.MF
    .version
    OneJar.class

The project is compiled with Netbeans and OneJar to get all the required libraries (in this case iText) in the same jar file to help the users - only one file is easier than two files.

The MANIFEST.MF file in the META-INF folder in the root of the jar file contains the following:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: One-Jar 0.97 Ant taskdef
Main-Class: com.simontuffs.onejar.Boot
One-Jar-Main-Class: my.package.MainClass
Class-Path: lib/itextpdf-5.3.3.jar

Note that this is automatically generated by OneJar so I suppose it's right though the real path to the main class also contains /main/main.jar/ if the path is related to the root.

The MANIFEST.MF in the inner jar file (the actual program) is empty. The one in binlib folder contains the following:

Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build
Main-Class: my.package.MainClass

How do I get the jar running?

MikkoP
  • 4,864
  • 16
  • 58
  • 106

3 Answers3

2

The jar files won't run without JDK, because Windows doesn't call java.exe (or javaw.exe) correctly. When the user selects the default program to open jar files, Windows adds the following in the registry:

"Path\To\JRE\Bin\java(w).exe" "%1"

As you can see in the quote, the -jar flag is missing. When you install JDK, it will automatically correct these values.

To fix this, you need a batch script to replace the wrong values. The registry entries that need to be repaired are jarfile, java.exe and javaw.exe.

What I did was to deploy a jarfix.bat with the program with the instructions how to correctly "install" the program.

reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment" /v "CurrentVersion" 1>nul
if errorlevel 1 goto :error

@FOR /F "tokens=2* " %%A IN ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment" /v "CurrentVersion"') DO @SET JAVAVERSION=%%B

reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\%JAVAVERSION%" /v "JavaHome" 1>nul
reg query "HKEY_CURRENT_USER\SOFTWARE\Classes\Applications\java.exe" 1>nul
reg query "HKEY_CURRENT_USER\SOFTWARE\Classes\Applications\javaw.exe" 1>nul
if errorlevel 1 goto :error

@FOR /F "tokens=2* " %%A IN ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\%JAVAVERSION%" /v "JavaHome"') DO @SET JAVAHOME=%%B
@FOR /F "tokens=2* " %%A IN ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\jarfile\shell\open\command" /v ""') DO @SET JAVACOMMAND=%%B
@FOR /F "tokens=2* " %%A IN ('reg query "HKEY_CURRENT_USER\Software\Classes\Applications\java.exe\shell\open\command" /v ""') DO @SET JAVACOMMAND2=%%B

reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\jarfile\shell\open\command" /f /v "" /t REG_SZ /d "\"%JAVAHOME%\bin\javaw.exe\" -jar \"%%1\" %%*"
reg add "HKEY_CURRENT_USER\Software\Classes\Applications\java.exe\shell\open\command" /f /v "" /t REG_SZ /d "\"%JAVAHOME%\bin\java.exe\" -jar \"%%1\" %%*"
reg add "HKEY_CURRENT_USER\Software\Classes\Applications\javaw.exe\shell\open\command" /f /v "" /t REG_SZ /d "\"%JAVAHOME%\bin\javaw.exe\" -jar \"%%1\" %%*"

The program will edit the registry so the program requires administrator privileges. To check them at the program startup, I did the following

NET SESSION >nul 2>&1
if %errorlevel% == 0 (
    echo  User successfully detected as an administrator!
) else (
    echo User doesn't have administrator privileges!
    exit /b 1
)
MikkoP
  • 4,864
  • 16
  • 58
  • 106
1

Java JAR file is just a ZIP with lots of binary classes, not understandable by your CPU or your operating system. In order to run JAR you need Java (JRE is enough, JDK is for developers) that can actually understand and execute the contents of JAR file, main class, etc. Of course it's because Java bytecode is not assembly that your CPU understands - these are instructions that Java VM understand and translates to CPU language.

You might consider converting your JAR file into a Windows executable, have a look at: How can I convert my Java program to an .exe file?

Community
  • 1
  • 1
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
0

A Jar file is just compressed data and it is not an executable. You have to run that with java command which is an executable. This command has an intelligence to open the jar files , read the class files and interpret the byte code, initialize JVM and run the byte code. So without the byte code interpreter command (java) , a jar file useless. So you run the class file in a jar in two ways.

1) java -classpath jarfile MainClass

2) java -jar jarfile (if the jar file's MANIFEST file is having it's main class mentioned )

sakthisundar
  • 3,278
  • 3
  • 16
  • 29
  • I know Java needs JRE to be run. But why doesn't it find the main class? I can't ask user to run programs from command line. – MikkoP Oct 06 '12 at 10:09