1

I learned here that, even if it is best practice and despite most compilers require you to do so, it is not that strict to have .class files named after the public class they contain, at least from a Language Specification viewpoint.

I searched the JLS and the JVM Specification, but could not manage to find the actual chapter where this topic is addressed. It seems weird to me that this issue is not treated at all.

Where, if it exists, an official Oracle document can confirm or debunk the following statement?

Giving .class files the same name as the public class they contain - whether they do - is simply a must, but according to the JLS this is not that strict. From the JLS's perspective, it is left to the compiler to choose whether to set such a restriction or not.

Salvioner
  • 303
  • 5
  • 16
  • I would use a chapter or page number for further referencing this topic in publications/writings. – Salvioner Oct 18 '17 at 13:11
  • Note that there may be multiple .class files per .java source, i.e. one for every inner class that's created. Those normally have the format `[toplevel_public_class]$[inner_class].class` for named inner classes or `[toplevel_public_class]$[number].class` for anonymous inner classes. I don't know whether that's a rule or just some standard way of doing it but it's an example that the .class files don't always match the top level class' name exactly (although it's an important part of the name). – Thomas Oct 18 '17 at 13:27
  • Btw, I might be wrong here but from the runtime's point of view the file names shouldn't matter at all since the files contain all the necessary information. However, having matching file names makes it easier for humans or text based operations (e.g. trying to find a class in a jar in order to load it) since you'd not have to scan every file to find the right one. The restriction on the source files is probably also mainly meant to prevent humans from messing it up ;) – Thomas Oct 18 '17 at 13:33
  • If you were to confirm that there is,in fact, no strict requirement for `.class` files to be named after the public class they contain: how will your life be improved? And if you learned that such a requirement _did_ exist, is it really _so_ bad? – Kevin Anderson Oct 18 '17 at 13:41
  • @Thomas as you said, the Java linker needs to know which .class file it has to load and it would take ages to find the right one in big projects. But the weird thing is that the problem is never addressed in the JLS, even if all major compilers and also Oracle NetBeans IDE follow this rule. – Salvioner Oct 18 '17 at 13:47
  • @KevinAnderson it is not bad at all, it would be great because that would mean i don't have to care about possible implementations that don't follow this rule. I work with ASM at bytecode level and i need to know if there *might* be exceptions to this rule. And when i have to explain my work it makes a difference whether i say i based my choices on official documentation or good programming practices and unofficial naming conventions. – Salvioner Oct 18 '17 at 13:58

1 Answers1

2

This is addressed in JLS §13.1., The Form of a Binary:

Programs must be compiled either into the class file format specified by The Java Virtual Machine Specification, Java SE 8 Edition, or into a representation that can be mapped into that format by a class loader written in the Java programming language.

So you are not required to deliver the compiled code as .class files at all, as long as you have a class loader implementation capable of loading your code representation. Note that on this level, e.g. when passing the mapped data to ClassLoader.defineClass, the file name of the class file is not present at all. Both specifications, JLS and JVM, consistently use the term “class file” synonym to “a sequence of bytes in the class file format”, rather than “an entry in a file system or zip archive” and therefore, never mention file names at all.

This is also matching the direction Java 9 is going, to deliver class libraries is a custom, potentially optimized library format rather then a zip container full of .class files.

Still, it would be very discouraged to name the files containing a different representation with a .class ending.

Your cited statement is a bit odd. It starts with

Giving .class files the same name as the public class they contain is simply a must,…

but a .class file doesn’t have to contain a public class at all. In its current form, it contains at most one class which doesn’t have to be public. But it may also contain a dummy class to deliver package meta information or, starting with Java 9, a module specification.

Also, in order to be found by default lookup rules, e.g. using URLClassLoader, you’re not giving the .class file the name of the contained class, but rather use its short name and place it in a directory structure/path derived from the package component of its qualified name.

But the second part

… but according to the JLS this is not that strict. From the JLS's perspective, it is left to the compiler to choose whether to set such a restriction or not.

is correct. As explained above, there’s not even a requirement to deliver class files. Compare to

JLS §1., Introduction:

The Java programming language is normally compiled to the bytecode instruction set and binary format defined in The Java Virtual Machine Specification, Java SE 8 Edition.

Note the word “normally

and

JVMS §2.1., The class File Format:

Compiled code to be executed by the Java Virtual Machine is represented using a hardware- and operating system-independent binary format, typically (but not necessarily) stored in a file, known as the class file format.

“typically (but not necessarily)”…

Community
  • 1
  • 1
Holger
  • 285,553
  • 42
  • 434
  • 765
  • Thank you! About the first part of the statement i should have specified "if they contain a public class at all"... Did not mean that .class file *must* contain a public class but that, if they do, they should (judging from your answer this is just good programming habit, but still they should) be named after that class' name. – Salvioner Oct 18 '17 at 17:28
  • The key point is, you have to follow the naming convention if you want the standard lookup algorithm, like implemented by `URLClassLoader`, to work. Otherwise, you’ll have to implement you own loader (though it wouldn’t be so hard if only the naming differs). In case of Java 9, there’s not only a new class loader implementation, but also a special `FileSystem` implementation that tools can use to read the modules. – Holger Oct 19 '17 at 06:05