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.
Related
we have a kotlin-microservice that needs to expose a maven-artifact that defines all DataTransferObjects that are required/emitted by that microservice (e.g. kotlin data-classes that represent events published to the event-bus).
client of that microservice is however a pure java application which shall depend on this kotlin-DTO-maven-artifact but not transitively get the kotlin-stdlib or any other kotlin-specific dependencies injected.
can we provide the kotlin-DTOs without introducing any kotlin-dependency?
The easiest and the most reasonable for me would be to create those DTOs as Java classes since the Kotlin is compatible with such classes
You don't need for this any additional tools or tricks. Inside this artifact you can easily use Lombok to not write plenty of boiler plate code
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.
I started learning spring today and i have a question regarding what happens to the annotations when java files with annotations is compiled ?.
The reason i am asking this is because of the fundamental difference i see when we choose to use the xml approach vs the annotations approach , and what i think is the philosophy of spring. The way i understand is spring says that all your java classes can be simple pojo's and all the spring related config should be kept independent (Like xml file.)
In case of developing spring application using xml *.java files have no idea about spring container and are compiled in to .class without any spring related dependencies.
But now when we annotate the .java file and the file is compiled the compiled file now has all spring related dependencies hard baked in to it and no longer are your classes simple pojo's.
Is this correct ? I am not sure if i am missing some thing here.
Annotations can be considered as metadata of a class or its element (method, field, local variable...). When you put annotation, you don't implement any behaviour. You just give additional info on an element.
That way, Spring, which is in charge of instanciating its bean can collect the info with reflection (see also this site) and process it.
To conclude, your Spring beans still remain POJO and there is no difference with the XML way (...from that point of view) since Spring gets from annotations the information it would have got from XML .
I think you are right and your question is justifiable, that's the way how I think about it too.
Not only compiled code but also dependency on spring jars bother me. Once you use this annotations your resulting jar depends on spring library.
It's reasonable to store beans in model according to DDD but spring is some kind of infrastructure layer so I didn't like the dependency.
Even if you would use XML, it's useful for few placed to use attributes. E.g. #Required attribute which is useful to verify that linked bean was injected. So, I've decide to use constructor dependency injection to omit this attribute, see my article. I completely leave out the dependency on spring in the code.
You can probably find such mind hook for many annotation you want/force to use.
You can use annotations only for your configuration classes, without marking them actual bean classes. In such scenario if you not use spring you just not load configuration classes.
Could someone provide a sample code snippet that stitches two java interfaces using spring-aop introduction (mixin)?
I'm looking for AspectJ annotation style configuration. Also, the specific use case I have is to stitch a few java beans each implementing their own interfaces together. So, rather than having a delegate coded, if I could just get away by using Spring XML, it'd be awesome.
You can use #DeclareParents or <aop:declare-parents> to get the mixin behavior. For example,
#DeclareParents(value="service.*", defaultImpl=AuditRecorderDefaultImpl.class)
private AuditRecorder mixin;
will mixin all classes in the service package with the AuditRecorder interface automatically forwarding each method to AuditRecorderDefaultImpl.
You can see working examples of this from AspectJ in Action's downloadable sources. You can also see detailed explanation in Spring documentation.
A demo based on Spring in Action book 4th edition is here, the configuration is JavaConfig style with #ComponentScan
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-specic 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.