sourcesJar task in gradle 5 - java

I have inherited a codebase which I suspect was originally built with Gradle 4 (but I don't know for sure). I am using Gradle 5.5.1 and when I run gradle I get errors to do with publication to a Maven repo:
* What went wrong:
A problem occurred evaluating root project 'common'.
> Could not find method sourcesJar() for arguments [build_d1u03z05r8d12r3e8b5qq1fxm$_run_closure3$_closure13$_closure15$_closure16#190bc2b8] on object of type org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication.
Add sourcesJar task to custom Gradle plugin looks like a similar problem but it is a different error and their solution doesn't work anyway.
The relevant parts of my build.gradle are:
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourcesJar {
classifier "sources"
}
artifact testJar {
classifier "tests"
}
}
}
repositories {
maven {
url 'http://repo.url'
credentials {
username "$username"
password "$password"
}
}
}
}
task sourcesJar(type: Jar) {
from sourceSets.main.allSource
classifier = 'sources'
}
task testJar(type: Jar) {
from sourceSets.test.output
classifier = 'tests'
}

Okay I think I figured it out: https://docs.gradle.org/5.5.1/userguide/publishing_maven.html#publishing_maven:deferred_configuration says that a publishing block was executed after the rest of the project in Gradle 4, but not in Gradle 5.
So, changing
artifact sourcesJar {
classifier "sources"
}
artifact testJar {
classifier "tests"
}
to
afterEvaluate {
artifact sourcesJar {
classifier "sources"
}
artifact testJar {
classifier "tests"
}
}
got me a little further. With that change I then got this error:
* What went wrong:
A problem occurred configuring root project 'common'.
> Cannot create a Publication named 'sourcesJar' because this container does not support creating elements by name alone. Please specify which subtype of Publication to create. Known subtypes are: MavenPublication
https://discuss.gradle.org/t/cannot-create-a-publication-named-x/3726 and Gradle: Using 'maven-publish' plugin in custom standalone plugin seem to suggest that a prefix of project. should fix it.
So changing it to:
afterEvaluate {
artifact project.sourcesJar {
classifier "sources"
}
artifact project.testJar {
classifier "tests"
}
}
seems to work, though I'm a little iffy on the project. prefix.

In my case I had to add the following that Gradle was aware about the artifacts:
java {
withJavadocJar()
withSourcesJar()
}
Then I was able to use it this way:
publishing.publications {
mavenJava(MavenPublication) {
from components.java
}
}
Javadoc as well as Sources were published. There seems to be no need to add the afterEvaluate block.

In this block:
artifact sourcesJar {
classifier "sources"
}
artifact testJar {
classifier "tests"
}
remove the closures...just make it look like this:
artifact sourcesJar
artifact testJar

Related

What is the proper way to migrate this pom maven task to maven-publish?

I have this task in my build.gradle file that was using maven:
task pom {
doLast {
pom {
project {
groupId "${project.group}.${project.name}"
artifactId project.name
version project.version
}
}.writeTo ("$buildDir/libs/${project.name}.pom")
}
}
Now its my task to get this project ready for gradle 7, and part of that means upgrading maven to maven-publish. The above code snippit doesn't work with maven-publish, as pom() isn't a recognized method. What is the proper way to migrate this code over to maven-publish?
Try this, based on the Official Gradle Publishing Maven page:
publishing {
publications {
MavenCustom(MavenPublication) {
from components.java
groupId "${project.group}.${project.name}"
artifactId project.name
version project.version
}
}
}
model {
tasks.generatePomFileForMavenCustomPublication {
destination = file("$buildDir/libs/${project.name}.pom.xml")
}
}

How to publish and use gradle plugin with dependencies on local project?

I am creating gradle plugin which has dependency on my other local module. Some of its gradle build look like this:
dependencies {
compile gradleApi()
compile project(":myDependencyProject")
}
publishing {
publications {
maven(MavenPublication) {
groupId = 'org.my.gradle.plugin'
artifactId = 'some-name'
version = '1.0-SNAPSHOT'
from components.java
}
}
}
gradlePlugin {
plugins {
jsonPlugin {
id = 'org.my.gradle.plugin'
implementationClass = 'my.implementation.class'
}
}
}
When I publish my plugin using gradle publishToMavenLocal and after that I try to use that plugin in another project it fails with this error:
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':my-project'.
> Could not resolve all artifacts for configuration ':my-project:classpath'.
> Could not find org.my.gradle.plugin:myDependencyProject:1.0-SNAPSHOT.
Searched in the following locations: ...
In simple words it could not find dependency for myDependencyProject project. That is why as a next step I tried to create a fat jar and publish it but I have got the same error (the code for gradle plugin was same except I have changed from components java to artifact shadowJar).
Can someone help me how can I publish gradle plugin with its local dependencies and use it in another project ?
Thank you very much for any help.
We ended up using the Gradle shadow plugin to include our module in the published artifact.
One thing that was important to us though, was to only include the local library in it to prevent our end consumer from having 2 copies of some library (such as Kotlin). So we filtered the dependencies
shadowJar {
dependencies {
include(dependency(':your-module-name:'))
}
}

How to get sources from parent project as dependency

I want to do something like this:
dependencies {
compile project(':projectA', classifier: 'sources')
}
But I couldn't find such functionallity, I've searched in the documentation but there was nothing besides specifying the classifier on real dependencies.
So it there a way on adding the sources from an parent project inside a Gradle multimodules project as dependency?
I'm not aware that there is a feature from Gradle for that, but there is a workaround:
Add an packageSources to the project which should provide sources
// projectA/build.gradle
project.task("packageSources", type: Jar) {
classifier = 'sources'
from { project.sourceSets.main.allSource }
}
Depend the task on compileJava where you need the sources
// projectB/build.gradle
compileJava.dependsOn tasks.getByPath(':projectA:packageSources')
Add the source as dependency
// projectB/build.gradle
dependencies {
compile files(tasks.getByPath(':projectA:packageSources').archivePath)
}
projectA/build.gradle
configurations {
sources
}
dependencies {
sources sourceSets.main.allSource
}
projectB/build.gradle
dependencies {
compile project(path: ':projectA', configuration: 'sources')
}
See DependencyHandler.project(Map)

Configure Gradle to publish sources and javadoc

How do I configure Gradle to publish sources and javadoc jars to a repository?
Solution as of Gradle 6.0
Here’s the somewhat minimal configuration you can use if you’re on Gradle 6.0 or later; note the newly introduced withSourcesJar() and withJavadocJar() methods:
plugins {
id 'java'
id 'maven-publish'
}
group = 'com.example'
java {
withSourcesJar()
withJavadocJar()
}
publishing {
repositories {
maven {
url = 'file:///tmp/my-repo'
}
}
publications {
myJava(MavenPublication) {
from components.java
}
}
}
Of course, you can also use the ivy-publish plugin instead of maven-publish.
See also the Gradle docs:
on the two new methods
on the maven-publish plugin
on the ivy-publish plugin
Add the following code to the build script:
task packageJavadoc(type: Jar, dependsOn: 'javadoc') {
from javadoc.destinationDir
classifier = 'javadoc'
}
task packageSources(type: Jar, dependsOn: 'classes') {
from sourceSets.main.allSource
classifier = 'sources'
}
artifacts {
archives packageJavadoc
archives packageSources
}
Tested with Gradle 1.10
2017, Gradle 4.0 Edition:
apply plugin: 'maven'
apply plugin: 'maven-publish'
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourceJar
artifact packageJavadoc
}
}
}
javadoc {
source = sourceSets.main.allJava
classpath = configurations.compileClasspath
options
{
setMemberLevel JavadocMemberLevel.PUBLIC
setAuthor true
links "https://docs.oracle.com/javase/8/docs/api/"
}
}
task sourceJar(type: Jar) {
classifier = 'sources'
from sourceSets.main.allJava
}
task packageJavadoc(type: Jar) {
from javadoc
classifier = 'javadoc'
}
Works with gradle publish and gradle publishToMavenLocal
Paolo Fulgoni's answer used to work for until I bumped up my Gradle version to 3.1. To get the packageJavadoc Task to work with Gradle 3.1 I found I had to make a slight tweak to it as follows:
task packageJavadoc(type: Jar) {
from javadoc
classifier = 'javadoc'
}

How to build sources JAR with Gradle?

I am working with an open source project that is built with Gradle. I would like to generate a (project)-sources.jar file that I can load into my IDE (IntelliJ IDEA) and debug through the project. I know how to load the file if I can generate it.
I have looked through the available Gradle tasks for the project and there isn't one that generates a sources jar file.
What is the easiest way to generate a sources jar file for this project?
Adding the source into the jar file that contains the compiled class files would be fine as well.
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourcesJar
archives javadocJar
}
Solution as of Gradle 6.0
Assuming that you use the java/java-library plugin with Gradle 6.0 or later, you can get a sourcesJar task using the following configuration:
java {
withSourcesJar()
// and/or analogously use “withJavadocJar()” to get a “javadocJar” task
}
If you additionally use the maven-publish/ivy-publish plugin (recommended nowadays), then this will also publish a *-sources.jar artifact along with your main Java publication.
See also the Gradle docs.
If you're using Android:
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives javadocJar
archives sourcesJar
}
from here
If you wish to add the sources to the compiled classes JAR file, which you also said would be acceptable, you can do that easily enough. Just add the following to your build file. You can see that, in theory, it is quite like the solution for putting sources into a separate JAR:
jar {
from sourceSets.main.allSource
}
The difference is that you are adding it to the main JAR file by saying "jar" in lieu of sourcesJar.
this should work
assemble.dependsOn 'propertyJar'
task propertyJar(type: Jar) {
archiveName = "myJarName.jar"
from('src/main/resources') {
include '**'
}}
When using:
Gradle: 5+
java and maven-publish plugins
task sourceJar(type: Jar) {
from sourceSets.main.allJava
archiveClassifier = "sources"
}
publishing {
publications {
maven(MavenPublication) {
from components.java
artifact sourceJar
}
}
}
https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPublication.html
The Kotlin DSL equivalent would be:
tasks {
val sourcesJar by creating(Jar::class) {
dependsOn(JavaPlugin.CLASSES_TASK_NAME)
classifier = "sources"
from(java.sourceSets["main"].allSource)
}
val javadocJar by creating(Jar::class) {
dependsOn(JavaPlugin.JAVADOC_TASK_NAME)
classifier = "javadoc"
from(java.docsDir)
}
artifacts {
add("archives", sourcesJar)
add("archives", javadocJar)
}
}
This is how I included Dokka (view it online) and sources JARs for my Android Kotlin library using Kotlin DSL (build.gradle.kts):
plugins {
// ...
id("org.jetbrains.dokka") version "1.4.32"
id("maven-publish")
}
lateinit var sourcesArtifact: PublishArtifact
lateinit var javadocArtifact: PublishArtifact
tasks {
val sourcesJar by creating(Jar::class) {
archiveClassifier.set("sources")
from(android.sourceSets["main"].java.srcDirs)
}
val dokkaHtml by getting(org.jetbrains.dokka.gradle.DokkaTask::class)
val javadocJar by creating(Jar::class) {
dependsOn(dokkaHtml)
archiveClassifier.set("javadoc")
from(dokkaHtml.outputDirectory)
}
artifacts {
sourcesArtifact = archives(sourcesJar)
javadocArtifact = archives(javadocJar)
}
}
publishing {
// ...
publications {
create<MavenPublication>("MyPublication") {
from(components["release"])
artifact(sourcesArtifact)
artifact(javadocArtifact)
// ...
}
}
}
Android:
task androidSourcesJar(type: Jar) {
getArchiveClassifier().set('sources')
from android.sourceSets.main.java.srcDirs//full sources
}
Java:
task sourcesJar(type: Jar, dependsOn: classes) {
getArchiveClassifier().set('sources')
from sourceSets.main.allSource
}

Categories

Resources