To put it simply, I have a different error where Eclipse won't allow me to export the recent version of a JAR. So, I'm trying in command prompt instead.
I'm using JDK 1.8.0.
1) First, I extracted all class files from their individual folders.
2) I created a manifest.txt which contains the following (including a carriage return at the end as described in the oracle tutorial)
Main-Class: Start
3) I'm creating the runnable jar with the following command, being verbose as possible to ensure correct versioning:
C:\correctDirectory\"C:\Program Files\Java\jdk1.8.0\bin\jar.exe" cvfm ERSR.jar manifest.txt *.class
4) That runs fine. I then inspect the JAR to ensure it containts the Start.class file which contains the main method:
C:\correctDirectory\"C:\Program Files\Java\jdk1.8.0\bin\jar.exe" tf ERSR.jar
The output of that is (reduced to useful info):
META-INF/
META-INF/MANIFEST.MF
Start.class
5) Then I run the JAR with the following command:
C:\correctDirectory\"C:\Program Files\Java\jdk1.8.0\bin\java" -jar ERSR.jar
To which I get the error:
Error: Could not find or load main class Start.
Thanks in advance kind folks.
Does your Start class contain any static field that is initialized with a contents of a resource (a .properties file, or alike)?
If that is the case, then it's likely the problem. The command you use in step 3) only packages the .class files into the JAR, but ignores the rest:
...\jar.exe cvfm ERSR.jar manifest.txt *.class
Modify it to include everything:
...\jar.exe cvfm ERSR.jar manifest.txt *
Related
When I create a jar file in a subdirectory, the BouncyCastleProvider class from bcprov-jdk15on-159.jar fails to load with a ClassNotFoundException. I would think that the location where a jar file is created should have no impact on its contents and behavior.
Here is the example of creating a working jar.
$ jar cfm MyProject.jar Manifest.txt Main.class bcprov-jdk15on-159.jar
$ java -jar MyProject.jar
hello provider: BC version 1.59
And here is the example where running jar with exactly the same input files, but a different jar file destination, results in a failing jar.
$ jar cfm dist/MyProject.jar Manifest.txt Main.class bcprov-jdk15on-159.jar
$ java -jar dist/MyProject.jar
Error: Unable to initialize main class Main
Caused by: java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider
This is the file Manifest.txt
Manifest-Version: 1.0
Main-Class: Main
Class-Path: bcprov-jdk15on-159.jar
and this is the Main.java file that uses the BouncyCastleProvider class.
public class Main {
public static void main(String... arg) {
java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
java.security.Provider p = java.security.Security.getProvider("BC");
System.out.println("hello provider: " + p);
}
}
I see this behavior both with JDK 8 and with JDK 9, and also both with the JDK jar command (shown above) and with Ant's jar task.
I stumbled on this problem while trying to upgrade the PCSecrets password manager to work under Java 9.
The reason the above fails is that Java will not load bcprov-jdk15on-159.jar from within the jar file, but from the class path, which seems to differ according the the location of invoked jar. When the generated jar file is in the same directory as bcprov-jdk15on-159.jar, it loads it from the directory and the command invocation works fine. When the generated jar file is in another directory, it fails to load bcprov-jdk15on-159.jar and throws the ClassNotFoundException. Solutions for including a jar within a jar are provided in this question. Interestingly, this answer, upvoted 26 times, is based on the same mistaken assumption.
I found the answer by comparing the binary images of the generated jar files. They seemed to differ only in the timestamps of the META-INF/MANIFEST.MF file. By generating the two files in parallel with the command jar cfm dist/MyProject.jar Manifest.txt Main.class bcprov-jdk15on-159.jar & jar cfm MyProject.jar Manifest.txt Main.class bcprov-jdk15on-159.jar I had two bit-identical jar files that still misbehaved. This prompted me to look at the environment of the two files' execution, rather than the files themselves.
I have a program written in java using Eclipse. For some reason that I won't write here, I decided to move to VS Code. If I run my code in debug mode, all works, but, when I want to export as jar file some errors comes out.
Some information:
- The program is composed by several classes.
- I use 3 external jars included via Eclipse.
- If I run the code with the extension 'Java extension pack - microsoft' all works. Compiling via terminal with
javac MyApp.java
it doesn't compile. (It doesn't find some classes belonging to external jars)
- If I use
jar -cvfm MyApp.jar manifest.txt *.class
where *.class are created by compiling via 'Java extension pack' the error is 'Unable to find or load the main class'
- I'm using a MacBook Pro and the last version of VS Code
What do I do wrong? Which more information you need to help me?
Let's say your project has app package. Under that a App.java class resides which has the main method. Now after building the class files let's assume the class file folder structure is
bin
|app
|App.class
Now go to the bin folder and copy the manifest.txt file in bin folder. manifest.txt file must contain Main-Class . here app.App is the name of the Main-Class.
Main-Class: app.App
Note manifest.txt file must be ended with a new line or carriage return . After Main-Class: app.App put a new line at least.Now run this command from the bin folder
jar cfmv App.jar manifest.txt app/
then test the Jar with
java -jar App.jar
I'm learning Java and I have a problem. I created 6 different classes, each has it's own main() method. I want to create executable .jar for each class, that is 6 executable .jar files.
So far I tried
java -jar cf myJar.jar myClass.class
and I get 'Unable to access jarfile cf'. I'm doing something wrong but I don't know what. I'm also using Eclipse IDE if that means something.
In order to create a .jar file, you need to use jar instead of java:
jar cf myJar.jar myClass.class
Additionally, if you want to make it executable, you need to indicate an entry point (i.e., a class with public static void main(String[] args)) for your application. This is usually accomplished by creating a manifest file that contains the Main-Class header (e.g., Main-Class: myClass).
However, as Mark Peters pointed out, with JDK 6, you can use the e option to define the entry point:
jar cfe myJar.jar myClass myClass.class
Finally, you can execute it:
java -jar myJar.jar
See also
Creating a JAR File
Setting an Application's Entry Point with the JAR Tool
Sine you've mentioned you're using Eclipse... Eclipse can create the JARs for you, so long as you've run each class that has a main once. Right-click the project and click Export, then select "Runnable JAR file" under the Java folder. Select the class name in the launch configuration, choose a place to save the jar, and make a decision how to handle libraries if necessary. Click finish, wipe hands on pants.
Often you need to put more into the manifest than what you get with the -e switch, and in that case, the syntax is:
jar -cvfm myJar.jar myManifest.txt myApp.class
Which reads: "create verbose jarFilename manifestFilename", followed by the files you want to include.
Note that the name of the manifest file you supply can be anything, as jar will automatically rename it and put it into the right place within the jar file.
way 1 :
Let we have java file test.java which contains main class testa
now first we compile our java file simply as javac test.java
we create file manifest.txt in same directory and we write Main-Class: mainclassname . e.g :
Main-Class: testa
then we create jar file by this command :
jar cvfm anyname.jar manifest.txt testa.class
then we run jar file by this command : java -jar anyname.jar
way 2 :
Let we have one package named one and every class are inside it.
then we create jar file by this command :
jar cf anyname.jar one
then we open manifest.txt inside directory META-INF in anyname.jar file and write
Main-Class: one.mainclassname
in third line., then we run jar file by this command :
java -jar anyname.jar
to make jar file having more than one class file : jar cf anyname.jar one.class two.class three.class......
Put all the 6 classes to 6 different projects. Then create jar files of all the 6 projects. In this manner you will get 6 executable jar files.
I have created my JAR on Windows 2000 having java version 1.5 which contains following directories/files:
manifest.txt
com
lib
lib contains all JARS which I want to make part of my JAR. com contains my class files and below is manfiest.txt file
Main-Class: com.as.qst.result.ResultTriggerSchedular
Class-Path: lib/axis.jar lib/c3p0-0.9.1.1.jar lib/commons-discovery-0.2.jar lib/commons-logging-1.0.4.jar lib/jaxrpc.jar lib/log4j-1.2.16.jar lib/medplus-hub-8.2-wsclients.jar lib/medplus-hub-13.1-jaxws-clients.jar lib/quartz-2.2.1.jar lib/quartz-jobs-2.2.1.jar lib/saaj.jar lib/slf4j-api-1.6.6.jar lib/slf4j-log4j12-1.6.6.jar lib/ wsdl4j-1.5.1.jar lib/xercesImpl.jar com\as\qst\result
I used following command to generate my JAR
jar cvfm test.jar manifest.txt com lib
It has successfully created a JAR file but when I try to run it with
java -jar test.jar
it does not execute and throws above exception. I used the same process for Windows 7 which has version 1.7 and it did work out even without class files path in manifest.txt com\as\qst\result. Is something more to do with class-path besides defining in manifest? and why is it working in Windows 7?
You do not need the class file path in your class path entry. So instead of adding com\as\qst\result to your class-path.
More over you must not package other jar files in your runnable jar.
Other required jars must be provided in the same folder as your jar file (may be in separate folder) and Add current directory "." (without quotes) to your class-path.
Hope this helps.
EDIT
Just found this Stackoverflow Link. This might give you more insight. Please read through it.
I'm learning Java and I have a problem. I created 6 different classes, each has it's own main() method. I want to create executable .jar for each class, that is 6 executable .jar files.
So far I tried
java -jar cf myJar.jar myClass.class
and I get 'Unable to access jarfile cf'. I'm doing something wrong but I don't know what. I'm also using Eclipse IDE if that means something.
In order to create a .jar file, you need to use jar instead of java:
jar cf myJar.jar myClass.class
Additionally, if you want to make it executable, you need to indicate an entry point (i.e., a class with public static void main(String[] args)) for your application. This is usually accomplished by creating a manifest file that contains the Main-Class header (e.g., Main-Class: myClass).
However, as Mark Peters pointed out, with JDK 6, you can use the e option to define the entry point:
jar cfe myJar.jar myClass myClass.class
Finally, you can execute it:
java -jar myJar.jar
See also
Creating a JAR File
Setting an Application's Entry Point with the JAR Tool
Sine you've mentioned you're using Eclipse... Eclipse can create the JARs for you, so long as you've run each class that has a main once. Right-click the project and click Export, then select "Runnable JAR file" under the Java folder. Select the class name in the launch configuration, choose a place to save the jar, and make a decision how to handle libraries if necessary. Click finish, wipe hands on pants.
Often you need to put more into the manifest than what you get with the -e switch, and in that case, the syntax is:
jar -cvfm myJar.jar myManifest.txt myApp.class
Which reads: "create verbose jarFilename manifestFilename", followed by the files you want to include.
Note that the name of the manifest file you supply can be anything, as jar will automatically rename it and put it into the right place within the jar file.
way 1 :
Let we have java file test.java which contains main class testa
now first we compile our java file simply as javac test.java
we create file manifest.txt in same directory and we write Main-Class: mainclassname . e.g :
Main-Class: testa
then we create jar file by this command :
jar cvfm anyname.jar manifest.txt testa.class
then we run jar file by this command : java -jar anyname.jar
way 2 :
Let we have one package named one and every class are inside it.
then we create jar file by this command :
jar cf anyname.jar one
then we open manifest.txt inside directory META-INF in anyname.jar file and write
Main-Class: one.mainclassname
in third line., then we run jar file by this command :
java -jar anyname.jar
to make jar file having more than one class file : jar cf anyname.jar one.class two.class three.class......
Put all the 6 classes to 6 different projects. Then create jar files of all the 6 projects. In this manner you will get 6 executable jar files.