Some doubts about Spring AOP example - java

I am leargnin AOP in Spring Framework studying on this tutorial: http://www.tutorialspoint.com/spring/schema_based_aop_appoach.htm
Differently from the previous tutorial I am not adding manually the needed jars file but I am using Maven.
Initially I have added this dependencies in my pom.xml (in addition to those relating spring-core, spring-bean, spring-context, spring-context-support Spring modules)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
But, in this way don't work and raises me the following exception:
Caused by: java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException
Reading online I have found the solution: I have to add these two dependencies in my pom.xml:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
So now I have two doubt:
Why I have to add this org.aspectj.aspectjtools dependencies if I have yet org.springframework.spring-aop? (Also...I noticed that I could delete the org.springframework.spring-aop, this is not used)
What is the difference between them?
Why I have to add cglib dependecies?
I know that I have to use cglib when I use annotations like #Configuration and #Bean...but why I need this dependencies in this case that have not these annotation?
Tnx
Andrea

You could have used aopalliance instead of cglib, and aspectjrt & aspectjweaver dependencies in your pom.xml. What I use and suggest is compile team weaving of your target code using Maven aspectj-maven-plugin.
As to your questions, Spring AOP does not itself instrument your target code. It uses AspectJ behind the scenes to do that. CGLib is used to generate Dynamic Proxies etc. If you need to dynamically generate an interface and then apply it to your advices then, CGLib can assist. Hibernate heavily uses CGLib

Related

Maven: Resolve dependencies using container dependencies first

I have a plugin project which is added to other container projects as a dependency.
Now, this plugin project uses many frequent dependencies like spring-security, commons-lang, etc.
Usually, the container projects contain their own versions of such frequent dependencies. So, when we add our plugin dependency there are conflicts and the dependencies are resolved based on regular maven dependency resolver and depending on scopes and optional tags provided in the plugin project dependencies.
Is there a way where all the dependencies are resolved using the version in parent dependencies first and iff they are not available then use the version specified in plugin dependency.
Note: optional and scope runtime have a problem that these dependencies are provided by the container and thus beats the aim to provide a hassle-free single dependency to add plugin dependency.
In your plugins pom define the version of a dependency as range of the versions you know the plugin to be able to use. If a container-dependency overlaps this will be used. If no overlapping version, of the dependency both container and plugin need, can be found, an error will be produced, since the negotiation failed.
Use no special scope for the dependencies, since you want them to be included if necessary into the container,
See:
https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html
And:
https://books.sonatype.com/mvnref-book/reference/pom-relationships-sect-project-dependencies.html#pom-relationships-sect-version-ranges
Assuming that your container and plugin projects use the same parent pom you could utilize the <dependencyManagement> section in the parent to define the common artifacts. This allows you to omit the version in the plugins <dependencies> section.
parent:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
plugin/module:
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
</dependency>
</dependencies>
See https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html for further details.
you can exclude it when you build a plugin project and add a dependency to maven.
This is an example. Dependency and main project have conflicted due to logging library. Below is to exclude log4j in dependency project.
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zk.version}</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
P/S: Added from my comments:
I have also developed a system which has a similar architecture with yours. I separate this system into 3 main parts: 1. Commons which contains common code and required maven dependencies, 2. The main project, 3. plugin project. You can refer this.

Why do we need the following jboss jar for EJB 3.2 in Wildfly?

This might be a silly question. But I have a doubt, why do we need the following dependency to run EJB in Wildfly?
<dependency>
<groupId>org.jboss.spec.javax.ejb</groupId>
<artifactId>jboss-ejb-api_3.2_spec</artifactId>
<scope>provided</scope>
</dependency>
Do we have something similar which is customized for Wildfly only?
Actually, you just need this maven dependency so your code can compile successfully during maven compile phase. For example, EJB annotations such as #Stateless are provided by it.
I use to declare this maven dependency instead for my Java EE 7 projects, so the whole bunch of JEE specs are available :
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
Finally this maven dependency has to be declared with "provided" scope as you don't need it within your package. Indeed it is already provided by Wildfly, as described in this documentation: Implicit module dependencies for deployments

download compatible dependency in maven

Supppose I use spring 4.0 in my pom file and I want to use junit. In that case how can I declare the junit dependency to download the which compatible with the given spring version with out specify any specific junit version. This can be any dependency where I take junit as a example.
In Maven there are two possible matching things. First the dependency management of the artefact itself. spring-core:4.2.0 defines that it depends on commons-codec:1:10. So there is nothing to do for you when you want to also use commons-codec since its already in your classpath. It did not define JUnit so it did not depend on it and should be compatible with all versions.
The second thing is aBOM pom. This is used to package a lot of dependencies together and let the user select the once he needs but the bom defines the versions for you already (and so they should be compatible). Especially spring has some of this bom poms in the repo.
For example spring-framework-bom which packaged everything related to spring which you could use in your app but you will define which parts you need and do not bothering yourself with the version numbers of the sub dependencies.
For example I want to use spring 4.2 and need webmvc the jdbc stuff and something for spring tests. So will define this:
<dependencymanagement>
<dependencies>
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-framework-bom</artifactid>
<type>pom</type>
<version>4.2.0.RELEASE</version>
<scope>import</scope>
</dependency>
<dependencies>
</dependencymanagement>
<dependencies>
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-webmvc</artifactid>
</dependency>
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-jdbc</artifactid>
</dependency>
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-test</artifactid>
<scope>test</scope>
</dependency>
</dependencies>
This question doesn't really make sense. If spring 4.0 depends on JUnit (you don't say which spring module you're referring to), JUnit (or any other dependency) will automatically be included in your dependencies, since it will be inherited from the spring 4.0 dependency you have already declared, and the version will match whatever version the Spring module declares in its POM.
However, it seems likely that your particular Spring 4.0 dependency does not depend on JUnit, so in which case you may just pick which ever version is suitable for your requirements.
You can view the dependencies which are currently included in your project (explicit and inherited) by running the following command:
mvn dependency:list
This will trace down the dependency tree and show you all the dependencies which are currently included in your project.

Java - Spring AOP on Eclipse?

I need to use AOP of Spring in Eclipse. So I tried to use '#Aspect' annotation, but it does not found it and just suggest me to create myself. As I understand Spring itself does not have this annotation? Because in documentation it shows that is uses aspectj. So I downloaded from http://www.eclipse.org/downloads/download.php?file=/tools/aspectj/aspectj-1.7.4.jar
Then added it as external jar from project properties. But still nothing changed. Did I miss something?
Update:
I also installed AJDT via plugin manager, but still it does not recognize '#Aspect' annotation. So what should I do so it would recognize it?
You are right, you need both the aspectj plugin and the spring aspect plugins.
First, make sure you have the proper maven dependencies in your project. It should be:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${version}</version>
</dependency>
And modify the versions by the ones you would like to use.
Then if you use a maven plugin for Eclipse like m2e it should find the dependencies.
Hope that helps

spring dependencies

I just found one daunting thing. There are two versions of spring dependency coordinates.
Project has dependencies on spring mvc and spring flow. There are two parallel sets of dependencies.
Spring MVC has dependencies of the following scheme: org.springframework:spring-asm.
Spring Flow has dependencies of the following scheme: org.springfrmaework:org.springframework.asm.
Why are there two different sets of the same dependency? How can it be overcome?
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>org.springframework.webflow</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
It's basically a question of the artifacts you are using:
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>org.springframework.webflow</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
Is an artifact from the SpringSource Enterprise Bundle Repository and those artifacts are OSGi compliant. I quote:
Welcome to the SpringSource Bundle Repository. Here you'll find
OSGi-ready versions of hundreds of open source enterprise libraries
that are commonly used when developing Spring applications.
On the other hand, you have:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
Is a standard artifact from the maven repository.
org.springframework.asm
Is a patched version of the asm artifact for use with OSGi.
The best solution to fix this is only using the SEBR repository artifacts.
I recommend this because one time I had a problem with the jars from the maven central repo (they were corrupt) so I try to use the SEBR for any spring dependency. But I quote from the documentation:
If OSGi does not matter to you, either place works, though there are
some pros and cons between them. In general, pick one place or the
other for your project; do not mix them. This is particularly
important since EBR artifacts necessarily use a different naming
convention than Maven Central artifacts.

Categories

Resources