Updating jar manifest file - java.io.IOException: invalid manifest format - java

I need to update the manifest in my jar file that I create (export) within Eclipse. I've tried to follow this explanation without success. I'm not quite sure what to specify on the command line. The Oracle web site is not too clear. I then found a post on SO that said to extract the manifest.mf file from the jar archive, update it, and add it back to the jar archive. I've tried that too, and it appears to work, however, at runtime, I get java.io.IOException: invalid manifest format. What is the correct way to update the manifest.mf to add new attributes? An example would be most helpful.

As manifest file is contained in META-INF subdirectory of jar file under the name MANIFEST.MF .Whenever you create a jar file for command prompt by the command
jar cvf Jarfilename FilesToadd
Then a default manifest file is created.
One can view this file and get an idea of valid Manifestfile.
In order to extract manifest file from jar type following command in cmd
jar xvf Jarfilename now a META-INF subdirectory will appear in the base directory from here you can view default manifest file.
Sometimes while updating manifest file we get java.io.IOException: invalid manifest format.This error comes because of following reasons:
1.You may have not left space between the name and value of any section in manifest file,
like Version:1.1 is inavalid section instead write Version: 1.1 that space between colon and 1.1 really matters a lot.
2.While specifying the main class you might have added .class extension at the end of class name.Simply specify the main class by typing Main-Class: Classname.
3.You may have not added newline at the end of file.You need not to write \n for specifying newline instead just leave the last line of your manifest file blank that will serve the purpose
4.Your text file for manifest must use UTF-8 encoding otherwise you may get into some trouble.
Finally i am providing an example of what a manifest file must look like.
Here package is calculator and the main class is Calculator.java
Manifest-Version: 2.1
Created-By: UselessCoder
Package-Name: calculator
Class-Name: calculator.Calculator.java
Main-Class: calculator.Calculator

The links offered by Peter were partially useful. However, I was able to solve this more or less by trial and error. The Oracle docs that explain how to do this need lots of work. They lack a good example of how to proceed. Anyway, for those who run into the same issues, here's what I did. I created a text file (eg. "Manifest.txt") using Notepad that contains the manifest attributes I wanted to add/update. In creating this file, I made sure to add a new line character to the last line by pressing the key on the keyboard. Next, I created a DOS bat file to do the actual modification. Here's what it looked like...
echo Updating manifest permissions...
"C:\Program Files\Java\jdk1.7.0_25\bin\jar" -umf "c:\some folder\Manifest.txt" "C:\some folder\jartoupdate.jar"
The order of the jar arguments as they relate to the actual paths that follow on the command line is important. The links from Peter's reply pointed that part out.

java.io.IOException: invalid manifest format error is also thrown when,
unwanted empty lines are present in manifest file.
For example:
Before manifest.txt
Manifest-Version: 1.0
Main-Class: Sample
After manifest.txt
Manifest-Version: 1.0
Main-Class: Sample

When modifying the contens of a jar you should more look into this direction:
http://docs.oracle.com/javase/tutorial/deployment/jar/update.html and especially
http://docs.oracle.com/javase/tutorial/deployment/jar/modman.html which describes the process of updating the manifest.

To update a manifest in a jar file, you found the answer in the oracle docs. Here is another place to see the answer. Assuming you have read access to the directory where the JDK is installed and the documentation was downloaded with it (easy to download the documentation, this is for SE7 http://www.oracle.com/technetwork/java/javase/documentation/java-se-7-doc-download-435117.html):
go to the [install_directory]/docs. In there is an index.html file.
>>>> e.g. mine for JDK 6 is called C:\my_TOOLS\Java_stuff\jdk_1.6.0_20\docs\index.html
Drag index.html onto a browser page.
That page shows you an overview of the JDK documentation and has many links to useful information.
In the top box's row under the Java Language row, click on JAR. It takes you to the page summarizing the documentation (with links) of the jartool.
In the "JAR Tools" section of that page, click on the reference page link for your platform (you probably want "JAR tool reference page for Windows").
That "JAR tool reference page" shows you the detailed documentation for the jar command. This is where you'll see the example "jar umf Manifest.txt my_jar.jar". (Solaris/Linux doesn't use the "-" in front of the args such as "umf".
I used it (on Linux) to merge 2 custom Manifest files into the default Manifest and put it in my jar. I do it in a two-step process but would be interested to know of a one-step command to do this. (Using two m's to the jar command causes the second manifest to overwrite the first manifest - not merged.)(Remember each manifest file must end with a blank line.)
Manifest.txt contains "Name: " and "Implementation-Version: "
Manifest.my_app.txt contains "Main-Class: " and "Class-Path: "
The default manifest contains "Manifest-Version: " and "Created-By: "
jar cmf my_app.jar Manifest.txt my_main.class my_utils.class
jar umf Manifest.my_app.txt my_app.jar
After this, my META-INF/MANIFEST.MF contains all the fields from all 3 manifests. I expected them to be appended one to another but the fields are jumbled together. Maybe someone can tell how to order them or straight append. This is the order in which they appear in my current META-INF/MANIFEST.MF.
Manifest-Version: 1.0
Implementation-Title: my_app
Implementation-Version: 1.2.1
Class-Path: ...
Name: My App
Created-By: 1.6.0_20 (Oracle Corporation)
Main-Class: My_App
I hope some of this is useful for you.

Related

Package structure and jar file with manifest

Let's say I have the following "project" structure.
*Root/
- manifest.txt
+ com/
+ mypackage/
+ example/
- MyClass.java
- MyClass.class
I know from the docs.oracle.com documentation that the manifest file must be written in the UTF-8 character set and that there must be a space after each colon, and a carriage return ('\r') or a new line ('\n') before save file.
/* ** MANIFEST.TXT ** */
Manifest-Version: 1.0
Class-Path: .
Main-Class: com.mypackage.example.MyClass
/* ** END OF MANIFEST ** */
Creating an executable .jar file using cmd from the root directory.
CMD:
jar -cvfm out.jar manifest.txt com/mypackage/example/*.class
OUTPUT from CMD:
added manifest
adding: com/mypackage/example/MyClass.class(in = 648) (out= 445)(deflated 31%)
Now I'm trying to run the newly created jar file from the root directory:
java -jar out.jar
OUTPUT from CMD:
Error: Could not find or load main class com.mypackage.example.MyClass
I can't get to the goal despite the last problem. What am I doing wrong??? Thank You.
Here is a screenshot of the screen and cmd.:
As you described it, you will get a running jar, and therefore, what you described is not an accurate representation of what you did.
A few steps to check:
Did you paste the complete error message? For example, maybe the error message includes the note Caused by: java.lang.NoClassDefFoundError: MyClass (wrong name: com/mypackage/MyClass) or something along that vein. Then the problem is: Your MyClass.java needs to start with package com.mypackage.example;, it needs to contain class MyClass with that exact casing, and it needs to be called MyClass.java with that exact casing.
Did you actually do all the steps exactly as you laid out in your question? I did, and it works fine. This isn't one of those 'works on one machine and may not work on another' kind of scenarios, which is why I conclude you didn't. For example, if you include just MyClass.class and not com/mypackage/example/MyClass.class (i.e. you run the jar command from something that isn't the directory containing the com directory), you'd get this problem.
NB: 99% of folks building java jars use a build system to do so, such as maven or gradle.
Class-Path: com.mypackage.examples
Main-Class:My class
On Unix don't forget to set the .jar executable permission.
And alternate with no manifest.
Java -cp thejar.jar com.mypackage.examples
Don't forget the main class must have a
public static void main(String args[])
method to start the class.

eclipse does not add classpath to manifest file

I have some dependencies that I need to specify in the manifest. So I created a manifest file manually and when doing that I exported my selected files and do next >> next and then choose "use existing manifest from file". this is the manifest I have locally:
Manifest-Version: 1.0
Main-Class: com.placeholder.ProcessServer
Class-Path: . ProcessServer_lib/commons-net-3.3.jar ProcessServer_lib/
com.ibm.mq.headers.jar ProcessServer_lib/db2jcc.jar ProcessServer_lib
/db2jcc_license_cu.jar ProcessServer_lib/db2jcc_license_cisuz.jar Pro
cessServer_lib/com.ibm.mq.jar ProcessServer_lib/com.ibm.mq.commonserv
ices.jar ProcessServer_lib/connector.jar ProcessServer_lib/com.ibm.mq
.jmqi.jar ProcessServer_lib/log4j-1.2.17.jar
I placed the jar in my unix box and invoke it via a shell script using -jar however it gives me a classdef not found exception. Upon seeing the jar generated via decomplier/zip utility I can see the manifest only contains the main-Class line not the class-path.
While exporting the jar should I unselect the buildpath that comes in the right hand box selection ?
I'm doing these deployment works for the first time, but I have tried for 1 day using -cp to specify jar folder and main class but I still haven't found a way. Could somebody help me or give me advice?
p.s. I don't use maven/ant so no need to advice me on that.
There's a bug in Eclipse where it won't export the last line of your manifest if you don't leave a trailing newline.
Export your project using the export to runnable jar of Eclipse and remeber to choose between these :
Extract required libraries into generated JAR : to inflate the referenced jar files and copy the classes into the generated jar
Package required libraries into generated JAR : to copy the referenced jar files as is into the generated jar
Copy required libraries into a sub-folder next to the generated JAR
See here

How to package required external libraries AND sources in Eclipse

I have an issue that is really annoying right now.
For a school project (that is due on monday :( ), I have to submit a .JAR file that is a stand alone app and that includes sources.
However, in Eclipse, I didn't find how to export the sources and at the same time, include the required libraries.
My BuildPath is set up this way :
http://image.noelshack.com/fichiers/2014/19/1399746312-owp08.png
When I do :
Export as a runnable JAR file, everything works in my program but I don't have the sources inside the JAR
Export as a JAR File, I can add my sources, but when i try to run the JAR file, I have this exception :
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
Here are my settings :
http://image.noelshack.com/fichiers/2014/19/1399746469-sans-titre.png
I really don't know what to do, I've been searching for hours now, can someone help me ?
Thank you in advance.
Regards,
Azsde.
Well, the short answer is that eclipse doesn't support doing that directly. This is why most people use other tools such as Ant or Maven in their projects, rather than relying on the IDE.
You can work around eclipse's lack of an export source option in the runnable jar export wizard in one of two ways:
You can create a runnable jar and then manually add your source files to it
You can create a normal jar which includes your source files and add a MANIFEST.MF file to it.
Adding source files manually
This is what I would normally consider a terrible option, but since this is a homework assignment, there are two mitigating factors:
this is a one-off
you are short on time
If you have neither the time nor inclination to learn the details about manifests, I would recommend this option.
Adding your own MANIFEST.MF
As you may have noticed, even when you select the option to have eclipse generate your manifest in the export wizard, your jar file won't actually run. If you open up the 'normal' jar file and look at the generated manifest file it will look something like this (for a simple HelloWorld program using one third party library):
Manifest-Version: 1.0
Main-Class: HelloWorld
Whereas if you open up the manifest file for an exported runnable jar it will look something more like this (for the same program):
Manifest-Version: 1.0
Rsrc-Class-Path: ./ commons-lang3-3.3.1.jar
Class-Path: .
Rsrc-Main-Class: HelloWorld
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
As you can see, the generated manifest file is failing to include support for third party libraries.
What you would need to do in this case is write your own manifest file and keep it as a resource in your project. Then do a normal jar export, and on the last page of the wizard select the Use existing manifest from workspace option, and point it at your own manifest file.
This will have the advantage that you can export a new runnable jar whenever you like, including your source files, and without requiring manual tinkering each time.
If you're interested in working with manifest files, there's a good tutorial on oracle's website here that can help you get started:
http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html

NoClassDefFoundError for a packaged class

I'm trying to run a jar file that uses the YouTube Data API and I'm getting a NoClassDefFoundError for one of the API classes:
alt text http://img205.imageshack.us/img205/1808/noclassdeffounderror.png
AuthenticationException.class is found in the gdata-core-1.0 jar:
alt text http://img683.imageshack.us/img683/7329/authenticationexception.png
The gdata-core-1.0 jar has been added to my classpath:
alt text http://img24.imageshack.us/img24/2195/classpathe.png
What am I doing wrong?
Perhaps you may not be having the jar in the classpath. The command prompt execution does not set the classpath. You will have to either do it by yourselves or give it on the fly while executing.
You should probably take a look at setting the MANIFEST file correct for the JAR file.
This post has a better description

How to set classpath in manifest file , while creating JAR from eclipse?

I am trying to creat JAR file through eclipse. I read some of the threads from
stackoverflow as well as other forums. But nothing is helping.
I have created a separate manifest file like this one.
Manifest-Version: 1.0
Main-Class: Main
Class-Path: gnujaxp.jar iText-2.1.5.jar jcalendar.jar jcommon-1.0.16.jar jfreechart-1.0.13.jar jfreechart-1.0.13-experimental.jar jfreechart-1.0.13-swt.jar junit.jar servlet.jar swtgraphics2d.jar tinyos.jar
I have put all this jars in same project folder.
While exporting i am exporting all resources (meants this jar files also.)
But still i am getting noclassdeffound error when my application tries to load any one of the jar included.
M i wrong anywhere ..
Thanks in advance.
If you are using eclipse >=3.4 try "export as runnable jar file" it should generate it correctly.
Otherwhise you can provide your own manifest file in the export as jar dialog.
I get this error and find that my manifest needs a space after the jars in the class-path. This includes the ones at the end of the line and end of list, otherwise it mashes them together.
Be sure to add an empty line at the end of your Manifest file.

Categories