Related to: Is there a way to obtain the bytecode for a class at runtime?
I'm adding durability to Clojure, and I'm finally at the point where I'm ready to add functions. In Clojure, functions are byte compiled into classes with invoke methods (among others). In this way, functions are first class. To make these durable, I need to serialize and deserialize these classes. How do I get the bytecode for the class without having access to the .class file?
Please correct me if I'm mistaken, but using an agent requires spawning a separate VM with the agent connecting to the first VM. I need to do it from the same VM.
It's not enough to use Serializable to set and get the Class object. Upon deserializing, I need to load the class, and upon subsequent VM instances, there may be a class name collision. I need to modify the bytecode to rename the class to something unique at deserialization/class-load time.
Remember,JVM only works during Run Time means after the compilation of Source Code into Byte Code..but before that javac compiles the source code into byte code. JVM converts bytecode into corresponding machine code by JIT Compiler and Java Interpreter.
They can be executed by intepretation, just-in-time compiling, or any other technique that was chosen by the designer of a particular JVM. A method's bytecode stream is a sequence of instructions for the Java virtual machine. Each instruction consists of a one-byte opcode followed by zero or more operands.
JVM is the abbreviation for Java virtual machine which is basically specification that provides a runtime environment in which Java byte code can be executed i.e it is something which is abstract and its implementation is independent to choose the algorithm and has been provided by Sun and other companies.
Nope. Byte code will differ on which compiler you use it in.
You could write your own ClassLoader
and hack up a scheme which records the bytecode as classes are loaded.
You would need to override findClass
to find the class file yourself, load it into memory, save the data somewhere (for later serialization), then call defineClass
to define that class in the JVM.
Unless you are running code via a tricky classloader, you should be able to do something like this:
Class<?> clazz = ....
String className = clazz.getCanonicalName(); // e.g. "foo.Bar"
String resourceName = ... // map className to a resource name; e.g. "/foo/Bar.class"
InputStream is = clazz.getClassLoader().getResourceAsStream(resourceName);
This gives you a handle on the contents of the ".class" file ... if it can be found.
Caveats. Some classloaders might:
If this approach doesn't work, you are pretty much out of options because the JVM does not provide a way to access the actual bytecodes that were loaded.
You can also use the Java Instrumentation API for this. You get access to the bytes of the classfile before defineClass is invoked. You can change them too!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With