I currently have a .java file set up like this:
package com.ds;
class c{...}
public class Main{...}
When I compile the file Main.java, it results in a single .class file being Main.class.
When I try to run the .class with java com.ds.Main
it does not work! It says it cannot find or load the class.
When I try to run the .class with java Main
it runs, but I get an error like so:
Exception in thread "main" java.lang.NoClassDefFoundError: Main (wrong name: com
/DatingService/Main)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:792)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)
I've seen this before while trying to find a solution and none of the solutions I found applied to me or just didn't work.
After doing a bit more research I am assuming that javac will not split the classes within a file by at least default? I know that many IDEs like Eclipse and IntelliJ split the classes into two separate .class files (I can confirm this). So is there any way for javac to do this? I'm using javac as my compiler for IntelliJ so there must be a way unless it's done before compiling.
If I remove the package, I can run java Main perfectly fine with only a single .class file compiled. So I'm a bit confused, and a little desperate. I am trying to completely avoid changing my code or splitting the classes into two separate .java files.
I am not sure what you are doing wrong so I will just show you how it can be done.
Lets say you have directories and files
[myProject]
|
+--[src]
| |
| +--[com]
| |
| +--[DatingService]
| |
| +-- Main.java
|
+--[classes]
and your Main.java file looks something like
package com.DatingService;
class c{
private int i;
public void setI(int i){
this.i=i;
}
public int getI(){
return this.i;
}
}
public class Main{
public static void main(String[] args){
c myCVariable = new c();
myCVariable.setI(10);
System.out.println(myCVariable.getI());
}
}
In terminal you need to go to myProject
directory and from it use
myProject>javac -d classes src\com\DatingService\Main.java
Thanks to -d
(directory) parameter packages with all compiled classes should be placed in classes
directory (note that classes
directory must already exist). So c.class
and Main.class
will be placed in myProject\classes\com\DatingService
.
Now to run main
method from Main
class you just need to provide information about directory that contains your packages (this is ClassPath) and also use full.package.name.to.your.MainClass
. So you will have to add -classpath classes
(or shorter -cp classes
) parameter to your java
command and run it like
myProject>java -cp classes com.DatingService.Main
(note: there is no .java
suffix after Main
class since JVM is running binaries stored in .class
files, not code from .java
files)