0
votes

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.

1
You need to isolate the problem. First step would be to analyse project dependencies for possible conflicts/replacements. Create two setups: a) working (without Spring AOP) b) non-working (with Spring AOP). Then invoke "gradle dependencies" for both, redirect output to files, compare files. It may happen, that Spring AOP introduces new dependencies that are replacing these of AspectJ, effectively breaking it.akhikhl

1 Answers

0
votes

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.