Bytecode enhancement for fields in a class - java

Is it possible to add "hooks" to a class via bytecode enhancement that execute code whenever a class field is read or written? For example, I'd like to automatically set a "dirty" flag whenever a new value is assigned to a field.
If so, which libraries are best suited to implement this functionality?

I'd suggest you to read about AspectJ. Probably this is the tool you are looking for.

Here is how to generate getters and setters using the ASM framework. That should get you started.
http://asm.ow2.org/doc/faq.html#Q9
You can even let your bytecode-rewriter hook into the class-loader and do the rewriting on the fly.

Related

Can I use custom annotations to classify Java classes?

Is it possible that use self defined Annotation to classify java class into different product function ? (Following are my thoughts)
If not, are there any other method to achieve the same purpose in Android project?
Step1: use self defined annotation to make clear java class's function
#SelfDefinedAnnotation( "product-function-a" )
class MyClass {
void func() {
//do something
}
}
Step2: during building period, generate a mapping file like this
MyClass -> product-function-a
YourClass -> product-function-b
I'm not sure about android (never worked with it), but in pure java its possible for sure.
You should define an annotation with retention policy SOURCE and since you're talking about build time, define an annotation processor. This is something that is "hooked" into the compilation process and allows creating such a mapping (I assume you want to store it in some kind of file, maybe *.properties file, or even generate a java source code with these definitions.
The annotation processor is broad topic, there are many ways to register them, so it pretty much depends on how do you build your stuff exactly, but its a general direction.
Please check out this tutorial it talks about annotation processors, the ways to register them, to associate with your custom annotation and so forth.
One suggestion though, if you're about to generate Java Source class and not just a properties file, this tutorial goes "low level" and tries to prepare the syntax by itself, I suggest using a much nicer (IMO) Java Poet library that will help to generate a proper java code

How to modify or substitute private method in a java class

I have a class which behavior I would like to change. I need to replace private method with another realization. Common reflection techniques allow to modify private variable or to invoke private methods. But I find little information about replacing entire methods.
I presume that there are advanced techniques to do so. May be its impossible with standard java reflection but there are probably other tools to recompile byte code in runtime.
Modify & replace:
One option is to mask the class with a modified copy (modify code, recompile code, add modified classes to the classpath before patched classes), similar to the approach used here to inspect how a normally unavailable method works.
If you do not have sources to modify, you can "reverse" almost any .class file into more-or-less readable source code using decompilers. Notice that, depending on licensing, you may not have permission to do so and/or to redistribute your changes.
Patch via agent:
You can also patch the methods using the -javaagent:<jarpath>[=<options>] commant-line option. The "agent" is a jar that gets to modify loaded classes and alter their behaviour. More information here.
Mock:
If you have control over where the methods are called, you can replace the target instance with a stubbed version. Libraries such as Mockito make this very, very easy:
LinkedList mockedList = mock(LinkedList.class);
// stubbing appears before the actual execution
when(mockedList.get(0)).thenReturn("first");
Even though Mockito does not support mocking private methods natively (mostly because it is considered bad manners to look at other classes' privates), using PowerMock allows you to do so (thanks, #talex).
You can't replace method in runtime (at least without hack into JVM). But you can replace whole class. There are several way to do it. For example you can use thing called "aspect".
But from my experience I can say that if you need to do this you have wrong turn somewhere in beginning of you way.
Maybe you better make one step back and look at whole picture
Instead of going for advanced techniques, there is a simple trick to achieve this.
If you class is part of an open-source jar, get source code of this class file from grepcode.com. Change the method that you want to change and compile it. And update your jar file/classpath with this updated class file.

Creating fields dynamically java

i was wondering if their is any way to dynamically create a static field for a class during run-time using reflection or a related API. If needed i can use the java native interface to accomplish this task if someone could tell me the appropriate steps. I don't want to use any data structures such as a hash-map, as i am doing this completely for fun. Please don't suggest using maps as i am not using this for any real program this is a completely theoretical situation. Thanks.
You could do this during class load time using bytecode manipulation.
This is a very complex solution though, so I'd consider other options.
It also does not help too much to have a new field that is not known at compile-time, because you cannot compile anything against it. If you are going to use reflection to access it, you might as well use a Map in the first place.
Java doesn't support metaprogramming or runtime programming in a way that is particularly nice or effective.
You could use a decorator pattern. You could pass the object that you want to add a static field to into a wrapper object. This wrapper would have the static field and the calls to the wrapper object would relate to the wrapped object.
If you could provide more details about the functionality you're looking for I could try to provide a better solution. You might be better off looking into another language that does support runtime programming if you absolutely need it to be done in that way.

java code template

I'm trying to make a code template that will generate tostring, constructor from field, and a default constructor.
I already looked at Useful Eclipse Java Code Templates and in http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.jdt.doc.user/reference/ref-tostring-templates.htm but it was not what I was looking for.
I tried this plugin http://eclipse-jutils.sourceforge.net/ but I still need to manually select an option in the menu (and it doesn't have a "constructor from fields" option).
I need to generate these methods and constructors for more then 100 classes so this the best way i found coz eclipse dont give tool to do it for more then one class and for this one class that he give this tool i need to do it one by one the (generate tostring ,constructor from field and also default constructor)
i will love to some help or some advice on a way to create these methods for all my classes, automatically.
thanks in advance.
I don't know of a plugin that will do this for multiple classes.
I'd just do it manually, even though it'd take time.
You could also use reflection and a scripting language like Groovy/JRuby/etc. to create the constructors, and rely on something like Commons' ToStringBuilder to create a toString, or just use reflection again.
(One problem is if you don't want a property in the constructor or toString you need to have a mechanism to tell the generator as much.)
I have just used Practically Macros, within a few minutes of install from the market place, I could generate *constructors*, getters / setters, toString, hashcode and equals (basically chaining the standard eclipse commands) in a single command. Just what I was looking for and saved me loads of time. I can also see a lot more uses for it, well done to Earnst (the creator).

Alternative to annotations?

I have situation where I cannot add annotations to class, but is there any way to add some kind of meta data to bean (code) that you cannot edit, but what would survive refactoring? What if I extend bean and then add annotations to that class is that possible?
The old way, use marker interfaces, that is interfaces without methods like Serializable or Cloneable.
Depending on your IDE, all you need to do is refer to your class or methods or fields in a text files such a properties or XML. Your IDE will find these and offer to perform a text find/replace when you rename classes/method/fields. (Though some refactors such a moving a method to another class won't work so well)
You could consider AOP
http://static.springsource.org/spring/docs/2.5.x/reference/aop.html
It allows you to externally add behaviour to specific methods, without editing your class. The extra code can be before, after, or around methods.
Without telling us exactly what you want to achieve, it's hard to guess what you need.
Do you need meta data for use from some other code or it should be readable for human?
You can use code instrumentation to add any data into your classes (javassist, some aop etc)
You could add a parallel class hierarchy with meta data. Sort of like the BeanInfo classes provide meta data for Java beans.
If you can't modify the code, you could put the meta data in a global map, with the Class as the key.

Categories