Spring Source Tool Help Needed - java

i am applying AspectJ in spring source tool
do i need to configure load time or compile weaving in spring source tool
i will be very happy if any provide details of using AspectJ for applying Aspect on Spring Source Tool

This is a very advanced topic, way beyond the scope of a single StackOverflow question.
Basically:
The simplest case is Spring AOP,
where you don't use AspectJ at all,
but create Java proxies from AspectJ
annotations. This is also the least
powerful option. Only a few pointcuts
are supported, and the targets must
be Spring Beans.
The most powerful option is static
AspectJ compilation, which you
usually integrate in your build
system (works fine with ant or
maven). Your class files are actually
changed to include the aspects. This
is called compile-time weaving.
Load-time weaving is somewhere
inbetween. You want to advise code,
but you don't want to change the
class files, so you "advise the
classloader" (this is not an adequate
definition, but it gives you an
idea). Loadtime-weaving is also
usually your only choice if you want
to add aspects to 3rd party library
code.
You should read AspectJ in Action by Ramnivas Laddad to understand all the subtle differences.
Either way, the settings you use in STS should reflect the settings you have in your build system. The section 7. Aspect Oriented Programming with Spring from the Spring Reference is also very helpful.

Related

How to add filter / AOP method that cannot be removed without recompile?

My question would be: how do I add a servlet filter, or a Spring AOP method (or a third solution - you name it) that cannot be removed from a web application without recompiling?
I'd like to solve license handling that way, but if anyone modifies the web.xml or the Spring config, the protection is gone.
Licence handling is definitely a cross-cutting concern which could (and IMO should) be modelled by means of AOP.
I cannot say much about servlet filters, being unexperienced in this regard, but
I know that Spring AOP is proxy-based, i.e. it does not modify the source code directly, which is not what you want.
AspectJ, on the other hand, when used at compile-time (not via load-time weaving as is the usual approach in Spring), does compile aspect code right into your core class files, "baking" them into your byte code. This is probably what you want. I do not say it cannot be reverse-engineered - there always is this option - but the code would not run without the AspectJ runtime on the classpath and you could not remove the licencing aspects without recompilation. So this is the option I recomment for that purpose.
Interesting question, by the way.

What is load-time weaving?

I am using load-time weaving for a spring (2.5.x) project but I don't know what it is the purpose of it in general. I tried little googling but didn't find the upcoming pages useful. The only thing I understood is that it is something about AOP.
I noticed that it is used for older spring versions also wondering why is that?
Weaving is an AOP concept and it is the phase of integrating the aspects with the targeted code. After weaving, aspects are applied to the original code.
This process can take place in different times like compile and load. This article explains the different weaving times and LTW of AspectJ.
It says about LTW:
Load-time weaving (LTW) is simply binary weaving defered until the point that a class loader loads a class file and defines the class to the JVM.

Compile/load time weaving with spring

The docs explain that, the LTW has to enabled either through the use of <context:load-time-weaver/> xml instruction or the use of #EnableLoadTimeWeaving annotation. However, I have done neither, but I still see that aspects are woven correctly in my projects!
In this case, I don't think they are woven at compile-time (but are they?), so it's surely got to be load-time-weaving?
Even if that's the case, how does it automatically choose to weave aspects in during load-time? Shouldn't the aspects remain unwoven if they are not turned on using one of the ways mentioned above as the docs say?
I've got the aspectj-weaver in my classpath, but that can't be enough to choose either of these weaving types anyway, can it?
Spring AOP does not rely on AspectJ byte code weaving. It just borrows the annotations used to define aspects from the AspectJ project. It is a separately implemented framework that uses run-time proxies to implement aspects. If you have <aop:aspectj-autoproxy /> in your application context then spring is using proxies to implement supported aspects defined on beans that are in the container.
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)
If you want to be able to advise fields for example, you would need to enable the use of Native AspectJ.

Unit testing classes weaved by aspects with dependency injected Spring beans

Because Spring-driven AspectJ LTW is unable to weave classes loaded before Spring initializes, I'm converting a Spring project to pure Aspectj LTW (with the AspectJ weaver java agent).
However, this collaterally enables AOP in our Unit Tests because I need to add AspectJ's agent to the Maven Surefire plugin argLine parameter and to the default TestNG configuration in my team's IDE (IntelliJ IDEA).
This wouldn't be a problem if our Aspects were not dependent on Spring, but some of them actually require Spring beans to be injected in their fields via #Resource notation. As Spring is not started during Unit Tests, that fields will be null and result in NullPointerExceptions.
Even though I could configure two independent executions of the Surefire plugin during the build process: one with the agent and the other without it; this solution would become impractical as each developer would still need to change the IDE's test configuration for unit tests vs other tests that actually require AOP and start Spring, for every independent test execution (i.e. outside of Maven build process).
What would be the best approach in order to solve this problem? Is there any way to disable AspectJ's LTW while still keeping the java agent configuration intact? Or maybe another and more flexible way to configure AspectJ's LTW that doesn't have the problems of Spring-driven AspectJ LTW?
We could argue about whether or not it is a good design decision to make pure AspectJ aspects dependent on Spring magic or if it would be an option to inject mock-ups for your Spring beans into the aspects. Actually a unit test is not a unit test if it requires such a framework. The same is arguably true for aspects.
Anyway, here is a cheap solution: Use if() pointcuts for all relevant advice and make them dependent on whether you are in testing mode or not. The performance overhead will usually be minimal, don't worry. Just give it a try before you say it is too expensive.
Also possible, but more expensive would be to determine if a test class is in the control flow of the currently intercepted joinpoint via cflow() or cflowbelow(). I do not recommend it in this case though.
A third option might be to add another META-INF/aop.xml to the classpath in testing mode which contains a global exclude statement excluding all classes from weaving. The AspectJ documentation explains how multiple aop.xml are merged logically. Probably this option is the best because it does not require you to change your aspects. I have not tried, but I would if you encounter any difficulties and give me a sign.

AspectJ load-time weaving configuration without XML

Is it possible to configure AspectJ LTW solely in Java? I don't want to deal with XML, and I was wondering if I can do without it. I searched through AspectJ website, and I found only the XML way.
I am planning to use it with Spring, hopefully without any strange consequences(had enough problems already:)).
Thanks!
You can set up Spring to use AspectJ via LTW mostly using Spring annotations. But you do need META-INF/aop.xml because this is an AspectJ LTW requirement, it does not come from Spring. AspectJ is an independent technology which does not need Spring, Spring only supports it being used in its own context.
If you don't like XML for whatever reason - done right there is no problem and you only need to touch the file once - use CTW (compile-time weaving), e.g. via AspectJ Maven Plugin.

Categories

Resources