Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Duplicate classes when using Maven AspectJ weave dependencies

We are using the Maven AspectJ plugin to build our web application. It makes use of "weaveDependencies" to add aspects to some dependency jar files.

Now we end up with two versions of some classes in the web application archive, one in WEB-INF/classes and one in the original jar file in WEB-INF/lib. It seems that only the one in classes has the aspects.

I am afraid that this can cause problems.

What is the best way to fix this?

The same problem is discussed (without solution) over at the Eclipse forums.


The whole pom.xml itself is huge, and of course the sub-projects that are included have their own, too. I hope the extract below from the WAR project is informative enough.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1.1</version>
    <configuration>
        <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
        <filters>
            <filter>${basedir}/src/etc/${environment}/environment.properties</filter>
        </filters>
    </configuration>
</plugin>
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.2</version> <!-- NB: do use 1.3 or 1.3.x due to MASPECTJ-90 - wait for 1.4 -->
    <dependencies>
        <!-- NB: You must use Maven 2.0.9 or above or these are ignored (see 
            MNG-2972) -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
    </dependencies>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <outxml>true</outxml>
        <aspectLibraries>
            <aspectLibrary>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
            </aspectLibrary>
        </aspectLibraries>
        <weaveDependencies>
            <weaveDependency>
                <groupId>OURPROJECT</groupId>
                <artifactId>OURPROJECT-api</artifactId>
            </weaveDependency>
            <weaveDependency>
                <groupId>OURPROJECT</groupId>
                <artifactId>OURPROJECT-service</artifactId>
            </weaveDependency>
        </weaveDependencies>
        <source>1.6</source>
        <target>1.6</target>
    </configuration>
</plugin>
like image 885
Thilo Avatar asked Mar 02 '14 03:03

Thilo


1 Answers

In a servlet container and inside a WAR, the classes inside WEB-INF/classes always have precedence over classes with the exact same name found inside a jar in WEB-INF/lib.

This is a quote from the servlet spec:

The Web application class loader must load classes from the WEB-INF/ classes directory first, and then from library JARs in the WEB-INF/lib directory.

This has been so since at least Servlet 2.4. This allows an application to selectively patch just a few library classes without having to repackage jars manually or via maven plugins.

In your case you can be certain that the classes with the aspects will always be taken, as they are in WEB-INF/classes and have priority over classes in WEB-INF/lib.

like image 143
Angular University Avatar answered Sep 28 '22 17:09

Angular University