4

I have got the following code in a file called test.java which is located inside the directory C:\D\JavaProjects

class test
{
        public static void main( String[] str )
        {
                System.out.println( "Hello, World! from test" );
        }
}

class Test
{
        public static void main( String[] str )
        {
                System.out.println( "Hello, World!" );
        }
}

When I do "javac test.java" it outputs test.class. Now, if I do "java test" I get the following output:

Exception in thread "main" java.lang.NoClassDefFoundError: test (wrong name: Test) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(Unknown Source) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.access$000(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) Could not find the main class: test. Program will exit.

But when I do "java Test" I get

Hello, World!

Now, if I simply reverse the occurrence of the two class declarations, such that Test is declared BEFORE test, the java compiler outputs the file Test.class. Now doing "java test" gives the output:

Hello, World! from test

but "java Test" gives

Exception in thread "main" java.lang.NoClassDefFoundError: Test (wrong name: test) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(Unknown Source) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.access$000(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) Could not find the main class: Test. Program will exit.

Now, I know it is very strange to have two classes with main in them in the same file, but this behavior seems completely illogical and more like a bug. Can somebody point me to the appropriate section of the Java Language Specification that specifies this behavior? Many thanks in advance for the help.

Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
dark_secrets
  • 51
  • 1
  • 3
  • This is already sort of answered here : http://stackoverflow.com/questions/4837723/can-linux-java-developers-create-classes-of-names-different-only-by-case-in-the-s – manojlds Apr 23 '11 at 07:37

3 Answers3

9

Presumably you're running on Windows, right?

That means you can't have two classes which differ only in case - because they'll both end up wanting to be in the same file, as Test.class and test.class are effectively the same filename in case-insensitive file systems.

It's not really a bug in Java - just an unfortunate but natural corollary of using a case-insensitive file system in conjunction with a language which attaches meaning to filenames.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Yup, that's right. I am running on Windows 7. Thanks for the very quick reply!!! So presumably, when I have got Test declared first and test afterwards, it first outputs Test.class, then tries to create test.class but finds Test.class already created so opens that and outputs test into that file. Now when I do java test, it finds Test.class (since the file system is case insensitive) and finds test inside it and runs it successfully!!!! But I still say it is a bug. Because this means somebody used the flag in fopen/_open/CreateFile that says open the existing file if already created. LOL!!! – dark_secrets Apr 23 '11 at 07:39
  • @dark_secrets: So you want compilation to fail if any of the output files already exist? Sounds like a bad idea to me. – Jon Skeet Apr 23 '11 at 07:44
  • Nopes, they should use the flag in fopen/_open/CreateFile that OVERWRITES the already created file. – dark_secrets Apr 23 '11 at 07:47
  • 2
    @dark_secrets: I think it *is* already overwriting it. It's not appending it - it's overwriting the `test` class with the `Test` class. Fundamentally, you're trying to store two different bits of content, but you've only got one file to put them in. How would you expect that to work? – Jon Skeet Apr 23 '11 at 07:53
-3

@dark_secrets, You have to begin a class name with a capital letter in JAVA or else you will get an error while compiling.

-4

use public (then class name).... that will definetely work....

nobody
  • 1