I want to use AOP concept to time execution time of some methods that I mark with an annotation that I created. My problem however is that I refer to the annotated method internally, from within the same class. For example:
public void login(params) {
some logic ...
performLogin();
some logic ...
}
#Measured
public void performLogin() {
some logic ...
}
This is a known issue caused by the fact that Spring AOP is using proxy based approach that does not "see" the internal calls within the same class. Apparently I can solve this situation by using AspectJ instead of Spring AOP. If I understand correctly, it can be configured from within Spring itself. From what I found, it looks like I should include #EnableAspectJAutoProxy annotation to configure Spring to use AspectJ instead of its own AOP. Unfortunately, it did not help and after adding the annotation, the interception of the annotated method did not occur.
There is a lot of information on this topic in Spring reference documentation and I got a bit lost. Is there anything else I am supposed to do so that AspectJ will be used?
P.S. Please note that I cannot refactor the whole class and move the calling method outside.
P.P.S. I also verified my pointcut configuration. I annotated the calling method which is invoked externally and it worked fine.
Proxies can only achieve a sub-set of the full capabilities of the actual AspectJ system, basically advice that wraps methods. Due to their nature proxies have following limitations:
interception on external calls only (while breaching proxy boundary)
interception on public members only (private/protected can't be intercepted)
unawareness to local calls (or calls with this or super)
<aop:aspectj-autoproxy /> is not enough - it only wraps methods, you need something like this: <context:load-time-weaver/>
If you want to be able to advise fields for example, you would need to enable the use of Native AspectJ.
Related
I have a component declared using the #Component annotation, in which there is a set of methods that implement communication with another api, in my product there are operations that are prohibited for a user with an anonymous id. I want to create an annotation, for example #ProhibitedForAnonym, which, every time the method is called, will check the ID of the anonymous customer, with the ID in the method parameter and throw an error if the IDs match. But I don't understand how to do annotation processing in OSGI, maybe some kind of interceptor?
There is no general interception framework in OSGi. However, you could do interception in the following ways:
Don't. Personally, I feel that since we've lambdas a code-based solution has won hands on over a 'magic' annotation check. It is about the same number of characters but a lambda based call allows me to single step, provide context to the security check, does not suffer from the THIS problem, is testable, and requires no complex framework with lots of bug opportunities.
Use the byte code weaving support in OSGi. You need to register a weaver early and then weave any class that has these annotations. You can take a look at https://github.com/aQute-os/biz.aQute.osgi.util/tree/master/biz.aQute.trace for an example of how to use the byte code weaver. Make sure your weaver is there first. If you use bndtools you can add it to the -runpath to run before anybody else. Or use start levels.
Use proxying. You can 'hide' and original service with the Service Hooks and then register a proxy. In the proxy you can then do the annotation check. This also requires that this code runs first and cannot be updated. I think the spec has an example of this
You might want to read: https://www.aqute.biz/appnotes/interceptors.html
I have a requirement to intercept every thrown exception and do something with it. I am using this part of code:
#Aspect
#Component
class Advice
{
#AfterThrowing(pointcut = "execution(* mail.service..*.*(..))", throwing = "throwable")
public void sendError(Throwable throwable)
{
System.out.println("exception thrown");
}
}
This somehow does not work as I expected. This pointcut seems to 'affect' only the public methods(which is expected from Spring AOP, I suppose?) but it prints the String only in certain methods, for example, methods that are declared in my Spring configuration class(i guess its because they are initialized before the app starts) and not in the other ones.
I tried to get this aspect working for any exception thrown, but I had no success. Is this somehow connected with the fact that I am using Spring AOP and not full AspectJ?
Also, my project is written in Kotlin(I wrote the aspect in Java so IJ can support it), will this have an impact on using AspectJ? I had a lot of troubles to get it working (because of final classes) and I am wondering if it's going to be a lot harder when I start writing more advanced AspectJ code.
Thanks!
Yes, Spring AOP only works for Spring components and only for public methods (plus protected and package-protected ones for CGLIB proxies). It also does not work for self-invoked methods like this.doSomething() because those do not go through the proxy. Only if your exceptions escalate outside a method called via proxy, Spring AOP will be able to intercept it.
AspectJ with LTW (load-time weaving) or CTW (compile-time weaving) does not have any of those limitations, plus you can also handle exceptions in constructors, not just in methods.
Never having used Kotlin before, I cannot tell you what possible problems might be there, but final classes should not be a problem as such because AspectJ instruments the classes' bytecode directly, not via proxies. Just give it a try.
BTW, just in case you only use Spring because of AOP: You do not need to use Spring at all in order to apply AOP to your classes because AspectJ is 100% independent of Spring. You can use them together or not, your choice. I for example never use Spring, but just Java SE + AspectJ.
I am new to Annotations and new to StackOverflow and this is my first question. I am trying to write custom annotations which will help me trace and log method executions.
For example:
class A
{
#Logthis
void methodA();
}
Here whenever the method methodA() is executed, I want to log to a file telling "we are entering the methodA in class A" and when methodA is over "we are exiting methodA in class A" something like this. We vil have a number of classes and methods.
I know that this can be done using AspectJ. I have done it by defining pointcuts and joinpoints. But I want to do it using custom annotations.
It will be very helpful if anyone can guide me as to how to go about this.
Thanks in advance.
Using AspectJ you do the following :-
Create an Aspect Class annotated with #Aspect
Annotation a method in the class with #Around and define the value to be execution on classes that you have annotated. You will also need to have enabled proxying of you classes by AspectJ.
#Aspect
public class LoggerAspect {
#Around(value = "execution(#you.custom.Annotation * *(..))")
public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable
{
// DO LOGGING HERE
}
}
You can use Log4J. Here is a tutorial of it:
http://javakane.blogspot.fr/2012/07/automate-log4j-logging-with-aop-and.html
It seems you want to roll your own aop framework. IMHO this is not a very good idea, a lot of work has gone into AspectJ and you would benefit greatly from using it. But I suspect you already know that :) It is strange that you can use NO external jars, that is rather stringent even for commercial software.
But if you really need to do it, you can probably learn from others. AspectJ is open source and there is nothing stopping you from reading through it and adapting it to you needs.
For limited requirements, it is probably not very complex either. You would need a java agent which can look at annotations on classes and methods as they are loaded and modify their bytecode to add logging. Again, there are excellent libraries out there that can aid this but alas you cannot use them.
Another option might be to use jpda. I have no experience with that, but I suspect it will have a significant impact on performance.
I need to intercept the calls to all the method calls to an Interface. I've gone through the Java Dynamic Proxies however that will not help me. I'm not even sure whether this can be achieved, but thought of confirming.
So basically lets say i have an interface as follows:
public interface Foo {
public String getValue();
}
I would like to intercept all the calls to getValue() from whichever implementations of Foo. Problem is i do not have control over the different implementations of Foo, because of which i cant use Dynamic Proxies.
Is there a way i can do this?
Thanks.
AOP might help, but as you've discovered, it all gets much easier if you're in control of the object creation (even if only through a DI framework like Spring or Guice).
Another alternative is compile-time byte-code weaving - that is, finding all implementations and altering them to have your interception code in them at compile time.
A third alternative would be to look at using either an agent or a custom classloader to do weaving as the classes are loaded into the system. This is load-time weaving. But if you're in, say, a web container where you're not fully in charge of the classloaders, this might be tricky.
The only way to do this would be with a custom classloader that replaces the implementation classes with a proxy.
It might be possible to do this out-of-the-box with Spring AOP's load-time weaving.
I want to add validations to a Java Bean. For example, I want to do the following:
#MaxLength(50)
#RequiredField
public void setEmployeeName(String name){
.....
}
I know I can write code that gets the validations for a specific method by calling method.getDeclaredAnnotation after all the bean values have been set. I would like to avoid writing this code
Is there anything in Java6 that gives standard validations via annotations? Do I need aspectj to invoke these annotations?
thanks in advance.
You can use Bean Validation Framework. Here is short overview
http://relation.to/Bloggers/BeanValidationSneakPeekPartI
take a look at JSR 303. The RI (Reference Implementation) is here, with also a nice tutorial. And no, you don't need AspectJ.
The only way you'll be able to do this is through reflections and a custom validation utility/interceptor/proxy. JSR 303 and JSR 305 were proposed to introduce similar functionality, but nothing like this exists.
One of the problems you'll run into is that these annotations need to be handled at some sort of framework level, or at a minimum, intercepted before some sort of invoked action. The two most common sense, brute force ways of doing this would be done either by creating a utility, or by validating pre-invoke in an invocation handler (proxy).
The reality is that unless this is built into Spring, Struts, Guice, Java itself, etc., you're just creating unnecessary overhead and you're better off checking for validation bounds on demand.