Reputation: 51
I am trying to run code from the official Oracle website to create a GUI. I saved this code in a .java file. I ran the command:
javac RadioButtonDemo.java
No messages appeared. But when I try to run the program, I get an error message:
C:\Users\User\Documents\Java Projects>java RadioButtonDemo
Error: Could not find or load main class RadioButtonDemo
Caused by: java.lang.NoClassDefFoundError: components/RadioButtonDemo (wrong name: RadioButtonDemo)
Why doesn't the code from the official Oracle website work? What am I doing wrong? How can I fix it? I don't understand this!
Tips from other posts don't help me. Minus all you want.
I have JDK 16.0.1. Windows 10 x64.
Upvotes: 1
Views: 90
Reputation: 45726
The RadioButtonDemo
class has a package components;
statement. In typical Java, packages are represented by directories. So you have at least two options:
./RadioButtonDemo.java
to ./components/RadioButtonDemo.java
javac ./components/RadioButtonDemo.java
java components.RadioButtonDemo
If you don't specify the output location (see below) then the compiler puts the class file(s) in the same directory as the associated source file.
javac -d <path> ./RadioButtonDemo.java
java components.RadioButtonDemo
The <path>
can even be the current directory (i.e. .
). When you specify the output location the compiler creates the directory structure mirroring the package structure of the resulting class files for you.
If you specify somewhere other than the current directory for -d
then you'll either need to navigate to that location or specify the class-path (via -cp
, -classpath
, or --class-path
) when executing java
.
Now, the compiler doesn't seem to care about the directory structure—at least, it didn't care when I experimented—but the class-loading mechanism does seem to care. So the compiler happily compiled RadioButtonDemo.java
despite it not being in a directory named components
, but it (by default) puts the resulting class file(s) in the same directory as the source file.
When you execute java RadioButtonDemo
you're telling Java to find and load a class named RadioButtonDemo
on the class-path. The class loader, at least as currently implemented, takes that class name and resolves the expected class file resource, which is /RadioButtonDemo.class
. It finds that class file and loads it. But the class file reports that the class' qualified name is actually components.RadioButtonDemo
. The names don't match and so it throws an error.
Once you apply either fix the class file ends up at ./components/RadioButtonDemo.class
. Now when you execute java components.RadioButtonDemo
you are telling Java to find and load a class named components.RadioButtonDemo
on the class-path. The class loader takes that class name and resolves the class file resource as /components/RadioButtonDemo.class
. It finds that class file, loads it, the names match, and everything is all good.
Upvotes: 2