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?
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:
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.