Class files don't actually care about file names so ClassLoader has nothing to do with this. The OP problem is the source. The Java compiler won't compile a source file if none of the classes (and the only public one) in the file matches the name of the file.
> Class files don't actually care about file names
But URLClassLoader does, which definitely has something to do with this.
True, before you get there, you'd first need it to compile - but modern JDKs have a compiler API that allows customization via the StandardJavaFileManager interface, and that looks like it should be able to do the job to make source file names follow a different convention.
Yes, commonly used ClassLoaders do care about file names and directories. The Java compiler javac does not. The javac compiler compiles compilation units which are generally files, but name does not matter.
No, the file names of compilation units do matter to javac. To quote the Java Language Specification, section 7.6:
> If and only if packages are stored in a file system (§7.2), the host system may choose to enforce the restriction that it is a compile-time error if a class or interface is not found in a file under a name composed of the class or interface name plus an extension (such as .java or .jav) if either of the following is true:
> * The class or interface is referred to by code in other ordinary compilation units of the package in which the class or interface is declared.
> * The class or interface is declared public (and therefore is potentially accessible from code in other packages).
and javac does indeed enforce this restriction, at least for public classes. It's an error to declare a public class called Foo in a file that's called anything except Foo.java.
I stand corrected. However, I don't believe that the class source file needs to be in a directory (or hierarchy of directories) that matches the package name. Many IDE's enforce this as well, which I believe is not correct.
Every class file contains the full information about the class name, package and everything needed to instantiate the class... it even includes the source class file name usually and other attributes like statement line numbers.
However, for performance reasons, the JVM loads classes lazily and will only try to find classes in the directory it would be expected to be (either in the directories included in the classpth or in jars). Because you can write your own class loader, you can implement something different (like OSGi does for example - it has much more metadata so it can even load multiple classes with the same name from different jars) but this is the default behaviour.
Actually, I'm fairly sure you can. You just need a custom classloader.