I am attempting to use aspectJ to intercept calls to public methods on classes which implement my Loggable interface. Loggable is a marker interface and defines no methods.
I have a before advice, in which I want to get the name of the Concrete class containing the method that is being called. By using thisJoinPoint.getTarget() I can get the concrete class, but when I call thisJoinPoint.getTarget().getClass.getName() I get a stackoverflow exception.
I'm pretty sure that this is because I am calling a public method on the Concrete class, which then causes my before advice to re-fire.
Here's my pointcut :
pointcut dave() : target(Loggable) && call (public * *(..) ) ;
How do I limit this to only the public methods that are defined directly within the concrete class, ignoring those that are inherited from java.lang.Object?
While StackOverflow is not an opinion-based discussion forum, I am going to answer with a few concrete examples in order to be a bit more explicit:
If !this(LoggerAspect) works for you, use it. But beware: It will not keep the advice from firing when a call() is indirectly, i.e. a method called by your advice, calling another method.
Option 1: use execution() instead of call()
When using an execution() pointcut, AspectJ fires only when the callee is executed, i.e. in one single place, not in many places where your callee is called by the caller. This is more efficient and in this context whould work for you because you seem to control the called code. Only if the aspect weaver/compiler does do have access to the callee, you should weave the caller using a call() pointcut.
As a side effect, executions of 3rd party library or JDK code will not be intercepted by execution() anyway because it is not accessible to the compiler/weaver with one exception being 3rd party libs (but not JDK code) woven via LTW (load-time weaving).
Option 2: adviceexecution() pointcut
By combining your pointcut with && !adviceexecution() you can stop the advice from firing when a call() is made while any advice in any of your aspects is being executed. This also excludes indirect calls and works nicely for a single advice. But if you combine multiple aspects and want your advice to still fire when a call() is made by another aspect's advice, you probably want to use another option such as...
Option 3: within() pointcut
By combining your pointcut with && !within(LoggerAspect) you can stop the advice from firing when a call() is made from within any advice in your LoggerAspect. Calls from other aspects are still being logged.
What exactly you want to achieve determines which option (or combination thereof) you should choose. There is no simple answer because I do not know your exact situation.
Related
I am wondering if I can use custom annotation to call some method right after annotated one. For example I have a class that holds some settings that can also notify objects that something has changed (for example user changed something in settings panel). Not all listeners are interested in all types of events, so MyEvent is enum. Now I have structure like this:
class Settings
{
private ArrayList<Listeners> listeners;
private void notifyListeners(MyEvent e)
{
// notify all listeners that something was changed
}
public void setSomeOption(int value)
{
// validate parameter, store it etc.
notifyListeners(MyEvent.SOME_INTEGER_SETTING_CHANGED);
}
}
Of course listening object has to check type of event and ignore it or perform some action, but it is not the case here.
I am interested if I can achieve this with annotations, like this
#NotifyAnnotation(MyEvent.SOME_INTEGER_SETTING_CHANGED)
public void setSomeOption(int value)
{
// validate parameter, store it etc.
// NO NEED TO CALL NOTIFY HERE - WILL BE HANDLED BY ANNOTATION
}
In JUnit for example, we have #Before or #After annotations, and I am wondering if JUnit has own annotations parser that handles method annotated this way, or this kind of behavior can be done simpler, since annotations can be #Retention(value=RUNTIME).
I know that in this example it might look over-complicated and calling notifyListeners() is much simper, but I wan't to know if annotation can be used the way I described, and if yes, can i get some tips? I don't expect ready solution, just a hint if this is possible and what should I take in consideration.
yes, you can do it but you have to use a framework or write one by yourself. you can use for example spring aspects and #After advice (or any other proxy mechanism). you can also use full aspectj for this. another option is to write it by yourself using reflection api. in last case you will need some kind of inversion of control - some mechanism that will launch your method and then the other method
In annotations you need a class that checks for it. they don't work on themselves.
The way systems check for them are with reflection.
Annotation<NotifyAnnotation> a = method.getAnnotation();
And explicitly call their methods
a.notifyListeners(a.evt);
I can't see any advantage with your case. but I see full of disadvantages. They should not be used in actual coding, just for test systems or similar scenarios, where an external system has control on your class.
It could be do that using bytecode manipulation (JAssist, Asm, Java Rocks ...). All the classes would be instantiated thru a Factory that would identify annotated methods and would inject in the first line of this method a call to the method specified in its annotation.
I want to listen on method calls in order to attach additional behavior dynamically around the call. I've already done it on JUnit methods with a custom annotation and runner. I'm trying to do it on a standard java application.
The main idea is to do:
#Override
public void beforeInvoke (Object self, Method m, Object[] args){
Object[] newargs = modifyArgs (args);
m.invoke (self, newargs);
}
It's just an abstract idea, I don't have any concrete example, but I'm curious if it's possible in java.
I've found some approaches:
java.lang.reflect.Proxy.newProxyInstance(...)
where a proxy is defined for an interface only (but not used to decorate concrete classes). It seems similar to injection pattern and it's a different concern.
Another approach here using a factory pattern with the ProxyFactory class. This other solution requires explicit calls to create() method to produce object proxies listening on method invocations. So, if you bypass it by using natural constructors of your classes, it's not working. It's very constraining if you must explicit a call to a factory each time you have to create an object.
There is a way to do it with transparency ?
Like Proxy.newProxyInstance() but working also on concrete classes ?
Thanks.
Well,this is commonly seen with Spring Framework and Aspect Oriented Programming. Since you delegate your constructor calls to Spring, it is quite easy for Spring to put a proxy in place to intercept calls to the actual objects.
As far as I can tell, the only way to intercept calls is to use a proxy. Either in the way you mentioned or using Spring and AOP.
I think cglib let you instrument concrete classes.
As far as I know there is no easy way to intercept method calls that are called on a concrete class.
As mentioned you could manipulate the bytecode during compilation (as Used in AOP) or at class loading time (as used from cglib).
Another product to instrument Classes would be jmockit (http://jmockit.org/). Usually I would use this special kind of black magic only in testing environments and not in an productive environment.
Another way you could go is Annotation Processing. It work's during compiling process. You have to write a Processor which will walk through your source code and generate source-code that contains the original code plus the enhanced method-calls you need.
Depending on how much source-code you have to enhance, this method might be a good idea, but in general it is a lot of work.
Here's a link (https://deors.wordpress.com/2011/10/08/annotation-processors/).
Despite usually it's used in combination with annotations, this is not a strict requirement.
In AOP in Java (AspectJ) when we talk about method pointcuts, we can differentiate them into two different sets: method call pointcuts and method execution pointcuts.
Basing on these resources here on SO:
execution Vs. call Join point
Difference between call and execution in AOP
And some AspectJ background, we can tell that basically the differences between the two can be expressed as the following:
Given these classes:
class CallerObject {
//...
public void someMethod() {
CompiletimeTypeObject target = new RuntimeTypeObject();
target.someMethodOfTarget();
}
//...
}
class RuntimeTypeObject extends CompileTypeObject {
#Override
public void someMethodOfTarget() {
super.someMethodOfTarget();
//...some other stuff
}
}
class CompiletimeTypeObject {
public void someMethodOfTarget() {
//...some stuff
}
}
A method call pointcut refers to the call of a method from a caller object which calls the method of a target object (the one which actually implements the method being called). In the example above, the caller is CallerObject, the target is RuntimeTypeObject. Also, a method call pointcut refers to the compile time type of the object, i.e. "CompiletimeTypeObject" in the example above;
So a method call pointcut like this:
pointcut methodCallPointcut():
call(void com.example.CompiletimeTypeObject.someMethodOfTarget())
Will match the target.someMethodOfTarget(); join point inside the CallerObject.someMethod() method as the compile type of the RuntimeTypeObject is CompiletimeTypeObject, but this method call pointcut:
pointcut methodCallPointcut():
call(void com.example.RuntimeTypeObject.someMethodOfTarget())
Will not match, as the compile time type of the object (CompiletimeTypeObject) is not a RuntimeTypeObject or a subtype of it (it is the opposite).
A method execution pointcut refers to the execution of a method (i.e. after the method has been called or right before the method call returns). It doesn't give information about the caller and more important it refers to the runtime type of the object and not to the compile time type.
So, both these method execution pointcuts will match the target.someMethodOfTarget(); execution join point:
pointcut methodCallPointcut():
execution(void com.example.CompiletimeTypeObject.someMethodOfTarget())
pointcut methodCallPointcut():
execution(void com.example.RuntimeTypeObject.someMethodOfTarget())
As the matching is based on the runtime type of the object which is RuntimeTypeObject for both and RuntimeTypeObject is both CompiletimeTypeObject (first pointcut) and a RuntimeTypeObject (second pointcut).
Now, as PHP doesn't provide compile time types for objects (unless type-hinting is used to somehow emulate this behaviour), does it make sense to differentiate method call and method execution pointcuts in a PHP AOP implementation? How then will the pointcuts differ from each other?
Thanks for the attention!
EDIT: #kriegaex has pointed out another interesting aspect between call and method execution pointcuts in AspectJ.
Thank you for the great and concise example. I have tried to make an example myself too and here is what I understood:
In case A (I use a 3rd party library), I actually can't intercept the execution of a library method because the library itself was already compiled into bytecode and any aspect concerning that library was already woven into that bytecode too (I would need to weave the sources in order to do so).
So I can only intercept the method calls to the library methods, but again I can only intercept the calls to library methods in my code and not the calls to library methods from within the library itself because of the same principle (the calls to library methods from within the library itself are also already compiled).
The same applies for System classes (same principle) as is said here (even if the reference refers to JBoss):
https://docs.jboss.org/jbossaop/docs/2.0.0.GA/docs/aspect-framework/reference/en/html/pointcuts.html
System classes cannot be used within execution expressions because it
is impossible to instrument them.
In case B (I provide a library for other users), if I actually need to intercept the usage of a method of my library either in the library itself or in the future user code which will use that method, then I need to use an execution pointcut as the aspect weaver will compile both the method execution and call pointcuts that concern my library and not the user code which will use my library methods (simply because the user code doesn't exist yet when I am writing the library), therefore using an execution pointcut will ensure that the weaving will occur inside the method execution (for a clear and intuitive example, look at the #kriegaex pseudo-code below) and not wherever the method is called within my library (i.e. at the caller side).
So I can intercept the usage (more precisely, execution) of my library method both when the method is used within my library and in the user's code.
If I had used a method call pointcut in this case, I would have intercepted only the calls made from within my library, and not the calls made in the user's code.
Anyway, still think if these considerations make sense and can be applied in the PHP world, what do you think guys?
Disclaimer: I do not speak PHP, not even a little. So my answer is rather general in nature than specific to PHP.
AFAIK, PHP is an interpreted rather than a compiled language. So the difference is not compile time vs. runtime type, but semantically rather declared vs. actual type. I imagine that a PHP-based AOP framework would not "compile" anything but rather preprocess source code, injecting extra (aspect) source code into the original files. Probably it would still be possible to differentiate declared from actual types somehow.
But there is another important factor which is also relevant to the difference between call vs execution joinpoints: The place in which the code is woven. Imagine situations in which you use libraries or provide them by yourself. The question for each given situation is which parts of the source code is under the user's control when applying aspect weaving.
Case A: You use a 3rd party library: Let us assume you cannot (or do not want to) weave aspects into the library. Then you cannot use execution for intercepting library methods, but still use call pointcuts because the calling code is under your control.
Case B: You provide a library to other users: Let us assume your library should use aspects, but the library's user does not know anything about it. Then execution pointcuts will always work because the advices are already woven into your library's methods, no matter if they are called from outside or from the library itself. But call would only work for internal calls because no aspect code was woven into the user's calling code.
Only if you control the calling as well as the called (executed) code it does not make so much difference whether you use call or execution. But wait a minute, it still makes a difference: execution is just woven in one place while call it woven into potentially many places, so the amount of code generated is smaller for execution.
Update:
Here is some pseudo code, as requested:
Let us assume we have a class MyClass which is to be aspect-enhanced (via source code insertion):
class MyClass {
method foo() {
print("foo");
bar();
}
method bar() {
print("bar");
zot();
}
method zot() {
print("zot");
}
static method main() {
new McClass().foo();
}
}
Now if we apply a CallAspect like this using call()
aspect CallAspect {
before() : call(* *(..)) {
print("before " + thisJoinPoint);
}
}
upon our code, it would look like this after source code weaving:
class MyClass {
method foo() {
print("foo");
print("before call(MyClass.bar())");
bar();
}
method bar() {
print("bar");
print("before call(MyClass.zot())");
zot();
}
method zot() {
print("zot");
}
static method main() {
print("before call(MyClass.foo())");
new McClass().foo();
}
}
Alternatively, if we apply an ExecutionAspect like this using execution()
aspect ExecutionAspect {
before() : execution(* *(..)) {
print("before " + thisJoinPoint);
}
}
upon our code, it would look like this after source code weaving:
class MyClass {
method foo() {
print("before execution(MyClass.foo())");
print("foo");
bar();
}
method bar() {
print("before execution(MyClass.bar())");
print("bar");
zot();
}
method zot() {
print("before execution(MyClass.zot())");
print("zot");
}
static method main() {
print("before execution(MyClass.main())");
new McClass().foo();
}
}
Can you see the difference now? Pay attention to where the code is woven into and what the print statements say.
PHP is dynamic language, so it's quite hard to implement call joinpoints because there are many languages features like call_user_func_array(), $func = 'var_dump'; $func($func);
#kriegaex wrote a good answer with main differences between call and execution types of joinpoints. Applying to the PHP, only possible joinpoint for now is an execution joinpoint, because it's much easier to hook execution of method|function by wrapping a class with decorator or by providing PHP extension for that.
Actually, Go! AOP framework provides only execution joinpoint, as well, as FLOW3 framework and others.
I'm trying to intercept a method of an interface annoted with a JAX-RS #POST. My Pointcut works for all non-interface methods and if the #POST-Annotation is directly at the called method.
The interface method to intercept:
#POST
Response postToConnector(#Context CallContext callContext, String contentStream) throws Exception;
The Pointcut to match the method:
#Pointcut("call(#(javax.ws.rs.DELETE || javax.ws.rs.GET || javax.ws.rs.HEAD || javax.ws.rs.OPTIONS || "
+ "javax.ws.rs.POST || javax.ws.rs.PUT) public * org.myapp..webapi..*(..))")
public void anyPublicWebApiPointcut()
{
...
}
The interface is inside a package com.myapp.social.webapi.v1 and even if I change the method to public AspectJ will not intercept the call.
Is there anything to change within my Pointcut? How can I make this working?
What a call() pointcut does is, as the name implies, intercept calls to a certain method/constructor. In order for this to work, the caller (i.e. the piece of code where the call is located) must be under your control, i.e. it must have been woven. So if e.g. you have woven the org.myapp..webapi..* classes and the call has also been issued from there, it should work. That it does not work makes me assume that the POST calls come from somewhere outside the woven code, e.g. the JRE or a 3rd party library.
So if org.myapp..webapi..* is under your control, i.e. you can weave aspect code into it, you should use an execution() pointcut. In contrast to call() it is woven into the callee, i.e. into the code where the method is defined, not into the many places where it is called. This way you can intercept all method executions, regardless if they come from within your application or 3rd party or JRE code. It will even work for method executions triggered by reflection.
call() and execution() have fundamentally different semantics which pay off to learn and understand. As a rule of thumb, you should try to use execution() whenever possible, i.e. whenever the callee is weavable for you. call() is just your fall-back if you cannot weave into the callee and must use the caller. call() can also make sense if for some reason you need to make any decisions based on the joinpoint context, e.g. in an around() advice which decides to call or not to call the original method based on some condition.
I have an abstract class called ChainHandler and many implementations of the ChainHandler.
Other programmers will write other implementations of that ChainHandler.
My program implements the Chain of Responsibility design pattern.
Each concrete implementation of the ChainHandler implements a handle method.
public abstract void handle(SomeclassA a);
If one handler can handle "a", it handles it and the chain stops. If not,"a" is passed to the next Handler until it hits the end of the chain.
I want each concrete handler to have a list of all "a"s it was able to handle. But I don't want to make the concrete classes developer to remember to write it to a list on success.
Is there a elegant way of doing it?
My best idea was the following:
1 - Change the handle method to protected at the concrete classes, make it return a boolean and change the name to innerhandle;
2 - Change the handle method at the abstract class to public and it calls the innerhandle. On success, it adds the object to the list.
The second option is surely better (and it relies on the Template method pattern) making it harder for someone implementing a subclass of doing it wrong, you can even make the handle method final so no one will ever be able to change it's behavior and break without noticing it.
The servlet API has such an example, the init method that takes a ServletConfig parameter can be overridden and it's rather common to see people forgetting to call super and the original init(ServletConfig) method, so you should try to avoid this same mistake.