-2

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.

AaronDancer
  • 649
  • 1
  • 7
  • 22
  • 4
    This question appears to be off-topic because it is about an urgent matter that will be of little interest to future visitors. – Andrew Thompson Oct 06 '13 at 18:58
  • 1
    Is it typo or is it real that your package is `com.ds` while `Main` class is inside `com/DatingService`? Anyway I cant reproduce your error. If I have two classes (one public) in `MyPublicClass.java` file I get two `class` files if compiled with `javac MyPublicClass.java`. – Pshemo Oct 06 '13 at 19:01
  • The real package name is com.DatingService, I simply shortened it for the example. They are both in the same package in the same .java file. They compile fine but I can't run it. Is there a special way to run something like this? java com.DatingService.Main doesn't work as I said above – AaronDancer Oct 06 '13 at 19:09
  • It doesn't look like you're using classpath. And it doesn't look like you're searching all that hard for the second class file which likely has been created. – Hovercraft Full Of Eels Oct 06 '13 at 19:15
  • @HovercraftFullOfEels I have no knowledge of how to use classpath, I've tried a few things I found around the internet and they compile but also do not run. I've found the second .class file now, it was buried under a bunch of files. I've set the output directory for compiling using -d now and I see it, however the problem still persists. My folder structure is like so: `./Dating Service\src\com\DatingService` With my the .java file being `Main.java` in the folder `.\DatingService` – AaronDancer Oct 06 '13 at 19:24
  • Why not save yourself a mountain of pain and just use an IDE? Who runs javac from the commandline these days... – Boris the Spider Oct 06 '13 at 19:32
  • @BoristheSpider I am using an IDE, I use IntelliJ and everything works perfectly when debugging and building, even making a jar artifact works flawlessly. But the person reviewing this is using javac, why? Because that person knows no better (and I have no control over this). I even provided them with .class files and .jar files from the IDE but, that person likes to compile the code then run... I don't get it, but I literally have no authority for that. – AaronDancer Oct 06 '13 at 19:38

2 Answers2

1

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)

Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • That did the trick! And thank you so much for the explanation! It makes a lot of sense now. Thank you very much for your help :) – AaronDancer Oct 06 '13 at 20:02
0

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
Thomas
  • 372
  • 2
  • 10
  • I have no idea why, but that did the trick when using the `.` for the directory, however if I change that to anything else I still get exceptions and such. Also I cannot get this working in my file structure, only when I place the .java in the JDK bin folder – AaronDancer Oct 06 '13 at 19:35
  • If you specify '-d something-else' to javac, you have to specify '-classpath something-else' to java. – user207421 Oct 06 '13 at 20:29