Runtime code generation and compilation - java

Say I have this code that uses some input (e.g. a URL path) to determine which method to run, via reflection:
// init
map.put("/users/*", "viewUser");
map.put("/users", "userIndex");
// later
String methodName = map.get(path);
Method m = Handler.class.getMethod(methodName, ...);
m.invoke(handler, ...);
This uses reflection so the performance can be improved. It could be done like this:
// init
map.put("/users/*", new Runnable() { public void run() { handler.viewUser(); } });
map.put("/users", new Runnable() { public void run() { handler.userIndex(); } });
// later
Runnable action = map.get(path);
action.run();
But manually creating all those Runnables like that has its own issues.
I'm wondering, can I generate them at runtime? So I'd have an input map as in the first example, and would dynamically create the map of the second example.
Sure, generating it is just a matter of building a string, but what about compiling and loading it?
Note: I know the performance increase is so little it's a perfect example of premature optimization. This is therefore an academic question, I'm interested in runtime generation and compilation of code.

The only ways to generate code dynamically are to either generate source code and compile it or to generate byte code and load it at runtime. There are templating solutiions out there for the former, and bytecode manipulation libraries for the latter. Without a real case and some profiling I don't think you can really say which will be better. From a maintenance point of view I think reflection is the best option when available.

I think you can achieve this with the code found here. It is some time ago I tried this, and I'm not sure anymore where I found the code I was using, but it seems that this is the same.
Basically, you use the 1.6 Compiler API, but use an "untraditional" way to find source files and write class files: The Compiler takes an Iterable<JavaFileObject>, where you plug in your memory-backed implementation, and a JavaFileManager that handles writing class files, where you hold the binary compiler output in memory.
Now that your code was compiled, you only need a custom ClassLoader that can read from your in-memory byte code and load the class with the right FQCN etc.
And, luckily, all that seems to be ready ;)

Actually, the reflection engine will generate similar invocation stubs internally, if you invoke the same methods over and over again. (Just use the same Method objects instead of recreating them again and again.)

Well, you could write code to a .java file, compile it with javac (how to do that) and load it into Java using Reflection.
But maybe, as a trade-off, you could also fetch the Method objects during initialization - so you would just have to call the invoke() method for every request.

Related

Best choice? Edit bytecode (asm) or edit java file before compiling

Goal
Detecting where comparisons between and copies of variables are made
Inject code near the line where the operation has happened
The purpose of the code: everytime the class is ran make a counter increase
General purpose: count the amount of comparisons and copies made after execution with certain parameters
2 options
Note: I always have a .java file to begin with
1) Edit java file
Find comparisons with regex and inject pieces of code near the line
And then compile the class (My application uses JavaCompiler)
2)Use ASM Bytecode engineering
Also detecting where the events i want to track and inject pieces into the bytecode
And then use the (already compiled but modified) class
My Question
What is the best/cleanest way? Is there a better way to do this?
If you go for the Java route, you don't want to use regexes -- you want a real java parser. So that may influence your decision. Mind, the Oracle JVM includes one, as part of their internal private classes that implement the java compiler, so you don't actually have to write one yourself if you don't want to. But decoding the Oracle AST is not a 5 minute task either. And, of course, using that is not portable if that's important.
If you go the ASM route, the bytecode will initially be easier to analyze, since the semantics are a lot simpler. Whether the simplicity of analyses outweighs the unfamiliarity is unknown in terms of net time to your solution. In the end, in terms of generated code, neither is "better".
There is an apparent simplicity of just looking at generated java source code and "knowing" that What You See Is What You Get vs doing primitive dumps of class files for debugging and etc., but all that apparently simplicity is there because of your already existing comfortability with the Java lanaguage. Once you spend some time dredging through byte code that, too, will become comfortable. Just a question whether it's worth the time to you to get there in the first place.
Generally it all depends how comfortable you are with either option and how critical is performance aspect. The bytecode manipulation will be much faster and somewhat simpler, but you'll have to understand how bytecode works and how to use ASM framework.
Intercepting variable access is probably one of the simplest use cases for ASM. You could find a few more complex scenarios in this AOSD'07 paper.
Here is simplified code for intercepting variable access:
ClassReader cr = ...;
ClassWriter cw = ...;
cr.accept(new MethodVisitor(cw) {
public void visitVarInsn(int opcode, int var) {
if(opcode == ALOAD) { // loading Object var
... insert method call
}
}
});
If it was me i'd probably use the ASM option.
If you need a tutorial on ASM I stumbled upon this user-written tutorial click here

Java Metaprogramming

I'm working on my first real project with Java. I'm beginning to get comfortable with the language, although I have more experience with dynamic languages.
I have a class that behave similar to the following:
class Single
{
public void doActionA() {}
public void doActionB() {}
public void doActionC() {}
}
And then I have a SingleList class that acts as a collection of these classes (specifically, it's for a 2D Sprite library, and the "actions" are all sorts of transformations: rotate, shear, scale, etc). I want to be able to do the following:
class SingleList
{
public void doActionA() {
for (Single s : _innerList) {
s.doActionA();
}
}
... etc ...
}
Is there any way to simply defer a method (or a known list of methods) to each member of the inner list? Any way without having to specifically list each method, then loop through each inner member and apply it manually?
To make things a bit harder, the methods are of varying arity, but are all of return type "void".
Unfortunately Java does not readily support class creation at runtime, which is what you need: the SingleList needs to be automatically updated with the necessary stub methods to match the Single class.
I can think of the following approaches to this issue:
Use Java reflection:
Pros:
It's readily available in the Java language and you can easily find documentation and examples.
Cons:
The SingleList class would not be compatible with the Single class interface any more.
The Java compiler and any IDEs are typically unable to help with methods called via reflection - errors that would be caught by the compiler are typically transformed into runtime exceptions.
Depending of your use case, you might also see a noticeable performance degradation.
Use a build system along with some sort of source code generator to automatically create the SingleList.java file.
Pros:
Once you set it up you will not have to deal with it any more.
Cons:
Setting this up has a degree of difficulty.
You would have to separately ensure that the SingleList class loaded in any JVM - or your IDE, for that matter - actually matches the loaded Single class.
Tackle this issue manually - creating an interface (e.g. SingleInterface) or a base abstract class for use by both classes should help, since any decent IDE will point out unimplemented methods. Proper class architecture would minimize the duplicated code and your IDE might be able to help with generating the boilerplate parts.
Pros:
There is no setup curve to get over.
Your IDE will always see the right set of classes.
The class architecture is usually improved afterwards.
Cons:
Everything is manual.
Use a bytecode generation library such as Javassist or BCEL to dynamically generate/modify the SingleList class on-the-fly.
Pros:
This method is extremely powerful and can save a lot of time in the long term.
Cons:
Using bytecode generation libraries is typically not trivial and not for the faint-hearted.
Depending on how you write your code, you may also have issues with your IDE and its handling of the dynamic classes.

Tool that lists all deprecated classes/methods that are no longer used anywhere?

I need to cleanup a some legacy code. Removing unused code is an important step.
Is there a tool that finds all deprecated code, removes all items which are still used somewhere and gives me a list of unused deprecated code?
For bonus points: Is there a tool which can find unused code non-deprecated code?
I'm aware that this is never perfect but I know for which cases I need special handling (as in DB drivers or classes that are referenced via DI).
I'm not completely certain that I understand your question. Do you want a tool that un-deprecates code that is still referenced? Any IDE will help you with that. Not automatically but removing an #Deprecated annotation is easily done with a global query-and-replace. After you have removed unused code, of course:
If all you want is to remove unused code, I have used the eclipse plugin ucdetector for this purpose in a previous project. While it does not actually remove the unused code it does give you a list of the methods, classes and constants that have no references so you can remove them yourself. This is a good thing.
As you point out yourself, there are some classes/methods that may seem to be unused using static analysis. In my opinion this makes it impossible to automate this task. You the coder will have to analyze every block of code that is reported to be unused.
If you are lucky enough to have excellent test coverage another option is to use a code coverage analysis tool, like cobertura, clover or emma.
I think this does what you want, but ignores #Deprecated. I seem to remember it adds an option in the project's contextual menu to find unused methods.
http://eclipse-tools.sourceforge.net/
IntelliJ identifies them as I write them. I'm not sure if there's an option to remove them automatically.
not sure your Q is a bit hard to grasp ... StackOverflow for me it is mostly about Code problem so I assume you want a way to get all Methods with the #Deprecated Annotation...
so basically you need to look into Java Reflection ..
So, for Example, let's say you want all the Deprecated Methods in the Date Class (Java.util.Date) this is what you can do ...
Class<?> clazz = Date.class; //Getting Class Obj of the Date Class
Method[] methods = clazz.getDeclaredMethods(); //Getting methods
for (Method m : methods) { //Inhanced For-Loop To get them-all
for (Annotation a : m.getAnnotations()) {
if (a instanceof Deprecated) {
System.out.println(m.getName()); // gitting the Methods Names
}
}
}
Using the Spoon library for transforming java source code:
String path = "src/main/java";
Launcher spoon = new Launcher();
spoon.addInputResource(path);
spoon.setSourceOutputDirectory(path);
spoon.addProcessor(new AbstractProcessor<CtMethod>() {
#Override
public void process(CtMethod method) {
if (method.hasAnnotation(Deprecated.class)) {
method.delete();
}
}
});
spoon.getEnvironment().setPrettyPrinterCreator(() -> {
return new SniperJavaPrettyPrinter(spoon.getEnvironment());
}
);
spoon.run();
See method removeDeprecatedMethods.

How to identify if an object returned was created during the execution of a method - Java

Original Question: Given a method I would like to determine if an object returned is created within the execution of that method. What sort of static analysis can or should I use?
Reworked Questions: Given a method I would like to determine if an object created in that method may be returned by that method. So, if I go through and add all instantiations of the return type within that method to a set, is there an analysis that will tell me, for each member of the set, if it may or may not be returned. Additionally, would it be possible to not limit the set to a single method but, all methods called by the original method to account for delegation?
This is not specific to any invocation.
It looks like method escape analysis may be the answer.
Thanks everyone for your suggestions.
Your question seems to be either a simple "reaching" analysis ("does a new value reach a return statements") if you are interested in any invocation and only if a method-local new creates the value. If you need to know if any invocation can return a new value from any subcomputation you need to compute the possible call-graph and determine if any called function can return a new value, or pass a new value from a called function to its parent.
There are a number of Java static analysis frameworks.
SOOT is a byte-code based analysis framework. You could probably implement your static query using this.
The DMS Software Reengineering Toolkit is a generic engine for building custom analyzers and transformation tools. It has a full Java front end, and computes various useful base analyses (def/use chains, call graph) on source code. It can process class files but presently only to get type information.
If you wanted a dynamic analysis, either by itself or as a way to tighten up the static analysis, DMS can be used to instrument the source code in arbitrary ways by inserting code to track allocations.
I'm not sure if this would work for you circumstances, but one simple approach would be to populate a newly added 'instantiatedTime' field in the constructor of the object and compare that with the time the method was call was made. This assumes you have access to the source for the object in question.
Are you sure static analysis is the right tool for the job? Static analysis can give you a result in some cases but not in all.
When running the JVM under a debugger, it assigns objects with increasing object IDs, which you can fetch via System.identityHashCode(Object o). You can use this fact to build a test case that creates an object (the checkpoint), and then calls the method. If the returned object as an id greater than the checkpoint id, then you know the object was created in the method.
Disclaimer: that this is observed behaviour under a debugger, under Windows XP.
I have a feeling that this is impossible to do without a specially modified JVM. Here are some approaches ... and why they won't work in general.
The Static Analysis approach will work in simple cases. However, something like this is likely to stump any current generation static analysis tool:
// Bad design alert ... don't try this at home!
public class LazySingletonStringFactory {
private String s;
public String create(String initial) {
if (s == null) {
s = new String(initial);
}
return s;
}
}
For a static analyser to figure out if a given call to LazySingletonStringFactory.create(...) returns a newly created String it must figure out that it has not been called previously. The Halting Problem tells us that this is theoretically impossible in some cases, and in practice this is beyond the "state of the art".
The IdentityHashCode approach may work in a single-threaded application that completes without the garbage collector running. However, if the GC runs you will get incorrect answers. And if you have multiple threads, then (depending on the JVM) you may find that objects are allocated in different "spaces" resulting in object "id" creation sequence that is no longer monotonic across all threads.
The Code Instrumentation approach works if you can modify the code of the Classes you are concerned about, either direct source-code changes, annotation-based code injection or by some kind of bytecode processing. However, in general you cannot do these things for all classes.
(I'm not aware of any other approaches that are materially different to the above three ... but feel free to suggest them as a comment.)
Not sure of a reliable way to do this statically.
You could use:
AspectJ or a similar AOP library could be use to instrument classes and increment a counter on object creation
a custom classloader (or JVM agent, but classloader is easier) could be used similarly

Rewriting method calls within compiled Java classes

I want to replace calls to a given class with calls to anther class within a method body whilst parsing compiled class files...
or put another way, is there a method of detecting usages of a given class in a method and replacing just that part of the method using something like javaassist.
for example.. if I had the compiled version of
class A { public int m() { int i = 2; B.multiply(i,i); return i; } }
is there a method of detecting the use of B and then altering the code to perform
class A { public int m() { int i = 2; C.divide(i,i); return i; } }
I know the alternative would be to write a parser to grep the source files for usages but I would prefer a more elegant solution such as using reflection to generate new compiled class files.
Any thoughts ?
As #djna says, it is possible to modify bytecode files before you load them, but you probably do not want to do this:
The code that does the code modification is likely to be complex and hard to maintain.
The code that has been modified is likely to be difficult to debug. For a start, a source level debugger will show you source code that no longer corresponds to the code that you are actually editing.
Bytecode rewriting is useful in certain cases. For example, JDO implementations use bytecode rewriting to replace object member fetches with calls into the persistence libraries. However, if you have access to the source code for these files, you'll get a better (i.e. more maintainable) solution by preprocessing (or generating) the source code.
EDIT: and AOP or Groovy sound like viable alternatives too, depending on the extent of rewriting that you anticipate doing.
BCEL or ASM.
I recently looked at a number of libraries for reading Java class files. BCEL was the fastest, had the least number of dependencies, compiled out of the box, and had a deliciously simple API. I preferred BCEL to ASM because ASM has more dependencies (although the API is reputedly simpler).
AspectJ, as previously mentioned, is another viable option.
BCEL is truly simple. You can get a list of methods in three lines of code:
ClassParser cp = new ClassParser( "A.class" );
JavaClass jc = cp.parse();
Method[] m = jc.getMethods();
There are other API facilities for further introspection, including, I believe, ways to get the instructions in a method. However, this solution will likely be more laborious than AspectJ.
Another possibility is to change the multiply or divide methods themselves, rather than trying to change all instances of the code that calls the operation. That would be an easier road to take with BCEL (or ASM).
The format of byte code for compiled Java is specified and products exist that manipulate it.
This library appears to have the capability you need. I've no idea how easy it is to do these transformations reliably.
If you don't mind using Groovy, you can intercept the call to B.multiply and replace it with C.divide. You can find an example here.
It's much easier to perform these operations ahead-of-time, where the executable on disk is modified before launching the application. Manipulating the code in memory at run time is even more prone to errors than manipulating code in memory in C/C++. Why do you need to do this?

Categories