I'm having an issue with wsgen and while I've seen some answers that worked none of those solutions seems to be working for me. I believe the problem is related to the structure of the source and binaries.
My WSTest project is setup with the following folders:
bin
└───com
└───example
└───ws
src
└───com
└───example
└───ws
The main class is Test which resides in package com.example.ws.
I'm running wsgen from the main project folder WSTest using the following command:
wsgen -cp ./bin/com/example/ws -d ./src/com/example/ws -s ./src/com/example/ws Test
This results in:
Exception in thread "main" java.lang.NoClassDefFoundError (wrong name: com/example/ws/Test)
This makes sense since the class is part of a package. So I change my command to the following:
wsgen -cp ./bin/com/example/ws -d ./src/com/example/ws -s ./src/com/example/ws com.example.ws.Test
But now I get class not found from the wsgen tool:
Class not found: "com.example.ws.Test"
Usage: WSGEN [options]
What am I missing?
Have you tried something like this?
wsgen -cp ./bin -d ./src -s ./src com.example.ws.Test
The classpath folder is were wsgen looks for class files. The package within the class is resolved to folder paths, so com.example.ws.Test should be a file like com/example/ws/Test.class within the bin classpath folder.
From the Java documentation:
Each classpath should end with a filename or directory depending on what you are setting the class path to:
For a .jar or .zip file that contains .class files, the class path ends with the name of the .zip or .jar file.
For .class files in an unnamed package, the class path ends with the directory that contains the .class files.
For .class files in a named package, the class path ends with the directory that contains the "root" package (the first package in the full package name).
Related
After converting my java program to executable jar file using commands in command prompt in windows 10,while executing jar file I am getting error:
Could find or load main class Combine.class" caused
by:java.lang.ClassNotFoundException:Combine.class
My jdk-11.0.1 has javamail api and excelapi.While executing I have set my classpath as:
classpath=%classpath%;C:\Program Files\Java\jdk-11.0.1\javamail_api\javax.mail-1.6.2.jar;C:\Program Files\Java\jdk-11.0.1\javamail_api\activation.jar;C:\Program Files\Java\jdk-11.0.1\jexcelapi\jxl.jar;.;
It was compiling and executing properly but after converting to executable jar file it is not running and giving above error.
Any help would be appreciated.
Thank you
The clue is in the exception message. It is trying to load a class with the name Combine.class. But the classes real name is Combine.
You have created the JAR file incorrectly.
echo Main-Class: Combine.class > manifest.txt
jar cmf manifest.txt FinalExecutable.jar Combine.class
If Combine is in the default package (i.e. it doesn't have a package statement) then the above should be:
echo Main-Class: Combine > manifest.txt
jar cmf manifest.txt FinalExecutable.jar Combine.class
If Combine is declared in package foo.bar, then the above should be.
echo Main-Class: foo.bar.Combine > manifest.txt
jar cmf manifest.txt FinalExecutable.jar foo/bar/Combine.class
and you need to be in the directory above the foo directory.
NB: the "Main-Class" attribute in the manifest must be a Java fully qualified class name, NOT a filename or file pathname.
It also should be noted that the CLASSPATH environment variable and the -cp argument will be ignored when you run a JAR using java -jar .... If your executable JAR depends on other JAR files, you should either combine them (to create a shaded JAR) or you should add a "Class-Path" attribute to the manifest; see https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
Finally, my advice would be to use a build tool (e.g. Maven) to compile your code, create the executable JAR file, etc rather than doing it by hand.
I'm trying to create a jar file and run it using java -cp main.jar com.test.Foo.Main but I keep getting:
Error: Could not find or load main class com.test.Foo.Main
Caused by: java.lang.ClassNotFoundException: com.test.Foo.Main
This is my file structure. So I'm thinking the line in my Main.java should be package com.test.Foo correct?
I'm compiling my Main.java with javac Main.java which outputs a Main.class file. Afterward, I create a jar file using jar cfm main.jar META-INF/MANIFEST.MF Main.class and finally while I'm in the same directory as the jar file <root>/src/com/test/Foo/ I run java -cp main.jar com.test.Foo.Main and that's when I run into the above error. Any idea how I can run this file like this (and yes I need it to run with this command specifically)?
Main.java
package com.test.Foo;
public class Main {
public static void main (String args[]) {
System.out.println("I am com.test.Foo.Main");
}
}
META-INF/MANIFEST.MF
Manifest-Version: 1.0
Main-Class: com.test.Foo.Main
I tried using some of the options given in this popular SO question and nothing helped.
The picture you're showing in your question is your project structure not your jar structure.
When you create a jar file, the structure for that jar file might be
different with your source code folder structure.
Every IDE (such as eclipse, netbeans, IntelliJ) has a mechanism for creating JAR files. In your case when you open the created jar file (using zip apps like winrar) you should see something like this :
com
|
test
|
Foo
|
Main
META-INF
|
MANIFEST.MF
This should be the ordering of your files and folders, otherwise Java can not find your main class from MANIFEST.MF
Now to solve this problem:
Open your jar file using a zip application like winrar
check the folder structure residing inside your jar file as I draw
Fix it right away within the winrar or try to correct your project structure to produce the structure I mentioned.
The class is called com.test.Foo.Main you need to specify the full name in the command:
java -cp main.jar com.test.Foo.Main
or you can use the simpler
java -jar main.jar
Check your META-INF/MANIFEST.MF for the attribute of Manifest-Version: 1.0
This attribute must be there.
Edit:
You need to move to the source root src/ and issue below command to create a valid jar.
javac com/test/Foo/*.java
and, create the jar using,
jar cmf com/test/Foo/MANIFEST.MF main.jar com/test/Foo/*.class
The thing is, package structure should match with the folder structure apparently.
I wonder if it's possible to run a program without packaging it into a jar.
For instance we have this:
-AppRoot
Main.class
-Misc
Math.class
OtherTools.class
-YetAnotherFolder
UsefulFunctions.class
Is this possible? The main method should be executed from command line or similar.
You can run this way from the AppRoot directory
javac -cp Misc/*:YetAnotherFolder/* Main.java //To compile
java -cp Misc/*:YetAnotherFolder/* Main // To run
Below is some documentation
-classpath classpath
-cp classpath
Specifies a list of directories, JAR archives, and ZIP archives to search for class files. Class
path entries are separated by colons (:). Specifying -classpath or -cp overrides any setting of the
CLASSPATH environment variable.
If -classpath and -cp are not used and CLASSPATH is not set, the user class path consists of the cur-
rent directory (.).
Add all (sub-)directories containing class files to classpath and use the class with the main method as argument of the java executable.
The directory structure is your package structure.
java -cp ./:./AppRoot:./AppRoot/Misc:./AppRoot/YetAnotherFolder AppRoot.Main
This should work if all dependencies are resolved and on the classpath.
So I'm still a noob in Java and I'm experimenting around with a few things.
I recently created a .jar file for my class using jar cvf <name>.jar <source files> and then used that jar to compile my driver class (javac -cp <name>.jar Driver.java) though how do I now run that class using the jar?
I've tried the following 2 commands:
java Driver and,
java -cp <name>.jar Driver.
The first gives me a NoClassDefFoundError for the class used, whereas the latter just gave me a single line error.
Error: Could not find or load man class Driver
What am I doing wrong? Is it possible I'm confusing this for something else?
I'm trying to do as much as I can without the use of any IDE.
You should put jar file and compiler output into classpath and specify main class:
java -classpath "<name.jar>;classes" Driver
EDIT (thanks to Kayaman):
If you are running command from linux/unix you have to use ":" as separator (in Windows works ";"). "classes" is a path to folder containing compiler output.
When creating an executable jar ( jar which contain a class with the main method) you should tell the jar which is the mainClass to be executed and for that you should create a file called 'Manifest.mf'.
The file should contain this:
Main-Class: MyPackage.MyClass
And when creating the jar you should use this to include your manifest:
jar cfm MyJar.jar Manifest.mf MyPackage/*.class
And for launching your jar :
java -jar MyJar.jar
I have a source file SerialTalk.java, in directory C:\javasrc\BattProj
This file imports classes from RXTXcomm.jar, eg.
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
...
RXTXcomm.jar is in the same directory as SerialTalk.java. I compile specifying a classpath pointing to the current directory:
javac -verbose -classpath . SerialTalk.java
Invariably, I get the following error. (Actually, many instances & variants of this error):
SerialTalk.java:3: error: package gnu.io does not exist
import gnu.io.CommPortIdentifier;
When I open the RXTXcomm.jar (eg. with 7-Zip) I can see the gnu.io structure, and the specific .class files that I'm trying to import.
So what am I doing wrong? The same .java (source) file has been compiled and run on another workstation within the Netbeans IDE. The difference here is I'm trying to compile it using javac from the command line. (Environment is Win7, 32 bit, jdk1.7.0_03)
So what am I doing wrong?
You're not putting the jar file on the class path. Putting the directory on the class path doesn't do it. That only tells javac where to find .class files in the directory structure, not jar files containing class files. You want:
javac -verbose -classpath .;RXTXcomm.jar SerialTalk.java