Why is Gradle ignoring groupId/artifactId? - gradle

Here is my Gradle build:
apply plugin: 'groovy'
apply plugin: 'maven'
group = 'myorg'
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.3'
compile 'org.apache.httpcomponents:httpclient:4.3.5'
compile 'org.slf4j:slf4j-api:1.7.5'
testCompile 'junit:junit:4.11'
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
artifacts {
archives sourcesJar
}
task createPom << {
pom {
project {
groupId group
artifactId "myapp"
version version
}
}.writeTo("build/libs/pom.xml")
}
And the build invocation I am using:
gradle clean build groovydoc sourcesJar createPom -Pversion=SNAPSHOT
When I run this:
The POM file is created with groupId, artifactId and version all appearing correctly inside the XML; but
The name of the resultant JAR is whatever folder the project is rooted under. For instance, if the name of my project root is "fizz", and the buildfile above is located at fizz/build.gradle, then the build invocation above produces fizz-<version>.jar (where <version> is whatever value I specify on the command line). If I now rename the fizz/ directory to buzz/ and re-run the same build invocation, a buzz-<version>.jar will be produced.
My question: how/where (what file) do I hardcode groupId and artifactId inside so that myapp-<version>.jar gets built, regardless of the name of the project root directory?

You need a settings.gradle in the project root and inside you set the rootProject.name = 'artifactId' this will fix the name of the project.
The groupId and version can be set in the build.gradle file via the group and version properties.

Related

pom.xml without dependencies using maven-publish plugin in a multi module gradle project

I've a gradle project with subprojects. Every subproject produces a jar and a pom that it's published on a repository
1) In the main project gradle file there's a subprojects section that I used to define what and where to publish:
snippet from rootproject.gradle:
subprojects {
apply plugin: 'maven-publish'
publishing {
publications {
mavenJava(org.gradle.api.publish.maven.MavenPublication) {
from components.java
}
}
repositories {
maven {
url 'file://c:/temp/repo'
}
}
}
}
2) In the gradle file of one of my subprojects, I've added some dependencies:
snippet from subproject.gradle:
dependencies {
compile group: 'my-group', name: 'my-module', version:'1.1.0'
}
If I run "gradle publish" from the rootproject it will correctly publish every subproject. However, I noticed that the dependency defined in the subproject is missing from the pom publication related to the subproject.
If I cut and paste the content of the subprojects section in each subproject, the generated pom file contains the correct dependency.
It seems that “from components.java” is not a reference to something that should be used by the publish task to produce the pom, but the task will publish exactly what components.java contains when you call the “from” method.
As a workaround, I moved the subprojects code in a method defined in the root:
rootproject.gradle
def configurePublishing(project) {
project.apply plugin: 'maven-publish'
…
}
And I called it from each subproject:
subproject.gradle
dependencies {
compile group: 'my-group', name: 'my-module', version:'1.1.0'
}
configurePublishing(project)
Another solution could be adding a switch in the subprojects section and centralize everything in the gradle file of the root project:
subprojects { subProject ->
switch(subproject.name) {
case: ‘my-subproject-with-dependencies’ {
dependencies {
compile group: 'my-group', name: 'my-module', version:'1.1.0'
}
break;
}
}
apply plugin: 'maven-publish'
}
Is it an acceptable approach? Is there a best practice to follow? Is there an easier way to do it?

dependent jar is not bundled along with project jar Gradle

I have a project corehibernate and a project coregeneral. corehibernate is dependent on coregeneral. I need the jar file of coregeneral to be bundled along with the corehibernate jar. I tried various versions of the build.gradle thing, nothing worked.
I tried compile files("../coregeneral/build/libs/coregeneral.jar")
This version of fatJar too does not work.
apply plugin: 'java'
repositories {
jcenter()
}
dependencies {
compile (':coregeneral')
testCompile 'junit:junit:4.12'
}
jar {
baseName='corehibernate'
from ('bin')
}
task fatJar(type: Jar, dependsOn: jar) {
baseName = project.name + '-fat'
}
There are two basic ways how to bundle projects together. The first would be to use application plugin which creates a zip with scripts that will also execute your application and bundle all jars by default. Second way is to use distribution plugin and define the final archive yourself (zip or tar).
Here is a sample project using the application plugin:
settings.gradle
rootProject.name = 'root'
include 'partone', 'parttwo'
build.gradle
subprojects {
apply plugin: 'java'
}
partone/build.gradle - this one is empty
parttwo/build.gradle
apply plugin: 'application'
mainClassName = 'Hello'
dependencies {
compile project (':partone')
}
Give that both projects actually have some content (classes), when you run gradle :projecttwo:build it will generate a zip file with executable scripts and both jars bundled inside.
If you prefer to use distribution plugin, change the parttwo/build.gradle to:
apply plugin: 'distribution'
distributions {
main {
contents {
from jar
from (project.configurations.runtime)
}
}
}
dependencies {
compile project (':partone')
}
And again run gradle :parttwo:build. It will create a zip file that contains both jars.

Collect build artifacts from subprojects into RPM with Gradle

I have the following project structure:
Root
+---Sub1
|
+---Sub2
Sub1 project produces JAR, Sub2 creates WAR.
Root project goal is to produce RPM that contains both the Sub1 and Sub2 output.
I'm trying to use ospackage Gradle plugin to build RPM. Here is part of root build.gradle:
ospackage {
from subprojects.collect { it.tasks.withType(Zip) } into 'lib'
}
It works but for Sub2 both JAR and WAR are created, which is undesirable.
What configuration should be applied in order to collect appropriate jars and wars into RPM?
UPDATE
I'm searching for some generic solution, i.e. iteration over subprojects is preferable to specifying behaviour for each subproject.
The solution is to add WAR plugin in Sub2 project's build.gradle:
apply plugin: 'war'
make buildRpm task dependent on all subprojects build tasks in the root build file:
buildRpm.dependsOn getTasksByName('build', true)
and finally configure ospackage plugin to collect the artifacts into the target RPM:
ospackage {
from(subprojects.collect { "${it.buildDir}/libs" }) {
into 'bin'
}
}

How to generate a war file based on two subprojects

I have a project which is splitted into two subprojects.
/project
/sub-project-a (backend with JAVA source which is compiled into JAR file)
/sub-project-b (frontend sources which are compiled with grunt via gradle call)
build.gradle
settings.gradle (contains include 'sub-project-a', 'sub-project-b')
My Question is how can I create a War file with sub-projects and external lib dependencies? The following code snipped is my current build.gradle:
apply plugin: 'war'
version '1.0.0'
repositories {
mavenCentral()
}
dependencies {
compile project(':sub-project-a')
compile project(':sub-project-b')
compile 'com.google.code.gson:gson:2.2.4'
}
task copy(type: Copy) {
from 'sub-project-a/build', 'sub-project-b/build'
into 'build'
}
build.dependsOn clean, copy
war {
archiveName 'project.war'
}
One detail is important. The java context listener (deep inside project code) work with compiled backend as jar file from WEB-INF/lib folder. This means that all class files can't be easily used from WEB-INF/classes folder.
As you can see I played with dependencies and a custom copy task. I'm not sure what is right gradle way. How should I do this?
SOLUTION
Define with war.from methode, where you get your static sources.
gradle docu
from(sourcePaths) -
Specifies source files or directories for a copy. The given paths are
evaluated as per Project.files().
My changed build.gradle
apply plugin: 'war'
version '1.0.0'
repositories {
mavenCentral()
}
dependencies {
compile 'com.google.code.gson:gson:2.2.4'
}
war {
archiveName 'project.war'
from 'sub-project-a/build/dist', 'sub-project-b/build/dist'
}
SOLUTION (for cleanly closing this question) shamefully taken from the question's originator ;-)
Define subproject dependencies with the "war.from" method, where you get your static sources.
gradle documentation excerpt: from(sourcePaths) - Specifies source files or directories
for a copy. The given paths are evaluated as per Project.files().
Ronny's changed build.gradle
apply plugin: 'war'
version '1.0.0'
repositories {
mavenCentral()
}
dependencies {
compile 'com.google.code.gson:gson:2.2.4'
}
war {
archiveName 'project.war'
from 'sub-project-a/build/dist', 'sub-project-b/build/dist'
}

How to add other projects in current project in Gradle?

I have two projects ProjA and ProjB, here ProjB is depends on ProjA. So, how to include ProjA in ProjB?
And please let me know in case change in the ProjA build.gradle file?
Okay, so you have two projects, whereas ProjA depends on ProjB.
If you have already set up a gradle build for those, both of them will have a file settings.gradle, which at least defines the project name and build.gradle, where you can specify the dependencies.
Example:
settings.gradle
rootProject.name = 'ProjA'
build.gradle
group = 'mygroup'
version = '1.0'
By further adding one of Gradle's publishing plugins (see Maven publishing or Ivy publishing), you can configure a publication. A publication in turn contains artifacts, that is the files you want to upload (and usually some repositories).
Example for a minimal Maven publication:
apply plugin: 'maven-publish'
publishing {
publications {
core(MavenPublication) {
from components.java
}
}
}
The maven-publish plugin will add the task publishToMavenLocal (among others) to your project which installs the jar somewhere to ~/.gradle/caches/.
In build.gradle of ProjB you can then define a compile time dependency on ProjA like so:
dependencies {
compile(group: 'mygroup', name: 'ProjA', version: '1.0')
}
If your projects are co-located, you could have a multi build project.
Say you have a root folder with these contents:
some root directory
project-a
project-a.gradle
src
project-b
project-b.gradle
src
build.gradle
settings.gradle
settings.gradle contains:
include 'project-a', 'project-b'
project-b.gradle then depends on project A:
dependencies {
compile project(':project-a')
}
After this, project a will always compile and assemble before project-b and the jar file for project-a jar will be on the classpath when compiling project-b.

Resources