views:

294

answers:

5

If I have a Class instance at runtime, can I get its byte[] representation? The bytes I'm interested in would be in the Class file format, such that they'd be valid input to [ClassLoader.defineClass][3].

[3]: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html#defineClass(java.lang.String, byte[], int, int)

EDIT: I've accepted a getResourceAsStream answer, because it's very simple and will work most of the time. ClassFileTransformer seems like a more robust solution because it doesn't require that classes be loaded from .class files; it would handle network-loaded classes for example. There's a few hoops to jump through with that approach, but I'll keep in in mind. Thanks all!

+1  A: 

In general you can't go back like that. However, for some class loaders you may be able to get the resource file be taking the fully qualified class name, replacing . with / and appending .class (so mypackage.MyClass becomes mypackage/MyClass.class (remember, may be case sensitive)).

Tom Hawtin - tackline
+1  A: 

Interesting ...

Would loading the ".class" as a file produce the input you need? In other words, I believe you need a file that has been compiled using javac or another compiler.

LES2
+5  A: 

You can usually just load the class as a resource from the Classloader.

Class c = ...
String className = c.getName();
String classAsPath = className.replace('.', '/') + ".class";
InputStream stream = c.getClassLoader().getResourceAsStream(classAsPath);

I would probably recommend using something from Apache commons-io to read the InputStream into a byte[]. IOUtils.toByteArray() should do the trick. Writing that code is really easy to get wrong and/or make slow.

Alex Miller
+1  A: 

You can try java instrumentation! In particular ClassFileTransformer maybe of interest to you!!

You simply override the transform method (from ClassFileTransformer), and your transform method will be called before each class is loaded. So then you cna do whatever class bytes.

Suraj Chandran
+1  A: 

Makes use of the ClassFileTransformer:

http://www.sixlegs.com/blog/java/definalizer.html

stacker