Gradle fatJar排除指定依赖失效问题排查与解决求助
Hey, let's figure out why those AspectJ Jars are still showing up in your fatJar and fix this step by step.
First, let's spot the most obvious issue in your code:
.filter({ !it.name.equalsIgnoreCase('aspectjrt-1.9.4.jar') !it.name.equalsIgnoreCase('aspectjtools-1.9.4.jar') })
In Groovy, these two lines don't act as a combined filter condition—you're missing a && operator between them. The first check gets treated as a throwaway statement, so only the second check actually runs. That means aspectjrt-1.9.4.jar never gets filtered out at all.
Common Reasons for the Issue
- Syntax error breaking filtering: The missing logical operator we just covered is the immediate culprit
- Overlapping dependency configurations:
compileandruntimeClasspathmay share dependencies, though this wouldn't be a problem if the filter worked correctly - Hidden transitive dependencies: Other libraries in your project might be pulling in these AspectJ Jars indirectly, even if you don't declare them explicitly
Fixes to Try
1. Correct the Filter Logic First
Let's rewrite the filter to properly check both Jar names, using a list to keep the code clean and maintainable:
task fatJar(type: Jar) { zip64 = true manifest { attributes( 'Implementation-Title': project.name, ) } // Store excluded Jar names in a list for easy updates def excludedJarNames = ['aspectjrt-1.9.4.jar', 'aspectjtools-1.9.4.jar'].collect { it.toLowerCase() } from { configurations.compile .filter { jarFile -> !excludedJarNames.contains(jarFile.name.toLowerCase()) } .collect { it.isDirectory() ? it : zipTree(it) } } from { configurations.runtimeClasspath .filter { jarFile -> !excludedJarNames.contains(jarFile.name.toLowerCase()) } .collect { it.isDirectory() ? it : zipTree(it) } } from { sourceSets.main.output.classesDirs } }
This ensures both Jar names are properly validated and excluded from the fatJar.
2. Exclude Dependencies at the Source (Recommended)
Instead of filtering during packaging, it's more reliable to block these dependencies from entering your project's classpath entirely. Add this to your build script:
// Exclude AspectJ dependencies from core configurations configurations { compile { exclude group: 'org.aspectj', module: 'aspectjrt' exclude group: 'org.aspectj', module: 'aspectjtools' } runtimeClasspath { exclude group: 'org.aspectj', module: 'aspectjrt' exclude group: 'org.aspectj', module: 'aspectjtools' } } // Simplified fatJar task (no filters needed now) task fatJar(type: Jar) { zip64 = true manifest { attributes( 'Implementation-Title': project.name, ) } from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } from { sourceSets.main.output.classesDirs } }
Using group and module is better than filename checks because it works even if the Jar version changes (e.g., aspectjrt-1.9.20.jar would still be excluded automatically).
3. Hunt Down Transitive Dependencies
If the Jars still appear, they're likely coming from a transitive dependency. Run this command to visualize your full dependency tree:
./gradlew dependencies --configuration runtimeClasspath
Look for which library is pulling in AspectJ, then exclude it directly in that dependency declaration:
dependencies { implementation('com.example:some-dependency:1.0.0') { exclude group: 'org.aspectj', module: 'aspectjrt' exclude group: 'org.aspectj', module: 'aspectjtools' } }
Bonus: Use the Shadow Plugin for Hassle-Free Fat Jars
If you regularly build fat Jars, the official Shadow plugin handles dependency exclusion, duplicate classes, and edge cases far better than a custom Jar task. Add it to your build script:
plugins { id 'com.github.johnrengelman.shadow' version '7.1.2' } shadowJar { zip64 = true manifest { attributes 'Implementation-Title': project.name } // Exclude the entire AspectJ package (or use dependency exclusion below) exclude 'org/aspectj/**' // Alternative: Exclude by dependency group/module dependencies { exclude(dependency('org.aspectj:aspectjrt')) exclude(dependency('org.aspectj:aspectjtools')) } }
Run ./gradlew shadowJar to generate a clean fatJar without unwanted dependencies.
内容的提问来源于stack exchange,提问作者Swapnil Kotwal

