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:
Main-Class: LongNameofTheStupidStartupClass
I saved it as "./manifestinfo.txt"
3. So, not having used jar before, I go to a tutorial I find online here
http://java.sun.com/docs/books/tutorial/deployment/jar/modman.html
which reads
"The basic command has this format:
jar cfm jar-file manifest-addition input-file(s)
- 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:
http://java.sun.com/developer/Books/javaprogramming/JAR/basics/update.html
(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/*
and IT WORKS!
But I forgot about the new manifest info... so I type:$ jar umf ./manifestinfo.txt ./jftpd.jar
...and I get this beauty:
java.io.IOException: misplaced continuation line
at java.util.jar.Attributes.read(Attributes.java:374)
at java.util.jar.Manifest.read(Manifest.java:182)
at java.util.jar.Manifest.
at sun.tools.jar.Main.update(Main.java:481)
at sun.tools.jar.Main.run(Main.java:184)
at sun.tools.jar.Main.main(Main.java:1022)
[fcassia@m6810 tmp]$
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
[fcassia@m6810 tmp]$
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).
GRRR
And finally, found this thread
http://forum.java.sun.com/thread.jspa?threadID=549376
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???
http://java.sun.com/docs/books/tutorial/deployment/jar/appman.html
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
following:
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?
-jonnie
==================
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
FC
2 comments:
If you can't type anymore (like you had in the post above), then do a "reset" in your terminal. In the xfce-terminal, this can be done by going to the "Terminal" menu, and then press "Reset".
Thanks for the comment, Karim!. I learn something new about Linux every day, even when I think I know plenty...
I never used the "reset" option and I thought it had to do with sending a conection reset to a Telnet session. :)
So thanks for the heads-up!
FC
Post a Comment