#2082 jstub fails to create an executable jar file

ortizgiraldo Mon 14 Jan 2013

Hi,

I created a simple Fantom class called MyMain with a static main method. I need to deploy and run this class on a server that has no Fantom installed, only the JVM. I'm not allowed to install Fantom there, so I was looking for ways to convert my pod into a runnable jar.

I tried running:

jstub -v -d . MyPod

It created a MyPod.jar file but when I tried to run it using:

java -jar MyPod.jar

I've got:

Error: Invalid or corrupt jarfile MyPod.jar

I opened the file using 7-Zip and found that the expected META-INF folder exists but in lowercase rather than in uppercase. The expected MANIFEST.MF file in it was not named all uppercase either but Manifest.mf instead. Then I created a META-INF folder outside of the jar file and copied the Manifest.mf file in it and renamed this file as MANIFEST.MF.

I noticed also that the Manifest.mf file was missing the Main-Class property, so I added it manually:

Main-Class: fan.MyPod.MyMain

The new MANIFEST.MF file now looks like this:

Manifest-Version: 1.0
Created-By: Fantom Java Stub
Main-Class: fan.MyPod.MyMain

Then I copied the external META-INF folder into MyPod.jar using 7-Zip and ran again:

java -jar MyPod.jar

This time I've got:

Exception in thread "main" java.lang.NullPointerException
      at sun.launcher.LauncherHelper.getMainClassFromJar(Unknown Source)
      at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

My bad. I edited the MANIFEST.MF file again to define the Main-Class property just after the Manifest-Version, like this:

Manifest-Version: 1.0
Main-Class: fan.MyPod.MyMain
Created-By: Fantom Java Stub

This time when I tried to run the jar I've got:

Exception in thread "main" java.lang.NoClassDefFoundError: fan/sys/FanObj
      at java.lang.ClassLoader.defineClass1(Native Method)
      at java.lang.ClassLoader.defineClass(Unknown Source)
      at java.security.SecureClassLoader.defineClass(Unknown Source)
      at java.net.URLClassLoader.defineClass(Unknown Source)
      at java.net.URLClassLoader.access$100(Unknown Source)
      at java.net.URLClassLoader$1.run(Unknown Source)
      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)
      at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: fan.sys.FanObj
      at java.net.URLClassLoader$1.run(Unknown Source)
      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)
      ... 13 more

I looked for sys.jar in my %FAN_HOME%\lib\java and opened it with 7-Zip and copied the fan\sys folder from there into MyPod.jar's fan folder. I copied also the fanx folder from sys.jar into MyPod.jar. Now when I try to run the jar file, I get:

Error: Main method not found in class fan.MyPod.MyMain, please define the main method as:
  public static void main(String[] args)

I had defined the main method of MyMain class just like this:

static Void main() {...}

So I changed it to:

static Void main(Str[] args) {...}

And then compiled it and repeated the entire process described above but with no luck. I'm still getting the last error shown above. I opened and decompiled MyMain.class from MyPod.jar using Java Decompiler and it shows that its main method is defined as:

public static void main(List paramList) {...}

My questions are:

  • Is there any way to get the META-INF\MANIFEST.MF folder and file created all uppercase by jstub and include the Main-Class attribute automatically?
  • Can jstub include all required dependencies in the jar file?
  • Is it possible to get the main() method declared correctly as public static void main(String[] args) {...} instead of using the List paramList parameter?

NOTE:

Java Runtime:
  java.version:    1.7.0
  java.vm.name:    Java HotSpot(TM) Client VM
  java.vm.vendor:  Oracle Corporation
  java.vm.version: 21.0-b17
  java.home:       C:\Program Files\Java\jre7
  fan.platform:    win32-x86
  fan.version:     1.0.63
  fan.env:         sys::BootEnv
  fan.home:        D:\dev\fan

brian Tue 15 Jan 2013

Hi @ortizgiraldo,

The jstub tool is not the right mechanism to create an executable jar file. Rather you need to use the build::JarDist build target. See Java examples

ortizgiraldo Tue 15 Jan 2013

Thanks Brian for pointing me in the right direction. I'll try it soon. However, I still think that at least part of my first question remains valid, since the META-INF and MANIFEST.MF names should be all uppercase, shouldn't they?

brian Tue 15 Jan 2013

jstub is just for compiling - I believe that just used jar tool. The JarDist does create the proper META-INF file in uppercase.

Login or Signup to reply.