Skip building jar in Gradle groovy scripts project - gradle

I have a gradle groovy project where I only have groovy scripts that are not in a source dir, but a separate dir. Additionally I have groovy junit tests that test the scripts invoking them using groovy shell.
I have a gradle build that runs the tests, then zips the scripts into separate zip files and uploads them into maven repo. The problem is, that gradle also creates and uploads a jar file. Since there are no files in source dirs, the jar contains only a generated manifest file.
In reality I don't need the jar at all.Is it possible to configure gradle to not create a jar file for a groovy project?
I upload the artifacts using uploadArchives task.
My full gradle config:
group 'groupName'
version '1.0-SNAPSHOT'
apply plugin: 'groovy'
apply plugin: 'java'
apply plugin: 'maven'
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.11'
testCompile group: 'junit', name: 'junit', version: '4.11'
}
task scriptsZip(type: Zip) {
from 'scripts'
}
artifacts {
archives file: scriptsZip.archivePath, type: 'zip', classifier: 'scripts', builtBy: scriptsZip
}
uploadArchives {
repositories {
mavenDeployer {
repository(url: "file://C:\\testRepo")
}
}
}

You can modify the jar task with an onlyIf condition, to skip building the jar when some condition is met (or not met)
jar {
onlyIf { /*some condition*/ }
}
In your case, it might make sense to check if there are any source files in your main sourceset:
jar {
onlyIf { !sourceSets.main.allSource.files.isEmpty() }
}

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.

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 simplify this Gradle command line?

I am new to Gradle and have gotten a fairly sophisticated build working with it so far (runs tests, uses CodeNarc, generates API docs, generates a sources JAR, etc.). The command line for a "full build" (that is, to execute all the major tasks that the CI server should be running), I need to enter the following Gradle command at the shell:
gradle clean build check groovydoc sourcesJar createPom dist -Pversion=<version>
Where <version> is the version I want to build.
I would like to condense this and add an alias so that all of the above can be accomplished with something simple, like:
gradle full-build
Is this possible? If so, how?
My build.gradle
apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'codenarc'
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.3'
testCompile 'junit:junit:4.11'
}
groovydoc
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
artifacts {
archives sourcesJar
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
task dist(type: Zip, dependsOn: build) {
classifier = 'buildreport'
from('build/test-results') {
include '*.xml'
into 'tests'
}
from('build/reports/codenarc') {
into 'reports'
}
from('build/docs') {
into 'api'
}
from(sourcesJar) {
into 'source'
}
from('build/libs') {
exclude '*-sources.jar'
into 'bin'
}
}
task createPom << {
pom {
project {
groupId "me"
artifactId "myapp"
version version
}
}.writeTo("build/libs/myapp-${version}.pom")
}
In the above build invocation, at least check and sourcesJar can be omitted already. (build depends on check, and from(sourcesJar) tells Gradle that dist depends on sourcesJar.) By adding further task dependencies (e.g. build.dependsOn dist), you can cut it down to gradle clean build -Pversion=.... dist should not depend on build but on the specific tasks that produce the artifacts that go into the zip (e.g. groovydoc and createPom).
Reducing gradle clean build to gradle fullBuild is more difficult, as Gradle doesn't currently have a first-class concept of "aliases", and adding build.dependsOn(clean) is usually not desirable. One way out is to implement your own aliasing mechanism by manipulating gradle.startParameter.taskNames.

Using jettyRunWar or jettyRun in Gradle with a Spring Boot app results in just a directory listing in the browser

I'm using Gradle and Spring Boot for the first time. I decided to create a project that actually builds a WAR archive and I'm using the Gradle Jetty plugin. If I run the jettyRun or jettyRunWar tasks, in my browser all I'm seeing is a directory listing, not my actual application.
For example, the jettyRunWar task results in a directory listing like this:
META-INF/
WEB-INF/
dist/
The dist/ directory contains my static files.
Maybe I'm missing something fundamental since I'm using Gradle and Spring Boot for the first time.
I'm trying to test my app while making changes to my static files without restarting the app. Here is my build.gradle file.
buildscript {
repositories {
maven { url "http://repo.spring.io/libs-snapshot" }
mavenLocal()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:0.5.0.M6"
}
}
apply plugin: "java"
apply plugin: "idea"
apply plugin: "spring-boot"
apply plugin: "war"
war {
baseName = "mis-support-client"
version = "1.0.0-SNAPSHOT"
includes = ["dist/**"]
}
repositories {
mavenCentral()
maven { url "http://repo.spring.io/libs-snapshot" }
}
dependencies {
testCompile "junit:junit:4.11"
compile ("org.springframework.boot:spring-boot-starter-web:0.5.0.M7") {
exclude module: "spring-boot-starter-tomcat"
}
compile "org.springframework.boot:spring-boot-starter-jetty:0.5.0.M7"
compile "org.springframework.boot:spring-boot-starter-security:0.5.0.M7"
compile "org.springframework.boot:spring-boot-starter-websocket:0.5.0.M7"
compile "javax.inject:javax.inject:1"
compile "org.codehaus.jackson:jackson-mapper-asl:1.9.12"
compile "org.apache.httpcomponents:httpclient:4.3.1"
compile "commons-io:commons-io:2.4"
}
task wrapper (type: Wrapper) {
gradleVersion = "1.8"
}
Did you try ./gradlew bootRun instead? Normal Spring Boot project has server embedded for easier usage :)
This task requires gradle plugin:
apply plugin: 'spring-boot'
Features
Embed Tomcat or Jetty directly (no need to deploy WAR files)
Task
Execution tasks
---------------
bootRun - Run the executable JAR/WAR

Resources