When I run
javac 'path/to/test.java'
java 'path/to/test'
I get an error like this
Exception in thread "main" java.lang.NoClassDefFoundError: path/to/test (wrong name: test)
It works when I do the same after I run "cd path/to", but is there a way to do this without the cd command? If so, how?
If you wish to compile and run the class from your current location (presumably a project directory), I would recommend:
Use a package declaration in your class:
package path.to;
public class Test {
public static void main(String[] args) {
System.out.println("LOADED");
}
}
When you run your code do so with dot notation to the class name:
javac path/to/Test.java
java path.to.Test
Your Test.java file should have a package line at the top:
package path.to;
public class Test {
public static void main(String argv[]) {
}
}
Then you can compile and run it. It works on my MacBook Pro. Note that java path.to.Test and java path/to/Test are equivalent.
% javac path/to/Test.java
% java path.to.Test
If you are missing the package statement, then you will get the error that you are reporting.
% javac path/to/Test.java
% java path.to.Test
Exception in thread "main" java.lang.NoClassDefFoundError: path/to/Test (wrong name: Test)
Assuming test.java does not have a package statement, your class (which should be named Test, not test) is in the unnamed package, so do this:
javac 'path/to/test.java'
java -cp 'path/to' test
If your test.java file starts with a package to; statement, then you do this:
java -cp 'path' to.test
And if it says package path.to;, then you do this:
java path.to.test
or this to be explicit:
java -cp . path.to.test
If your package statement says any other name, then your directory structure is wrong, since the directory must match the package statement, starting at the directory named in the classpath (-cp).
Related
When I try to compile with javac .Main
D:\Desktop\Development\Java\Section 4\Abstract
❯ javac -classpath . *.java
error: Invalid filename: *.java
Usage: javac <options> <source files>
use --help for a list of possible options
[17:37] Shell xUSAGE 174ms
Main.java:5: error: cannot find symbol
Student st1 = new Student("John");
^
symbol: class Student
location: class Main
Main.java:5: error: cannot find symbol
Student st1 = new Student("John");
^
symbol: class Student
location: class Main
2 errors
But I able to compile it succesfully with
D:\Desktop\Development\Java\Section 4\Abstract\src\com\Testing
>javac -classpath . *.java
Although I still haven't figured it out how to run the Main class
java Main
Error: Could not find or load main class Main
Caused by: java.lang.NoClassDefFoundError: com/Testing/Main (wrong name: Main)
If you want to use straight javac to compile (really, don't - use a build system), you have to specify the files where they are on the file system. so not *.java, but src\com\Testing\*.java. Yes, if you have many packages, this means an extremely large command line.
java's argument takes a class name - a fully qualified one. Not a path.
If you have this source file:
package com.foo;
public class Bar {
public static void main(String[] args) { .. }
}
Then:
It should be in projectRoot/src/main/java/com/foo/Bar.java where projectRoot is whatever dir serves as your main project folder, src/main/java can be just src, or src/whatever - or something to indicate the kind of sub-project this covers, com/foo matches the package statement, and Bar matches the public class name.
When compiling a Bar.class falls out of it; this should be in projectRoot/bin/com/foo/Bar.class or similar, where bin might also be build. But the com/foo/Bar.class part is mandatory - class files have to be in a subdir structure that matches package.
To run this file, you would put projectRoot/bin on the classpath and then write out the full classname. So, if you're in the projectDir right now, java -cp bin com.foo.Bar.
I am trying to compile (from the command line) a java package that imports another package of my own. I was following a tutorial online but it seems that I get an error when I try to compile the final java file (CallPackage.java).
Here is the file structure:
+ test_directory (contains CallPackage.java)
-> importpackage
-> subpackage (contains HelloWorld.java)
Here is CallPackage.java:
/// CallPackage.java
import importpackage.subpackage.*;
class CallPackage{
public static void main(String[] args){
HelloWorld h2=new HelloWorld();
h2.show();
}
}
and here is HelloWorld.java:
///HelloWorld.java
package importpackage.subpackage;
public class HelloWorld {
public void show(){
System.out.println("This is the function of the class HelloWorld!!");
}
}
Attempted Steps
Go to the subpackage and compile HelloWorld.java with $javac HelloWorld.java.
Go to test_directory and compile CallPackage.java with $javac CallPackage.java.
This gives me an error on the last command:
CallPackage.java:1: package importpackage.subpackage does not exist
import importpackage.subpackage.*;
^
CallPackage.java:4: cannot find symbol
symbol : class HelloWorld
location: class CallPackage
HelloWorld h2=new HelloWorld();
^
CallPackage.java:4: cannot find symbol
symbol : class HelloWorld
location: class CallPackage
HelloWorld h2=new HelloWorld();
^
3 errors
How can I compile both packages? Thanks so much for any help!
The issue was that the class path needs to be set for each command (javac and java):
Attempted Steps
instead of going to subpackage, compile HelloWorld.java from the top_level:
$javac -cp . importpackage/subpackage/HelloWorld.java
compile CallPackage.java in the same way:
$javac -cp . CallPackage.java
run the file using the class path also:
$java -cp . CallPackage
NOTE: running "$java CallPackage" will give an error "Error: Could not find or load main class CallPackage"
In summary, during each step, the class path must be specified. It worked after running it as such.
Same situation to me. And I came to take over it by compiling classes at the same time.
For example, here is my project:
+ beerV1
-> classes
-> src
-> com
-> example
-> model
-> BeerExpert.java
-> web
-> BeerSelect.java
BeerExpert.java:
package com.example.model;
import ...
public class BeerExpert{
...
}
BeerSelect.java:
package com.example.web;
import com.example.model.*;
import ...
public class BeerSelect {
...
}
As you can see: BeerSelect.java is trying to import classes in com.example.model package.
At the first time, I compiled BeerExert.java first by command:
--> javac -d classes src/com/example/model/BeerExpert.java
Then:
--> javac -d classes src/com/example/web/BeerSelect.java
And the result was:
-->... error: package com.example.model does not exist
So, I knew that compiling multiple classes separately will not work in this case.
After suffering on google, I found this very simple way to solve the problem:
Just compile all at once:
--> javac -d classes src/com/example/model/BeerExpert.java src/com/example/web/BeerSelect.java
Finally, here is what I got:
+ beerV1
-> classes
-> com
-> example
-> model
-> BeerExpert.class
-> web
-> BeerSelect.class
-> src
-> com
-> example
-> model
-> BeerExpert.java
-> web
-> BeerSelect.java
Hope that helps.
Are you sure importpackage/subpackage is in your classpath?
-cp path or -classpath path
Specify where to find user class files, and (optionally) annotation processors and source files. This class path overrides the user class path in the CLASSPATH environment variable. If neither CLASSPATH, -cp nor -classpath is specified, the user class path consists of the current directory. See Setting the Class Path for more details.
If the -sourcepath option is not specified, the user class path is also searched for source files.
If the -processorpath option is not specified, the class path is also searched for annotation processors.
http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html
It's an old topic but Google has led me to this site. For the completness, I'd like to add one bit to #Vĩnh Thụy Trần's answer on how to run the main class after compiling it into a custom folder. While it looks trivial now it took me some time to get it right.
In order to run your project, you also need to specify a path to the classes:
java -classpath <directory> your.package.name.classname
or
java -cp <directory> your.package.name.classname
Taking Vĩnh Thụy Trần's example again, the command would look like this:
java -cp classes com.example.web.BeerSelect
I hope it will help someone as I spent some time figuring it out.
(1)first compile the code
javac -d importpackage.subpackage.HelloWorld
(2) and then compile the CallPackage.java
javac CallPackage.java
delete your package folder (after pasting you code to some other folder) and then locate to the folder in cmd where you current code is and try javac -d . Helloworld.java (this will create the Helloworldclass and subpackage as well) and try same for you mainfunction code ie Callpackage.java after compiling to run the code try java Callpackage
I'm trying to understand the inclusion of third party jar files in a java project using only the command line in Windows 10.
Specifically, I try to include the file json-20200518.jar in my "project" so that I can use the java object JSONObject in the project.
My java file:
package com.mypackage.example;
import org.json.JSONObject;
class Example {
public static void main(String[] args) {
// ... program logic
}
}
location of my java file (Examp.java):
./com/mypackage/example
location of jar file:
./jars
using cmd win10 I compile:
javac -cp "C:\Users\pfort\Desktop\java\jars\json-20200518.jar" "C:\Users\pfort\Desktop\java\com\mypackage\example\Examp.java"
compilation is successful.
Run:
java -cp "C:\Users\pfort\Desktop\java\jars\json-20200518.jar" com.mypackage.example.Examp
I get a report:
Error: Could not find or load main class com.mypackage.example.Pokus
Caused by: java.lang.ClassNotFoundException: com.mypackage.example.Pokus
Second attempt:
java -cp "C:\Users\pfort\Desktop\java\jars\json-20200518.jar" "C:\Users\pfort\Desktop\java\com\mypackage\example\Pokus"
But the same error message comes back to me.
Where am I going wrong? Is it the wrong structure? I don't get it, the compilation is successful but the run does not work.
The compiled Examp.class file isn't part of json-20200518.jar, so you'll need to add the directory containing it to the command line. Assuming it's the current directory (.):
java -cp "C:\Users\pfort\Desktop\java\jars\json-20200518.jar;." com.mypackage.example.Examp
I am trying to use the javax.jms library: https://docs.oracle.com/javaee/7/api/javax/jms/package-summary.html, for which I have downloaded the jar: http://www.java2s.com/Code/Jar/j/Downloadjavaxjms111sourcesjar.htm
Specifically, I am trying to use the MessageListener and Message classes, which I know to be in there based on the Jar decompilation. I put this jar file next to my java file, so that the file structure looks like this:
myDir
-|jms.jar
-|Main.java
Main.java:
import javax.jms.MessageListener;
import javax.jms.Message;
public class Main {
public static void main(String[] args) {
MessageListener listener = new MessageListener() {
#Override
public void onMessage(Message msg) {
}
};
System.out.println("Hello World");
}
}
I can compile this using javac -cp jms.jar Main.java from inside myDir. This creates Main.class. However, when I run java Main, I get:
Exception in thread "main" java.lang.NoClassDefFoundError: javax/jms/MessageListener
This would lead me to believe that MessageListener is not included in the jar, but it is and the file structure is javax/jms/MessageListener checks out. What dumb mistake am I making?
When I compile without -cp js, it fails, saying:
error: package javax.jms does not exist
thus, at least the compiler is looking in the jar.
I made 2 Mistakes
1: Credit to #NormR, .:jms.jar (or .; for Windows I surmise)
2: Link jar while executing. Therefore, the commands should've been:
javac -cp .:jms.jar Main.java
java -cp .:jms.jar Main
I'm trying to understand how jars and packages work in Java. So to do this, I created a simple test JAR and am trying to use a class contained in that jar. Simple enough, but it is giving me errors like "class not found". Here's the setup:
1) I have a file called MyHelloWorld.java, which will be packaged in a JAR:
package com.mytest;
public class MyHelloWorld {
public String getHello() {
return "Hello";
}
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
2) I have another file called 'HelloHello.java' which uses the function getHello() in com.mytest.MyHelloWorld
import com.mytest.*;
public class HelloHello {
public static void main (String[] args) {
MyHelloWorld hello = new MyHelloWorld();
System.out.println(hello.getHello());
}
}
3) To package the MyHelloWorld class inside a JAR, I created the folders com/mytest in the current directory, and moved MyHelloWorld.java to that folder
4) I compiled MyHelloWorld.java in that folder using javac MyHelloWorld.java
5) I ran jar -cf myhello.jar ./com/mytest/*.class from the root folder to create the JAR file (as described in http://www.javacoffeebreak.com/faq/faq0028.html)
6) I copied HelloHello.java and myhello.jar to a new folder with nothing else in it, to test this setup
7) javac -cp ./*.jar HelloHello.java [succeeds]
8) java -cp ./*.jar HelloHello [FAILS] (I also tried just `java HelloWorld', which failed too, with a different error message)
This last statement fails with the message:
$java -cp ./*.jar HelloHello
Exception in thread "main" java.lang.NoClassDefFoundError: HelloHello
Caused by: java.lang.ClassNotFoundException: HelloHello
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:315)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:330)
at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:398)
Any idea why it's failing? Any insights you can provide on why it works this way, and how package names are defined inside a JAR etc. would also be appreciated!
I believe it is looking in the jar for your HelloHello class. You probably need the current folder on the classpath too.
java -cp .:myhello.jar HelloHello
You should use:
java -cp .:./* HelloHello
java and javac treat -cp argument a bit differently. With java the * in cp will automatically load all the jars it finds in the given location.
Also, the colon : is the separator between different classpath elements.
Make sure if HelloHello.class is in appropriate directories structure (com/mytest) than change your 8th step:
8) java com.mytest.HelloHello //or java -cp .;*.jar com.mytest.HelloHello
well, java HelloHello works too