Instead of the old adage "Life's a bitch, and then you die" I propose a new version: "JAR is a bitch, and then you die".
In case you're living in a bottle or you're not a geek, JAR is the Java JDK tool used to build the compressed ".JAR" (Java Archive) files that contain a Java software application (all the different binary files inside it). It's a tiny command line application just like everything in the JDK that should be no different or more complex to use than ZIP or tar.
However, it proved to be a real pain in the ass and a TIME WASTING EXERCISE, just to update a SINGLE TEXT LINE inside an existing .jar file's "Manifest".
1. What I wanted to do:
Unpack an existing application,
update its MANIFEST file, to include the "Main-Class: ClassnameHere" statement, so I could just start the application by typing
java -jar applicationname.jar
instead of using the author's ancient approach of having to name the "Main-Class" on the command-line every time...
java -classpath applicationname.jar LongNameofTheStupidStartupClass
2. I unpacked the existing application's .jar file just fine with 'unzip', and created a text file with my favorite text editor which read:
I saved it as "./manifestinfo.txt"
3. So, not having used jar before, I go to a tutorial I find online here
- The c option indicates that you want to create a JAR file.
- The m option indicates that you want to merge information from an existing file into the manifest file of the JAR file you're creating."
...and thinking I know what I'm doing, I type:
$ jar -c jftpd.jar ./manifestinfo.txt ./ ./ftpserver/*
I get this as a result:
4. I had to close the terminal as I couldn't type anymore (I could type but I couldn't understand anything).
Then I found what I think is a more friendly explanation on how to update the "Manifest" of the .JAR file with new info, over HERE:
(Later I realize that what happened in Step#3 was that I forgot to include the "f" parameter to indicate that I wanted output to a file rather than to STANDARD OUTPUT. What the **** is the purpose of having output of JAR to standard output?? I don't get it).
5. So I type
jar cf jftpd.jar ftpserver/*But I forgot about the new manifest info... so I type:
and IT WORKS!
$ jar umf ./manifestinfo.txt ./jftpd.jar
...and I get this beauty:
java.io.IOException: misplaced continuation line
WHAT THE F#CK IS GOING ON NOW????????
6. You know what was the problem? the file "manifestinfo.txt" had TWO BLANK SPACES before the text "Main-Class: ..." and TWO BLANK LINES below it !! (I pressed [Enter] twice).
Apparently, JAR FREAKS OUT (this is JAVA 6.0 update 2 JDK's JAR, for crying out loud!).
7. I removed the two leading spaces and trailing blank lines and guess what? IT WORKED!.
[fcassia@m6810 tmp]$ jar umf ./manifestinfo.txt ./jftpd.jar
8. Done.... BASTARDS!!
9. Another Golden Rule when dealing with JAR:
JAR NAME APPARENTLY ALWAYS GOES LAST.
So, contradicting what would be the 'zip' usage of "hey zip, I want to update THIS ZIPFILE with THIS_DATA" (zip something.zip newfile.txt) in JAR is totally the opposite way: "hey JAR, I want THIS NEW FILE into THISJAR" (jar umf newdata ./intothisjar.jar).
And finally, found this thread
See comment #11:
FINICKY? That's being mercyful...
and then comment #15:
"One diference between unix and windows' file system is that text files in unix always have a final linebreak at the end of the file, while windows doesn't need to.
Java, being developed by Sun primarily for the unix comunity requires that the
manifest file ends with a new-line.
no new-line, no manifest file."
Want more? See the comments on page #2 of the above thread at Sun.com, discussing the "joys" of the "jar" command:
Does this instruction really work???
They specify the following command:
jar cmf MyJar.jar Manifest.txt MyPackage/*.class
When I tried that with my classes and files (with different names, of
course), it didn't work. What worked for me is equivalent to the
jar cmf Manifest.txt MyJar.jar MyPackage/*.class
The order is simply permuted. Maybe it's just Apple's Java
implementation. Is this what you were asking about?
The Tutorial is wrong. It should be jar cfm, not cmf.
The order of the command must match the order of the parameters.
Thank you. That is good to know.
I REST MY CASE:
JAR IS A BITCH, AND THEN YOU DIE