Why gradle jars are written in `build/libs`? - gradle

According to the documentation of the Jar plugin, the output directory is controlled by the destinationDir property:
File destinationDir
The directory where the archive is generated into.
Default with java plugin: project.distsDir
Looking at the documentation of the Project class the same property is mentioned:
Properties added by the java plugin
distsDir: The directory to generate TAR and ZIP archives into.
distsDirName: The name for the distributions directory. This in interpreted relative to the project' build directory.
And Googling a bit I find a document specifying their defaults:
File distsDir (read-only)
The directory to generate TAR and ZIP archives into.
Default with java plugin: ${project.buildDir}/${project.distsDirName}
String distsDirName
The name for the distributions directory. This in interpreted relative
to the project' build directory.
Default with java plugin: 'distributions'
All these documents point to the same Gradle version, that matches the one I have installed.
I add this in my build.gradle to check the real values of these properties:
println("distsDirName = " + project.distsDirName)
println("distsDir = " + project.distsDir.toString())
jar {
println("jar.destinationDir = " + destinationDir)
}
And finally, I run ./gradlew and check the output:
distsDirName = distributions
distsDir = /home/ntrrgc/myProject/build/distributions
jar.destinationDir = /home/ntrrgc/myProject/build/libs
Why does jar.destinationDir not respect its documented default?

I think, #Alicia is right in pointing out that currently the documentation of the Gradle Jar plugin is providing wrong information in the default value for the File destinationDir:
File destinationDir
The directory where the archive is generated into.
Default with java plugin:
project.distsDir
where default of distsDir is 'build/distributions' as can be here.
In my opinion, it should be
File destinationDir
The directory where the archive is generated into.
Default with java plugin:
project.libsDir
where default of libsDir is 'build/libs' as can be seen here again.
I have opened Gradle issue #1086 for this. Let us see, what they answer.

Related

How to create a Zip file using gradle 2.3

I have my archive at location myProject/unzip and need to:
Zip the contents within the unzip folder and create a zip file with some name at any location within the project.
Using gradle 2.3.
Can anyone help me for this?
I am not sure what you are doing differently than the examples in the documentation from the link I gave in the comments. But this works for me with Gradle 2.3:
task myZip(type: Zip){
from "$projectDir/unzip"
archiveName = "my-zip.zip"
destinationDir = buildDir
}
The input folder is called unzip and needs to present as a child in the project folder. It outputs a file my-zip.zip in the build folder.
Be sure that there actually are some resources located in the from path, or Gradle might skip it.

Gradle Plugin output name

How could I set output name when Gradle builds custom plugin artifact?
I mean when I create a custom plugin and build it Gradle puts plugin-name-1.0.0.jar into build/libs folder.
By default it gets final .jar name from the project folder name.
But I'd like to set it a custom name.
Thanks.
try this :
jar {
baseName = 'custom-name'
}
You will get custom-name-1.0.0.jar

How do I copy a file into my WAR based on profile?

I’m using Gradle 2.7 on Mac Yosemite. I have the following files:
src/main/environment/dev/context.xml
src/main/environment/qa/context.xml
src/main/environment/prod/context.xml
What I would like is if I run a build gradle -Pqa build, the appropriate context.xml file above is copied into my WAR (into the WEB-INF/classes directory is fine). How do I set this up with gradle?
There're many ways of solving the problem. You can configure sourceSets, or include or exclude particular resources when building war file. You can also have single context.xml and perform resource filtering with ReplaceTokens filter.
I've chosen sourceSets:
apply plugin: 'war'
ext.env = project.hasProperty('env') ? project.env : 'dev'
sourceSets {
main {
resources {
srcDir "src/main/environment/$env"
}
}
}
The trick is to include/process only the env being passed. If no env is passed dev will be picked for further processing. Have a look a the demo.
You would have to do that using the environment variable. Have the system properties in a file. Read them in the build.gradle and based on it include the context.xml into the war.

How do I prevent Gradle from building a non-project directory?

In the Gradle samples (included with version 2.2.1) there is a java/multiproject project.
The settings.gradle file defines the following projects:
include "shared", "api", "services:webservice", "services:shared"
Note that services is not itself a project, merely a directory which contains the webservice and shared projects.
When I run the command gradle build from the root directory, I notice that after gradle successfully builds it creates inside the /services directory a /build directory containing /lib and a /tmp directories.
Inside of /services/build/lib is a jar: services-1.0.jar which contains very little; specifically just a META-INF/MANIFEST.MF file containing:
Manifest-Version: 1.0
provider: gradle
So what is causing Gradle to build a jar for this non-project? And how can I prevent this behavior in my similarly structured multiproject project?
/services isn't a project, I don't want to create anything inside /build folder at all. Yes I could just delete it, but I would like to avoid the unnecessary work of building this jar/running any tasks on this non-project in the first place.
To be honest I've no reasonable idea why gradle builds this folder. I guess that because it's a kind of a transient folder. However it can be excluded by adding the following piece of code to main build.gradle script:
project(':services').jar { onlyIf { false } }
Desired effect (services.jar elimination) can be also obtained with the following settings.gradle content:
include "shared", "api", "services/webservice", "services/shared"
File instead of project paths are included.
My guess would be that this is a combination of the next 2 gradle rules:
When you're including subprojects in the build.settings file using the include keyword according to Gradle Documentation here:
the inclusion of the path 'services:hotels:api' will result in
creating 3 projects: 'services', 'services:hotels' and
'services:hotels:api'.
In simple words, this means that the inclusion of services::webservice will also build the services project
The bulid.gradle file in your root that applies the 'java' plugin. According to Gradle Documentation here every configuration defined in the root.gradle takes effect for all sub projects. This means that it will also hold as the default configuration for the services project. As the 'java' plugin was applied a jar will be created, but as there is no src/main folder under the services directory nothing will be compiled and the jar will include only a META-INF/MANIFEST.MF file.

Gradle - Add folder to Eclipse classpath

I am migrating a legacy application from Ant to Gradle. The requirement is to build a zip file with a certain folder structure which is used by the deployment team. I am able to create the zip file in the correct format, so-far-so-good.
I am able to open the project in Eclipse, but cannot run it. In Eclipse (and IntelliJ) I need src/main/conf to be added to Eclipse's classpath, but not be included in the JAR (e.g. if I were to run gradle jar).
This is how the project is currently structured:
src
/main
/java
/com
/example
/App.java
/resources
/applicationConfiguration.xml
/conf
/dev.properties
/staging.properties
/prod.properties
How can I add the conf folder to Eclipse's classpath so that it is not included in the JAR that Gradle creates?
Given the limitations of Gradle's EclipseClasspath API, the most straightforward solution I can think of is to declare src/main/conf as another source directory:
sourceSets.main.java.srcDir "src/main/conf"
As long as the directory doesn't contain any Java files, this won't affect the outcome of the Gradle build. However, the directory will show up as a source directory in Eclipse, and its properties files will therefore be copied into the Eclipse output directory.
Another tip. If you need it to run in Eclipse WTP, then I set the sourceDirs property of eclipse.wtp.component:
eclipse {
project {
natures 'org.eclipse.wst.common.project.facet.core.nature',
'org.eclipse.wst.common.modulecore.ModuleCoreNature',
'org.eclipse.wst.jsdt.core.jsNature'
name 'blah-blah'
}
wtp {
facet {
facet type: 'fixed', name: 'wst.jsdt.web'
facet name: 'java', version: '1.7'
facet name: 'jst.web', version: '3.0'
facet name: 'wst.jsdt.web', version: '1.0'
}
component {
sourceDirs = new HashSet([
new File(project.getProjectDir().getAbsolutePath() + "/src/main/java"),
new File(project.getProjectDir().getAbsolutePath() + "/src/main/resources"),
new File(project.getProjectDir().getAbsolutePath() + "/src/main/conf")
])
}
}

Resources