Reputation: 272577
I have a Gradle project which does a couple of orthogonal things:
This artifact is nothing to do with the Java; it's generated by a custom JavaExec task. However, the auto-generated POM (from the Maven plugin) seems to include the wrong dependencies. Question: How can I prevent this?
My build.gradle looks something like this:
apply plugin: "java"
apply plugin: "maven"
configurations {
foo // Custom configuration for the artifact I want to build and publish
}
// Dependencies for Java configurations (nothing to do with foo)
dependencies {
compile "foo:foo:1.1"
testCompile "bar:bar:2.2"
}
// Custom task
task generateFoo(type: JavaExec) {
ext.outputFile = new File(buildDir, "foo.bar")
...
}
artifacts {
foo file: generateFoo.outputFile, builtBy: generateFoo
}
uploadFoo {
repositories {
mavenDeployer { ... }
}
}
I invoke Gradle like this:
./gradlew uploadFoo
AFAICS, the foo
configuration is unrelated to the Java configurations. So I expect the published POM to list no dependencies. However, I observe all the unrelated dependencies listed.
The Gradle docs for the Maven plugin hint at dependency mapping with conf2ScopeMappings
, but I'm entirely unclear what (if anything) I should be doing with this.
Upvotes: 2
Views: 2170
Reputation: 2329
I managed to setup similar configuration with both maven
and maven-publish
gradle plugins.
In my case I was using custom Jar task with custom configuration, but it should work because the artifacts { ... }
are used in both cases.
With maven
plugin, your build.gradle
would look like:
apply plugin: "java"
apply plugin: "maven"
configurations {
foo // Custom configuration for the artifact I want to build and publish
}
// Dependencies for Java configurations (nothing to do with foo)
dependencies {
compile "foo:foo:1.1"
testCompile "bar:bar:2.2"
}
// Custom task
task generateFoo(type: JavaExec) {
ext.outputFile = new File(buildDir, "foo.bar")
...
}
artifacts {
foo file: generateFoo.outputFile, builtBy: generateFoo
}
uploadFoo {
repositories {
mavenDeployer {
pom.scopeMappings.with {
mappings.clear()
addMapping(300, configurations.foo, 'runtime')
}
pom.artifactId = 'other artifact id than main jar'
...
}
}
}
This solution was inspired by following thread:
http://gradle.1045684.n5.nabble.com/pom-generation-and-inherited-dependencies-td1436197.html
Note the line:
addMapping(300, configurations.foo, 'runtime')
You can add other configurations as well, or use other maven scope than the 'runtime' scope.
300 stands for priority, which is not significant in this case.
Advantage of this solution is that we have quite fine control over dependencies and their mappings. Disadvantage would be that this will not work for the install
task. We would need to setup different poms for the install task, which might be possible, but it is beyond my knowledge.
Alternative with usage of maven-publish
plugin:
apply plugin: "java"
apply plugin: "maven-publish"
configurations {
foo // Custom configuration for the artifact I want to build and publish
}
// Dependencies for Java configurations (nothing to do with foo)
dependencies {
compile "foo:foo:1.1"
testCompile "bar:bar:2.2"
}
// Custom task
task generateFoo(type: JavaExec) {
ext.outputFile = new File(buildDir, "foo.bar")
...
}
artifacts {
foo file: generateFoo.outputFile, builtBy: generateFoo
}
publishing {
publications {
foo(MavenPublication) {
from new org.gradle.api.internal.java.JavaLibrary(\
configurations.api.artifacts.toArray()[0], \
configurations.api.allDependencies)
artifactId 'other artifact id than main jar'
}
}
repositories {
maven { ... }
}
}
gradle tasks
will give you possible publish commands:
publish - Publishes all publications produced by this project.
publishFooPublicationToMavenLocal - Publishes Maven publication 'foo' to the local Maven repository.
publishFooPublicationToMavenRepository - Publishes Maven publication 'foo' to Maven repository 'maven'.
publishToMavenLocal - Publishes all Maven publications produced by this project to the local Maven cache.
...
The advantege of maven-publish
alternative is that it will work for both local and remote maven repositories. Disadvantage may be a fact that we are using the internal API which may change in future and that all dependencies are mapped to the 'runtime' maven scope. Also the MavenPublication snippet would be much more verbose and more internal API would be used if we would like to use some other maven scope or apply some scope mapping.
I am using Gradle 1.10
Upvotes: 5