ClassLoader: Treating a class as a resource - safe or implementation detail?

48 views Asked by At

For my use case, I want to transfer a class (not an object, the actual class file) over a Socket connection, then load that class on the receiving end.

The class is included normally in the project (on the sending end), so its somewhere on the class path.

I have all the code working, but to actually get the class file from the classpath, I had to resort to somewhat oddly mistreating the class as a resource (Code stripped down to essential part):

public class ClassTransport {

    public byte[] data;
    public String qualifiedName;

    public static ClassTransport create(Class<?> theClass) throws Exception {
        ClassTransport result = new ClassTransport();
        result.qualifiedName = theClass.getName();
        // brute force derive the class file name
        String classResourceName = theClass.getName().replace('.', '/') + ".class";             

        ClassLoader cl = theClass.getClassLoader();
        try (InputStream in = cl.getResourceAsStream(classResourceName)) {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int b;
            while ((b = in.read()) >= 0) {
                out.write(b);
            }
            out.close();
            result.data = out.toByteArray();
        }
        return result;      
    }

}

This works, but is it actually safe to do this or does it violate any specifications - specifically what are the possibilites where this may fail to retrieve the class in future JRE releases or on a specific platform?

1

There are 1 answers

0
Kevin Workman On BEST ANSWER

Short answer: it's probably fine.

Longer answer: it's not guaranteed to be fine, because nothing in the JLS guarantees that classes in packages are organized as files in directories.

The pertinent section of the JLS is 7.2. Host Support for Packages:

In simple implementations of the Java SE platform, packages and compilation units may be stored in a local file system. Other implementations may store them using a distributed file system or some form of database.

If a host system stores packages and compilation units in a database, then the database must not impose the optional restrictions (ยง7.6) on compilation units permissible in file-based implementations.

The gist is that the classpath, in theory, might be in something like a database instead of a filesystem. So although your approach doesn't violate any specifications, it also isn't supported by any specification. I can't find any system where this is the case though, so you're probably okay assuming a file system in most cases.

This has also been discussed in this StackOverflow question.