Java code sensitivity: class file conflict: resource exists with different case

I am on Windows OS, working in Eclipse IDE, I have two scripts:

1. I created below class, it's in Employee.java class (uppercase E):

public class Employee {
    public static void main(String[] args) {
        employee emp = new employee();
        emp.test();
    }
}

//here e is in lowercase
class employee {
    public void test() {
        System.out.println("I am in test()");
    }
}

      

In this case I ended up with below Exception:

Exception in thread "main" java.lang.NoClassDefFoundError: employee (wrong name: Employee)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
.
.
.
at Employee.main(Employee.java:4) // i.e at emp.test();

      

2. I created below class, this is Employee.java class:

public class Employee {
    public static void main(String[] args) {

    }
}

      

Now when I tried to create an employee.java class (lowercase e) in the same package, I got a message in eclipse that Type with same name but different case exists.

My question is Java is case sensitive. Does this mean the JVM (based on Windows and UNIX) is case sensitive, or the compiler is case sensitive? And why is it giving this exception in scenario 1 and eclipse won't let me create employee.java file in the same place in scenario 2.

Also remember that I'm on Windows, which is case insensitive for the filename, so I know it won't allow employee.java and Employee.java in the same place. Does this violate Java's case sensitivity in some way?

+2


source to share


5 answers


The file system on Windows is not case sensitive: Employee.class and employee.class cannot be in the same directory.

Scenario 1 with both classes defined in the same java source: The compiler that generates employee.class is probably renaming Employee.class or whatever.

Scenario 2 with separate java sources: Eclipse will fail to create employee.java in the same directory as Employee.java (under Windows file system). So someone in the past has taken care of handling the error in a user-friendly way.

Java accepts case sensitive names.

You can port your sources to Linux, compile them to .jar (zip format, also case sensitive). Then copy the jar to windows and execute it.

By the way, I think you found a new way to obfuscate java source code, decompile under Windows.


A related topic uses Unicode letters in class / file names. This applies to different platforms, different canonical representations of Unicode ( Γ©

as one or two Unicode code points), version control systems.



Development: (for those interested)

The human character Γ©

has two representations in Unicode:

  • "\ U00E9" - as one code point + 00E9 the U, Γ©

    ;
  • "e \ u0301" - as two code points, U + 009B, letter e

    , plus diacritic combination U-0301, Β΄

    (zero-width accent).

Unfortunately, different operating systems (I was told) used a different canonical representation. I once wanted to use the hg version control system , but had to figure out their missing support for Linux / Windows interoperability.

Otherwise, you can normalize the canonical form with java.text.Normalizer

.

So wait:

class CaféMañanaFaçade

      

+2


source


This is not a limitation of Java, but of the Windows file system in which you are trying to write files. The file system is not case-sensitive, the compiler can not be written as Employee.class

well as Employee.class

on the disc, as against FS is one and the same file.



If you could somehow compile on a registrar-specific filesystem (like Linux) and then package the resulting class files in a JAR, then you should be able to run from that JAR without error on Windows, as a ZIP file can contain two different entries whose names differ only in case.

+1


source


In any case, by convention, class names should always start with uppercase.

This convention avoids the problem you are describing.

0


source


No, it is not; Java is case sensitive and that all Java has control over itself. N / a>

It has no control over your filesystem, the implementation of which may not conform to Java rules.

0


source


I had this problem with a gradle project that contained multiple child projects and the sources were different. One of them had a class that read com.package.level1.Main

and the other had com.package.level1.main.Util

. When I ran gradle build for the whole project, it worked well from the command line, but the red exclamation mark in the Eclipse project was difficult enough to solve. The way to get rid of this was to remove the automatic compilation of Java source files for the project and set it for gradle use only. This is how it looks:

  1. Go to Project Properties

    .
  2. Select Builders

    on the left pane.
  3. Deselect Java Builder

    and leave only Gradle Project Builder

    .
  4. Apply and close properties.
  5. Remove the project from the workspace. When uninstalling, select the option not to remove files from the file system.
  6. Import the project back into Eclipse and you're done.
0


source







All Articles