AspectJ in Spring: CTW vs LTW - spring

Question regarding AspectJ in Spring: CTW vs LTW. What's the difference? As far i understand the both approaches make the same - they both are producing java class with incorporated aspect logic instead of original class. CTW do it during compile time, LTW do it during JVM loading classes. Could you please explain any other diff between them? Thank you in advance!

First of all, AspectJ is independent of Spring. It was invented before Spring and does not need any frameworks. Maybe you are unaware of the difference between Spring AOP (based on dynamic proxies) and AspectJ (based on byte code instrumentation). By default you would not use CTW or LTW in Spring but just simply Spring AOP. Only if this "AOP lite" approach is not powerful enough for you, you will use the full power of AspectJ with or without Spring.
Please read the Spring AOP manual in order to learn how to use it. There is also a chapter on AspectJ there for you to study.
Concerning the basic technical differences with between types of AOP like CTW, LTW, proxy-based incl. pros and cons, see my answer there. #Moderators: I really do not want to quote myself here, but also not flag this question as a complete duplicate.

I tried to use LTW a long time ago and it had some bugs as sometimes on startup it failed to do the weaving which is pretty bad and I decided to use CTW from then on.
LTW increases startup time but is probably easier to debug in intellij/eclipse while with CTW debugging might be hard to setup sometimes.
But as I said CTW is safer for me - classes are there ready to go, no surprises during startup/runtime. So if you do not do dynamic class loading (like in OSGi or similar) and want to weave that code with aspects then I would stick to CTW.

Related

Spring | Hibernate | Transaction management with AspectJ

We are working on a new project using Spring, Hibernate and Transaction management using AspectJ (#Transactional annotations) and we are not sure what is the best practices weaving options to go.
We've started with the LTW and placed the tomcat Loader, it worked fine.. but then we thought that it may be less risky to have compile time weaving which instruments and *.classes and not on load time (in memory), so it will done just one time and not when on the tomcat startup. This is done via Maven aspectj-maven-plugin plugin.
Can you please advice ?
What are the pros and cons of using those weaving options ?
Thanks!
Disclaimer: This is not a discussion forum but a Q/A platform, so your question does not have the correct answer, it rather sparks discussion. I am trying to elaborate a bit anyway.
You basically already stated the main facts about LTW versus CTW. I am failing to see why LTW should be more risky than CTW, though. It slows down your server start-up, but the risk is the same as with CTW because the resulting byte code is also the same. Or are you talking about the risk that maybe more code gets (e.g. 3rd party libraries) woven than you intend? In that case yet, CTW keeps you on the safe side and you have more control over what should be woven. It should also speed up your server start-up time in comparison with LTW.
So if you have no compelling reasons to use LTW, such as the wish to dynamically intercept code you are unaware of during development, go ahead and use CTW and you are on the safe side, as long as you are fine with adjusting your build process accordingly. AspectJ Maven plugin is pretty straightforward to use, so that should not be a big deal. You can still switch to LTW as needed and when needed. OTOH, if you are using LTW now and are fine with the server start-up time, maybe there is no need to switch. If unsure, try both approaches and compare the results. ;-)

Using aspects written with AspectJ in projects which use Spring AOP

I'm new in Gradle/AspectJ and I have a few questions regarding this.
I develop some library which will be used in other projects. I use AspectJ to implement some cross-cutting logic and I created my aspects using #Aspect without apectj specific language.
This lib is small framework which provides some annotations to use it.
I created unit tests for my classes. I know that to apply aspects I need to compile classes using AspectJ compiler ("ajc"). In my ide I run tests with option: -javaagent:[path to aspectjweaver jar] and all my tests are working well as excpected. But when I run tests from gradle then some tests are failed because my aspects aren't applied. I heard about aspectj plugin in maven and tried to find something similar for gradle. I found this plugin which weaves AspectJ aspects into classes and it works good, all tests are passed, but I faced with some problems. How I said I develop third-party lib which used in other projects, if some projects use Spring AOP then my aspect doesn't work. For example aspect isn't apply with next configuration:
<aop:aspectj-autoproxy/>
<bean id="myAspect" class="com.ext.aop.MyAspect"/>
To make it clear my aspect wraps all methods which annotated with my specific annotation in some logic, that's all.
In the case of Load-time weaving my aspects are working:
<context:load-time-weaver aspectj-weaving="autodetect"/>
-javaagent:lib/spring-instrument.jar
Maybe somebody know what's the problem ? How I understand in the case of LTW the project's developers need to compile project with using some plugin again in order to wave acpects. Whether the use of LTW affect other aspects which already exist in a project? Maybe there is a way to say gradle to wave aspects only for tests and leave project's developers to be responsible for compiling aspects in an appropriate way? Or better create separate version of lib for spring framework? Maybe someone encountered such situation and have any ideas, so please give me advice. Thanks for advance.
Spring AOP cannot process a aspects which were compiled by ajc, the snippet from AbstractAspectJAdvisorFactory source:
/**
* We consider something to be an AspectJ aspect suitable for use by the Spring AOP system
* if it has the #Aspect annotation, and was not compiled by ajc. The reason for this latter test
* is that aspects written in the code-style (AspectJ language) also have the annotation present
* when compiled by ajc with the -1.5 flag, yet they cannot be consumed by Spring AOP.
*/
public boolean isAspect(Class<?> clazz) {
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
}
I guess you should provides pure acpects (java classes compiled only by javac) to give others a chance to compile it as needed. But I recommend you to create tests for all possibles use cases: using your lib together with spring aop, acpectj, guice aop and etc.

Testability in AOP

I'm totally new in AOP world.
After reading some books(ex, spring in action), I have a basic question for AOP -- How can we ensure AOP is still working or not working in existing system especially when the system is changing.
You know in real world, especially when the program is still under implementation, the design is always changing. It might be the big program structure changing, might be the refactor. In a word, the program is always changing.
However, the way we adopt AOP in our program is depend on the implementation detail. (ex, the public/private method name) If the implementation detail is changed, possibly the AOP will not work. What's worse, if we're working in a big team, possibly someone will change some implementation detail on which AOP depends, but he is not aware at all. Then the big question is how we can know the AOP is not working in such case? Is there any compilation guarantee or at least junit case guarantee?
Thanks a lot for answer.
This can be tested with Junit and spring-test, a Junit test class can be written that get's injected with an object from the layer at which your aspect is being applied and mock the layer beneath it.
Then call the object to which the aspect is applied and assert that the results are as expected.
This is an example of how to test if method security (applied via aspects) is working.
The test confirms that an AccessDeniedException is thrown as expected, proving that the aspect is working.
Other aspects could be tested in a similar way using spring-test and mocks.
The only way to really test this is with some automated testing, otherwise, as you have pointed out, people could change implementation detail and break the existing AOP. Spring provides integration testing support that will load the beans from your contianer (and also load your AOP). http://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch10s03.html

Advantage of Spring

Spring is a popular framework, however I have difficulties to see in which situation the framework would actually help.
Currently I'm using the following:
* Tomcat
* Jersey
* Jackson
* Hibernate
Together this results in a Webservice, created by annotations, automatic JSON (un)marshalling and a comfortable Object/Relational Mapping.
So honestly at the moment I'm not missing anything, but I might just not know what great thing I'm missing... Could you help me out with this?
Thank you
Spring is a big framework providing a lot of functionality. It's hard to talk about advantages without knowing what functionality are you trying to use in the project.
Most probably you talk about Spring as an IoC container. It is very important part of Spring, but there is also AOP, transaction management, JDBC abstraction layer, authentication and authorization, testing and some more.
In a nutshell, Spring offers you uniform way to control dependencies between your objects. This is called inversion of control or dependency injection. Using it you can create pluggable, testable code that is easy to maintain.
In addition it gives you gazillion utility classes that just make life easier. For example, Hibernate is much easier to maintain via Spring facilities. It kind of brings together many different technologies under the same roof.

What is 'weaving'?

I've seen this term when read about how Spring works and I've just read the article about JPA implementation performance and it has the next statistics:
EclipseLink 3215 ms
(Run-time weaver - Spring ReflectiveLoadTimeWeaver weaver )
EclipseLink (Build-time weaving) 3571 ms
EclipseLink (No weaving) 3996 ms
So, could someone explain in plain English, what is weaving?
Thanks!
Weaving is generating or editing code by directly modifying existing .class (byte-code) files.
This can occur at different points in the application life cycle.
Outside of JVM
at compile time
at packaging time
Inside a JVM
at class load time.
after a class has been loaded.
Spring Framework uses this for AOP functionality. Eclipselink uses weaving for lazy loading or change tracking.
From here:
In Spring AOP makes it possible to modularize and separate logging, transaction like services and apply them declaratively to the components Hence programmer can focus on specific concerns. Aspects are wired into objects in the spring XML file in the way as JavaBean. This process is known as 'Weaving'.
In nutshell, we could say
Weaving is the process of applying the Advices to the Target objects
at given pointcuts to get the Proxy Objects.
I‌ found this description useful:
Weaving: This is the process of inserting aspects into the application code at the
appropriate point. For compile-time AOP solutions, this weaving is generally done
at build time. Likewise, for runtime AOP solutions, the weaving process is executed
dynamically at runtime [using JDK‌ dynamic proxy and CGLIB proxy]. AspectJ supports another weaving mechanism called load-
time weaving (LTW), in which it intercepts the underlying JVM class loader and
provides weaving to the bytecode when it is being loaded by the class loader.
reference: Pro Spring 5: An In-Depth Guide to the Spring Framework and Its Tools
Object-oriented software systems that are developed
using aspect-oriented programming techniques
consist of classes and aspects. Classes implement
the primary functionality of an application,
for example, managing stocks or calculating
insurance rates. Aspects, on the other hand, capture
technical concerns like persistence, failure handling,
communication, or process synchronization.
There are two ways in which classes and aspects
can be woven: static or dynamic.
Static weaving means to modify the source code of a class by inserting aspect-specic statements at
join points.In other
words: aspect code is inlined into classes. The
result is highly optimized woven code, whose execution
speed is comparable to that of code written
without using aspects.
Weaving is a technique of manipulating the byte-code of compiled Java classes.
Ref: http://www.eclipse.org/eclipselink/documentation/2.5/concepts/app_dev007.htm
Cheers!
Weaving is the process of linking aspect with other application types or objects to create an advised object. Weaving can be done at compile time, load time or runtime. Spring AOP performs weaving at runtime.

Resources