Creating a single source jar for a multi-module gradle project - gradle

I have a multi-module gradle project setup like this:
Module A (Parent)
-build.gradle
-settings.gradle
+Module B
--src
---main
----java
----kotlin
--build.gradle
+Module C
--src
---main
----java
----kotlin
--build.gradle
In this instance, Module B has a compile time dependency on Module C.
I want to create a sources jar including the sources from all sub-projects to publish to my repository.
In single module builds I have added the following to my project, but adding it to all subprojects does not result in the collection of source sets in the sources jar produced:
sourceSets {
main.kotlin.srcDirs += 'src/main/kotlin'
main.java.srcDirs += 'src/main/java'
}
task sourcesJar(type: Jar) {
from sourceSets.main.kotlin
from sourceSets.main.java
archiveClassifier = 'sources'
}
How can I do this? ShadowJar works but unfortunately does not provide the option to create a sources jar as far as I know.

We have found a solution - deploy the sub-modules as independent sources jar and include them on an individual basis.
For example, in each sub-module:
sourceSets {
main.kotlin.srcDirs += 'src/main/kotlin'
main.java.srcDirs += 'src/main/java'
}
task sourcesJar(type: Jar) {
from sourceSets.main.kotlin
from sourceSets.main.java
archiveClassifier = 'sources'
}
publishing {
publications {
mavenJava(MavenPublication) {
groupId = rootProject.group
artifactId = "$rootProject.name-$project.name"
version = rootProject.project.version
from components.java
artifact sourcesJar
}
}

Related

How to collect javadoc jars into a zip file

For a multi-project Gradle project, foo, bar and baz. I'm trying to create a task which creates a zip file with both libraries and javadoc, i.e. foo.jar, AND foo-javadoc.jar..
./build.gradle
./settings.gradle
./foo/build.gradle
./bar/build.gradle
./baz/build.gradle
settings.gradle
include ":foo"
include ":bar"
include ":baz"
Top level build
allprojects {
apply plugin: 'java'
task generateJavadoc (type : Javadoc) {
source = sourceSets.main.allJava
classpath = sourceSets.main.compileClasspath
failOnError = false
}
task javadocJar(type: Jar, dependsOn: generateJavadoc) {
classifier = 'javadoc'
from generateJavadoc.destinationDir
}
artifacts {
archives javadocJar
}
}
task buildZip(type: Zip, dependsOn: build) {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from (project(':foo').configurations.runtime) {
into 'jars'
}
from (project (':foo').configurations.archives.all) {
into 'jars'
}
}
When I invoke this with gradle clean buildZip a zip file is created, but without the any -javadoc JARs I was expecting... The JavaDoc jars are generated into the project build directories, e.g. foo/build/lib/foo-javadoc.jar I've tried multiple combinations of from project (':foo').artifacts etc.
This is possible using the following. Note javadocJar is the name of the task defined in the allprojects block
from (rootProject.allprojects.javadocJar.outputs) {
into 'javadoc'
}

Exclude Compiled Source From Custom Jar with Gradle

I'm trying to build a JAR from a specific package of classes so I want to exclude all the other packages from this JAR. This is what I have...
task receiverJar(type: Jar) {
baseName = "receivers"
from sourceSets.main.output
include 'com/foo/receivers/**'
exclude 'com/foo/cli/**'
exclude 'com/foo/tdl/**'
with jar
}
When I execute gradle receiverJar I still get all the other packages and classes in my JAR file.
task receiverJar(type: Jar) {
enabled = true
baseName this.name + '-receivers'
from sourceSets.main.output
manifest {
attributes 'Implementation-Version': project.version
}
include 'com/foo/tdl/**'
exclude 'com/foo/cdl/**'
}

Publish (rootproject) pom without (rootproject) publishing artifact / packaging = pom

I'm migrating one of our projects from maven to gradle: it's a gradle multi-project & all subprojects are publishing artifacts to artifactory. So far so good.
The legacy (maven-based) build environment however also expects the root project to publish a pom file with the "packaging" node equal to "pom" (common maven behaviour, so it seems)
So now, I'm trying to have this generated by Gradle, but only find ways to customize an automatically generated pom for each artifact, I can't find a way to generate/upload a pom without publishing an actual artifact.
Workaround for now is to have the root project use the java plugin, generate/install an empty jar and manipulate the generated pom to conform to maven expectations (packaging=pom), but that's a hack.
Is there a way to have this root pom file generated with gradle ?
Example project:
settings.gradle
rootProject.name = 'MultiProject'
include 'child01', 'child02'
rootProject.children.each { it.name = rootProject.name + "-" + it.name }
build.gradle
subprojects {
apply plugin: 'java'
}
allprojects {
apply plugin: 'maven'
group = 'my_group'
version = '0.0.1-SNAPSHOT'
}
EDIT (current workaround), addition to build.gradle
// workaround to generate pom
apply plugin: 'java'
configurations {
pomCreation
}
task createPom {
ext.newPomFile = "${buildDir}/blabla.pom"
doLast {
pom {
project {
packaging 'pom'
}
}.writeTo(newPomFile)
}
}
install.dependsOn(createPom)
artifacts {
pomCreation file(createPom.newPomFile)
}
I would use the gradle maven-publish plugin for that. With that plugin you can define your specific pom and don't have to upload other artifacts. Here an example:
publishing {
publications {
maven(MavenPublication) {
pom.withXml{
def xml = asNode()
xml.children().last() + {
delegate.dependencies {
delegate.dependency {
delegate.groupId 'org.springframework'
delegate.artifactId 'spring-context'
delegate.version( '3.2.8.RELEASE' )
}
}
}
}
}
}

Configuration for projects in subdirectory

I have a Gradle multi-project build that looks like this:
rootProject
build.gradle
settings.gradle
shared/
SharedLib
SharedLib2
plugins/
FirstPlugin
SecondPlugin
I'd like to add all projects in the directory shared as dependencies to all projects in plugins.
More generally speaking: How do I configure subprojects by directory?
Contents of settings.gradle:
include 'plugins:FirstPlugin', 'plugins:SecondPlugin', 'shared:SharedLib', 'shared:SharedLib2'
Contents of build.gradle:
task wrapper(type: Wrapper) { gradleVersion = "2.1" }
allprojects{ apply plugin:"java" }
subprojects {
group = "eu.test.myGroup"
repositories { mavenCentral() }
dependencies { testCompile "junit:junit:4.11" }
}
Adding this to build.gradle does what I wanted to achieve:
// Define what's a plugin and what's a shared library by directory paths.
// Ignore empty projects
def plugins = subprojects.findAll{ it.path.contains("plugins") && hasSrc(it) }
def sharedLibs = subprojects.findAll{ it.path.contains("shared") && hasSrc(it)}
/** Checks whether a project has a source directory */
def hasSrc(proj){
return new File(proj.projectDir, "src").exists()
}
// Configure the plugins to depend on the shared libraries at compile time
configure(plugins) { dependencies { sharedLibs.each{compile it} } }

How to generate multiple jar files with gradle's java plugin

I have a multi-project gradle build using the java plugin setup as follows:
myProj/
settings.gradle
build.gradle
util/
build.gradle
In my util project, I would like to generate 2 jars... one for packageA and one for packageB. I'm a noob with gradle so any help here would be much appreciated. Here are my settings and gradle files:
myProj/settings.gradle
include 'util'
myProj/build.gradle
subprojects {
apply plugin: 'java'
repositories {
maven {
url "http://mymavenurl"
}
}
sourceSets {
main {
java {
srcDir 'src/java'
}
}
}
}
myProj/util/build.gradle
dependencies {
.
.
.
}
jar {
baseName = 'packageA'
includes = ['com/mycomp/packageA']
}
task packageBJar(type: Jar) {
dependsOn classes
includes = ['com/mycomp/packageB']
baseName = 'packageB'
}
When I try to build my project here is the output:
:util:compileJava
:util:processResources UP-TO-DATE
:util:classes
:util:jar
:util:assemble
:util:compileTestJava UP-TO-DATE
:util:processTestResources UP-TO-DATE
:util:testClasses UP-TO-DATE
:util:test
:util:check
:util:build
I would hope to see :util:packageBJar after classes, but I'm not having any luck.
One way is to declare packageBJar as an artifact of, say, the archives configuration:
artifacts {
archives packageBJar
}
Now gradle assemble, and therefore also gradle build, will produce packageBJar.

Resources