DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Introduce a New API Quickly Using Spring Boot and Gradle
  • Magic of Aspects: How AOP Works in Spring
  • A Guide to Aspect-Based Sentiment Analysis With GPT and BERT
  • Adding Versatility to Java Logging Aspect

Trending

  • RAG Done Right: When to Use SQL, Search, and Vector Retrieval and How To Combine Them
  • Ten Years of Beam: From Google's Dataflow Paper to 4 Trillion Events at LinkedIn
  • 11 Agentic Testing Tools to Know in 2026
  • Evaluating SOC Effectiveness Using Detection Coverage and Response Metrics

Working With Gradle, Spring Aspects and Compile-time Weaving

By 
Lieven Doclo user avatar
Lieven Doclo
·
Jul. 22, 13 · Interview
Likes (2)
Comment
Save
Tweet
Share
27.2K Views

Join the DZone community and get the full member experience.

Join For Free

As one of my previous posts already mentioned, I’m in the process of migrating most if not all of my projects to Gradle. I’m very pleased with the fact it’s going a lot smoother than I had anticipated.

However I came across an issue: how to get AspectJ compile-time weaving working with Gradle. My use case is quite simple: I’m using Spring’s @Configurable annotation, which either requires load-time or compile-time weaving to work correctly. Load-time weaving isn’t really an option, so compile time weaving it was. There is a plugin but it’s outdated: it doesn’t work with Gradle 1.6. If this was the case with Maven, I’d be screwed/ I would have to write my own plugin. Luckily with Gradle, it was not that difficult.

The old plugin relied on the old Gradle 0.9 DSL, so I could use that as a starting point. The instructions required me to define some new configurations and add some things to the javaCompile task. So I started out with this:

configurations {
  ajc
  aspects
}

compileJava {
  sourceCompatibility="1.6"
  targetCompatibility="1.6"

  doLast{
      ant.taskdef( resource:"org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.ajc.asPath)
      ant.iajc(source:"1.6", target:"1.6", destDir:sourceSets.main.output.classesDir.absolutePath, maxmem:"512m", fork:"true",
          aspectPath:configurations.aspects.asPath,
            sourceRootCopyFilter:"**/.svn/*,**/*.java",classpath:configurations.compile.asPath){
          sourceroots{
              sourceSets.main.java.srcDirs.each{
                  pathelement(location:it.absolutePath)
              }
          }
      }
  }
}

dependencies {
  ajc             "org.aspectj:aspectjtools:1.6.10"
  compile         "org.aspectj:aspectjrt:1.6.10"
  aspects        "org.springframework:spring-aspects:3.2.2.RELEASE"
}

This, however, did not work. I was greeted by the following exception:

can't determine superclass of missing type org.springframework.transaction.interceptor.TransactionAspectSupport

It seems like spring-aspects contains multiple aspects, each requiring some dependencies which are required regardless whether you want to use those aspects. This, by the way, was also required when using the Maven AspectJ plugin. After some POM fishing, I found out I had to add a couple of libraries. So now we have the following dependencies:

dependencies {
  ajc         "org.aspectj:aspectjtools:1.6.10"
  compile         "org.aspectj:aspectjrt:1.6.10"
  aspects        "org.springframework:spring-aspects:3.2.2.RELEASE"
  aspects        "javax.persistence:persistence-api:1.0"
  aspects        "org.springframework:spring-tx:3.2.2.RELEASE"
  aspects        "org.springframework:spring-orm:3.2.2.RELEASE"
}

My code compiled and my aspects were weaved in! Unfortunately, it wasn’t the end of the story. My tests failed. It was missing the aspect library at runtime, as the (now weaved) classes referenced some classes that were contained in spring-aspects and I was subclassing them in my testcode. The quick solution would be to duplicate the spring-aspects dependency in the compile configuration, but that was something I didn’t like. I did however came up with a cleaner solution: I had to make sure the aspect dependencies were added to the compile configuration. A small change in the configurations section was all I needed to do.

configurations {
  ajc
  aspects
  compile {
      extendsFrom aspects
  }
}

Hurrah! I wished. Unfortunately now the dependencies I had to add to the build in order to make the weaving work were now also added to the compile configuration. I didn’t need them or used them, so I had to find a way to exclude them from the compile configuration, but still include them in the aspect weaving. The solution was simple and clean: add a new configuration and include those configuration’s dependencies in the weaving classpath. The new configiration is not added in the compile configuration, so your build is not dependent on those dependencies.

The final product looked like this:

configurations {
  ajc
  aspects
  aspectCompile
  compile {
      extendsFrom aspects
  }
}

compileJava {
  sourceCompatibility="1.6"
  targetCompatibility="1.6"

  doLast{
      ant.taskdef( resource:"org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.ajc.asPath)
      ant.iajc(source:"1.6", target:"1.6", destDir:sourceSets.main.output.classesDir.absolutePath, maxmem:"512m", fork:"true",
          aspectPath:configurations.aspects.asPath},  sourceRootCopyFilter:"**/.svn/*,**/*.java",classpath:"${configurations.compile.asPath};${configurations.aspectCompile.asPath}"){
          sourceroots{
              sourceSets.main.java.srcDirs.each{
                  pathelement(location:it.absolutePath)
              }
          }
      }
  }
}

dependencies {
  ajc             "org.aspectj:aspectjtools:1.6.10"
  compile         "org.aspectj:aspectjrt:1.6.10"
  aspects        "org.springframework:spring-aspects:3.2.2.RELEASE"
  aspectCompile  "javax.persistence:persistence-api:1.0"
  aspectCompile  "org.springframework:spring-tx:3.2.2.RELEASE"
  aspectCompile  "org.springframework:spring-orm:3.2.2.RELEASE"
}

The entire process took me about an hour, although most of it was looking up stuff in the Gradle documentation. I’m also really impressed with the error notification of Gradle. If something goes wrong, it’s quite accurate in pinpointing the problem.

This was one of the more complex things in the builds I have, so anything else should be a breeze. One thing I really, really like about Gradle is that you can merge all build configuration of a multi-module project into a single build.gradle file. For a build with 10 modules this meant going from maintaining 11 Maven POM files to only one gradle build script. Even better: the single build.gradle file is 3 times smaller than the projects root POM! If that’s not nice, I don’t know what is.

Gradle Aspect (computer programming)

Published at DZone with permission of Lieven Doclo. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Introduce a New API Quickly Using Spring Boot and Gradle
  • Magic of Aspects: How AOP Works in Spring
  • A Guide to Aspect-Based Sentiment Analysis With GPT and BERT
  • Adding Versatility to Java Logging Aspect

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook