jvm - Case sensitivity of Java class names -
if 1 writes 2 public java classes same case-insensitive name in different directories both classes not usable @ runtime. (i tested on windows, mac , linux several versions of hotspot jvm. not surprised if there other jvms usable simultaneously.) example, if create class named a , 1 named a so:
// lowercase/src/testcase/a.java package testcase; public class { public static string mycase() { return "lower"; } } // uppercase/src/testcase/a.java package testcase; public class { public static string mycase() { return "upper"; } } three eclipse projects containing code above available website.
if try calling mycase on both classes so:
system.out.println(a.mycase()); system.out.println(a.mycase()); the typechecker succeeds, when run class file generate code directly above get:
exception in thread "main" java.lang.noclassdeffounderror: testcase/a (wrong name: testcase/a)
in java, names in general case sensitive. file systems (e.g. windows) case insensitive, i'm not surprised above behavior happens, seems wrong. unfortunately java specifications oddly non-commital classes visible. java language specification (jls), java se 7 edition (section 6.6.1, page 166) says:
if class or interface type declared public, may accessed code, provided compilation unit (§7.3) in declared observable.
in section 7.3, jls defines observability of compilation unit in extremely vague terms:
all compilation units of predefined package java , subpackages lang , io observable. other packages, the host system determines compilation units observable.
the java virtual machine specification vague (section 5.3.1):
the following steps used load , thereby create nonarray class or interface c denoted [binary name] n using bootstrap class loader [...] otherwise, java virtual machine passes argument n invocation of method on bootstrap class loader search purported representation of c in platform-dependent manner.
all of leads 4 questions in descending order of importance:
- are there guarantees classes loadable default class loader(s) in every jvm? in other words, can implement valid, degenerate jvm, won't load classes except in java.lang , java.io?
- if there guarantees, behavior in example above violate guarantee (i.e. behavior bug)?
- is there way make hotspot load
a,asimultaneously? writing custom class loader work?
- are there guarantees classes loadable bootstrap class loader in every jvm?
the core bits , pieces of language, plus supporting implementation classes. not guaranteed include class write. (the normal jvm loads classes in separate classloader bootstrap one, , in fact normal bootstrap loader loads classes out of jar normally, makes more efficient deployment big old directory structure full of classes.)
- if there guarantees, behavior in example above violate guarantee (i.e. behavior bug)?
- is there way make "standard" jvms load , simultaneously? writing custom class loader work?
java loads classes mapping full name of class filename searched on classpath. testcase.a goes testcase/a.class , testcase.a goes testcase/a.class. filesystems mix these things up, , may serve other when 1 asked for. others right (in particular, variant of zip format used in jar files case-sensitive , portable). there nothing java can (though ide handle keeping .class files away native fs, don't know if , jdk's javac isn't smart).
however that's not point note here: class files know internally class talking about. absence of expected class file means load fails, leading noclassdeffounderror received. got problem (a mis-deployment in @ least sense) detected , dealt robustly. theoretically, build classloader handle such things keeping searching, why bother? putting class files inside jar fix things far more robustly; handled correctly.
more generally, if you're running problem real lot, take doing production builds on unix case-sensitive filesystem (a ci system jenkins recommended) , find developers naming classes case differences , make them stop confusing!
Comments
Post a Comment