Custom Annotation Processor to call specific methods at runtime - java

I'm trying to learn annotation processors. I'm trying to create a custom annotation that would send a certain object to a certain method. Both of them will be annotated with the same annotation.
For Example:
public void processData(#MyAnnotation("xyz") Object obj) {
// applies certain computations on the obj and then broadcasts the object using Android's Broadcast
}
Now there are 2 methods that have one argument of type Object. I want my annotaton processor to intercept the Android Broadcast & then call the method that's #MyAnnotation("xyz") annotation only.
#MyAnnotation("xyz")
public void method1(Object obj) {//...
}
#MyAnnotation("abc")
public void method2(Object obj) {//...
}
So in this case, the custom annotation processor will call ONLY method 1.
I'm not really sure if this is even possible, but if it's,
How can I acheive this? I don't want code. I want direction and may be a tutorial that can help me achieve this custom annotation on my own.

Related

Is it possible to use JMockit's Deencapsulation API to exchange method implementation?

So, basically, a there is some poor code that I cannot change that needs to be tested. Traditionally, you inject your mocked dependencies, but with this code, I cannot do so, because there are no setter methods. Worse, the function I need to test calls a bunch of static factory methods-I can't just use the MockUp strategy to swap out the implementation there, because there is no class instance to be injected at all.
In C/++, you can retrieve a pointer to a function and know it's type by it's signature. If you changed the pointer, then you could potentially change how the stack was constructed by the compiler and you could pass function's around and all that Jazz.
Is there a way to use the Deencapsulation API to replace a static method implementation? Using this, I could write my own class, descend from the traditional, but return mocked objects in order that dependency injection still be achieved?
public class TestedClass {
public static void testedMethod() {
UnMockableType instanceVariable =
UnInjectableFactory.staticFactoryConstructor();
instanceVariable.preventControlFlowInfluenceThroughMocking();
}
}
Easy enough:
#Test
public void exampleTestUsingAMockUp()
{
new MockUp<UnMockableType>() {
#Mock
void preventControlFlowInfluenceThroughMocking() {}
};
TestedClass.testedMethod();
}
Above, UnInjectableFactory isn't mocked because it doesn't need to be (assuming it simply instantiates/recovers an UnMockableType).
It could also be done with #Mocked and the Expectations API.

How to "proxy" a method in Java

First off, I'm not sure how to best word my solution so if I seem to be babbling at times then please consider this.
There is an interface in a library I wish to modify without touching the physical code,
public interface ProxiedPlayer {
// .. other code
public void setPermission(String permission, boolean state);
}
I have written a third party library for handling permissions and having to hook into my API to edit permissions may be a step some developers do not want to take. So I ask that when setPermission is called is it possible to have it invoke my invoke the appropriate method in my library that will handle permission setting whilst ignoring the pre-programmed code or not?
Here is the full interface I am attempting to proxy.
I have looked into the Java Proxy class but it seems you need an instance of the object you're trying to proxy in the first place. Given that the method can be called any time I do not believe this to be my solution but will happily stand corrected.
I do not have control over instantiation of classes implementing the ProxiedPlayer interface.
EDIT: Ignorant me, there several events that I can subscribe to where it is possible to get an instance of the player, would this be the appropriate place to attempt to proxy the method? One of these events is fired when a player joins the server and getting the instance of the player is possible.
Would the Proxy code need to be called for every instance of the ProxiedPlayer interface or is it possible to simply proxy every invocation of the method in an easier way?
My library is a plugin loaded after everything else that is essential has finished loading.
Edit #2:
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class InvocationProxy implements InvocationHandler {
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ProxiedPlayer player = (ProxiedPlayer) proxy;
if(method.getName().equals("setPermission")) {
// Call my code here?
}
return method.invoke(player, args);
}
}
Would something along the lines of what I have above work or am I barking up the wrong tree entirely?
If you do not want to touch the original source, then you only solve this problem by using a Java agent that redefines any class that implements the ProxiedPlayer interface to enforce your security check before calling the actual method. AspectJ together with a load-time-weaving agent was already mentioned as a possible solution for this but you can also implement a pure Java solution using my library Byte Buddy:
public class InterceptionAgent {
public static void premain(String arguments,
Instrumentation instrumentation) {
new AgentBuilder.Default()
.rebase(isSubtypeOf(ProxiedPlayer.class))
.transform(new AgentBuilder.Transformer() {
#Override
public DynamicType.Builder transform(DynamicType.Builder builder) {
return builder.method(named("setPermission"))
.intercept(MethodDelegation.to(MyInterceptor.class)
.andThen(SuperMethodInvocation.INSTANCE));
}
}).installOn(instrumentation);
}
}
With this agent, you more or less specify that you want to redefine any class that is a subtype of ProxiedPlayer to redefine (any) method named setPermisson in order to call a MyInterceptor (that would be your code) and to subsequently call the original implementation.
Note that the suggested implementation assumes that all classes implementing ProxiedPlayer implement the method of this interface and that there is only a single method of this signature. This might be too simple but it shows what direction to go.

Java modifying class on the fly (adding new method)

Is there a way to modify class instance in Java? For example I want to provide custom callback method.
How is it possible to provide separate method/context/scope for each instance of a class?
In javascript it's easy to modify an existing class. It's easy to pass an anonymous function as callback to any method as well. With it's context and scope.
Or do I have to extend my custom class for every request if I need a different callback?
You can do it on instantiation like:
Whatever w = new Whatever("Something") {
public void onWhateverDoThis() {
//...
}
};
So where I personally used it recently were callback methods of a modal:
ModalManager.show(new Modal("Title", "Text") {
public void onDismiss() {
//Do something on dismiss
}
public void onConfirm() {
//Do something on confirm
}
});
Java and Javascript are very different languages. You'll be very frustrated if you try to apply to one a programming paradigm that works in the other. I too was very frustrated with Javascript at the beginning, coming from Java, until I understood the fundamental differences between dynamic and static languages.
In this particular case I don't think it's a good idea to extend your class every time you need to use a different callback, as it would result in a large number of subclasses. If you need a lot of objects that differ only on a particular aspect, wouldn't it be better to have a class or interface that represents that particular aspect?
A possible solution (but not the only correct one by any means) would be to use the Strategy pattern: define an interface that represents a callback and implement the interface for every different callback you need. You can then pass those callbacks as parameters just as you do in Javascript, with the exception that those callbacks won't be able to access any non-public member of the class that calls them.
Also be sure to take a look at the Apache Commons Functor library, which is essentially about having objects that represent functions. I've never used it but, being Apache Commons, it sure would be my first stop if I had your requirements.
You can get frustrated easily, due classic nonfunctional Java is not for those run time goals you have mentioned.
But indeed, you can implement callback in java by using an interface like this:
Ref: CALLBACK PATTERN IN JAVA ENVIRONMENT
For example, suppose you want to be notified when an event happens.
You can define an interface like this:
public interface SomeEvent{
// A regular method, it can return something or take arguments
public void someEventMethod();
}
Then, define a class that will signal/notify the event, It needs to expect objects that implement the SomeEvent interface and then invoke the someEventMethod() method as appropriate.
public class EventNotifier{
private SomeEvent se;
private boolean somethingHappened;
public EventNotifier (SomeEvent event){
//Save the event object for later use.
se = event;
// Nothing to report yet.
somethingHappened = false;
}
//...
public void doWork (){
//Check the predicate, which is set elsewhere.
if (somethingHappened){
//Signal the even by invoking the interface's method
se.someEventMethod();
}
//...
}
// ...
}
Finally, write some code that expects to receive the event notification, it must implement the SomeEvent interface and just pass a reference to itself to the event notifier, like this:
public class CallMe implements SomeEvent{
private EventNotifier en;
public CallMe (){
//Create the event notifier and pass itself to it.
en = new EventNotifier (this);
}
//Define the actual handler for the event
public void someEventMethod(){
// Some event interesting must have occurred
// Do something...
}
}

Generic method invocation using annotations

I am creating a web application and I am injecting a SystemManager interface in it. All of my business logic resides behind it and pages just have to request data from it. I would like to create a generic implementation which would get a method signature and based on the annotation it would invoke the correct method in the system.
The implementation of this interface acts like a facade pattern - it just calls methods on different objects.
The current implementation is
SystemManager.java
void executeA();
void executeB();
SystemManagerImpl.java
void executeA(){
SystemA.exectueA();
}
void executeB(){
SystemB.exectueB();
}
But I would like to replace it with some generic solution like
SystemManager.java
#SystemA
void executeA();
#SystemB
void executeB();
SystemManagerImpl.java
void genericMethod(){
// based on the annotation of the method received I am calling correct System class and invoking correct method
}
I dont think this is possible but still I am open to suggestions.

Java Inheritance and Wrapping

I have a generated object that I want to:
Preserve existing functionality of without injecting into the constructor and rewriting every method to call injectedObject.sameMethod().
Add additional functionality to that generated object without modifying the generated object.
add additional functionality to.
For example:
public class GeneratedObject {
public String getThis() { ... }
public String getThat() { ... }
}
public interface ObjectWrapper {
String doThisWithThat();
}
public class ObjectWrapperImpl extends GeneratedObject implements ObjectWrapper {
String doThisWithThat() { ... }
}
However, downcasting is not allowed, what is the proper implementation without rewriting a bunch of redundant code just to wrap the object?
I think decorator pattern may help you: "The decorator pattern can be used to extend (decorate) the functionality of a certain object at run-time, independently of other instances of the same class"
Have you tried aspectj? http://www.eclipse.org/aspectj/doc/next/progguide/semantics-declare.html It's a bit complicated but so is your request.
If you can extract an interface from GeneratedObject, then it would be possible to do this using a dynamic proxy. You would make a proxy which implemented the extracted interface and ObjectWrapper, with an invocation handler which passed all calls to methods in the GeneratedObject interface through to the delegate, and sent the doThisWithThat() calls elsewhere.
Proxies aren't pretty, but the ugliness is at least well-localised.

Categories

Resources