Question

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.

Was it helpful?

Solution

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)

OTHER TIPS

Specify where to place the generated class files using the -d option. Eg. If you want to compile it to the current directory where your prompt is, use

javac -d . Main.java

It will create the folder structure com/ds in you current directory and place the two class files in there. Then run using

java com.ds.Main
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top