I asked this long ago and there is an archived answer from the Old Forum, but that solution doesn’t work with Gradle 5.
I want to replace the default jar with an obfuscated one. Ideally this would be conditional, so I could do an unobfuscated build vs and obfuscated build.
The jar task creates a JAR file containing the class files and resources of the project. The JAR file is declared as an artifact in the archives dependency configuration. This means that the JAR is available in the classpath of a dependent project. If you upload your project into a repository, this JAR is declared as part of the dependency descriptor. You can learn more about how to work with archives in Archive creation in depth and artifact configurations in Legacy Publishing.
Tried that as well (removing the file from both ‘runtime’ and ‘archives’ configurations. It doesn’t work. When I list the files that come from project A (where I do the stuff shown above, even including the archives configuration) in sibling project B. I still see the output of A:jar listed.
When I try to remove the unobfuscated jar using:
configurations.default.artifacts.removeAll { …some condition… }
there are NO artifacts present to remove. I tried this in a doLast for the obfuscate task which runs after the jar task has produced the unobfuscated jar. The default configuration seems to be “special”.
I am currently using a workaround similar to what you proposed (in your deleted comment) by putting the jar I want in a separate configuration ‘outputJar’ - this allows me to pick the unobfuscated or obfuscated jar as output of project A without doing anything in the downstream project B… but it is not ideal as anyone depending on A must remember to not depend on the default configuration.
I wish Gradle had a more straightforward way of handling a task that wants to replace an artifact produced by another task that runs earlier. There are many possible reasons to do this for the default artifact… e.g. if you want to sign it with a specific tool, or transform it in any way… like inject another file into an archive, etc.
Yeah they know how to make life hard for users. I needed the same some time ago. Ended up writing plugin in Kotlin. Used this extension function to remove the clear jar from all configurations. Somewhere around Gradle 4.8-10 they started using LazyPublishArtifact that complicated things even further!
fun Project.removeArtifacts(task: Task, excludeDefaultConfiguration: Boolean = true) {
configurations.stream()
.filter { if (excludeDefaultConfiguration) it.name != Dependency.DEFAULT_CONFIGURATION else true }
.forEach {
it.artifacts.removeIf {
// it is ArchivePublishArtifact && it.archiveTask == task
// FIXME: LazyPublishArtifact doesn't provide information about archiveTask
it.file == task.outputs.files.files.first()
}
}
}
After that I’m adding the the obfuscated artifact to configurations with:
Just wanted to thank you for your code! In my case I had disabled the default jar task (jar.enabled = false) and added a bunch of new jar tasks producing archives. That worked fine on the command line, but when using Eclipse Buildship dependent projects still kept looking for the non-existent default JAR when the project was closed. Your code, slightly modified to only remove the default JAR, was the solution:
// Remove the default jar archive which is added by the 'java' plugin.
// This is necessary so that Eclipse pulls in the schema JARs properly to dependent projects
// when this project is closed.
configurations.each { cfg ->
cfg.artifacts.with { archives ->
def artifacts = []
archives.each {
if (it.file =~ jar.archiveName) {
// We can't just call `archives.remove(it)` here because it triggers
// a `ConcurrentModificationException`, so we add matching artifacts
// to another list, then remove those elements outside of this iteration.
artifacts.add(it)
}
}
artifacts.each {
archives.remove(it)
}
}
}
Note that it only worked for me if I used the java plugin – using the java-library plugin caused my artifact JARs to not be picked up by dependent projects when built using the CLI.