I'm sending a Class object from client to server side. Every time the server needs to load the Class object sent by the client instead of reusing it by parent delegation model (when it was loaded during the 1st iteration).
I'm trying to use a custom class loader on the server side whose loadClass(String)
simply calls findClass()
instead of checking with parent hierarchy.
To achieve this, I'm doing following:
Class cl = com.example.XYZ.class; String path = cl.getName().replace('.', '/') + ".class"; InputStream is = cl.getClassLoader().getResourceAsStream(path); ByteArrayOutputStream bos = new ByteArrayOutputStream(); int data = -1; while((data=is.read())!=-1) bos.write(data); byte[] classBinaryData = bos.toByteArray();
I'm sending classBinaryData
to the server side.
byte[]
, verify if it's the same as on client side by matching MD5 checksum, then I create a new instance of my custom class loader and pass the byte array so it could be used in calling defineClass
from within findClass
.However, I'm getting either of the errors (depending on the way I create byte[] out of .class)
Incompatible magic value ..... in class file <Unknown>
OR
com/example/XYZ (wrong name: com/example/XYZ)
coming from defineClass
I need help in figuring out the mistake in my approach/code.
Your byte[] generation code looks fine.
When I used the byte array generated form your code to load the class with following class loader code, it was able to load the class successfully.
class CustomClassLoader extends ClassLoader {
public Class loadTheClass(String name, byte[] bytes) {
return defineClass(name, bytes, 0, bytes.length);
}
}
Using this classloader like this
CustomClassLoader ccl = new CustomClassLoader();
Class cz = ccl.loadTheClass("com.example.XYZ", classBinaryData);
Object o = cz.newInstance();
'.'
instead of '/'
in the name when you are loading the class at server side.