I need some help understanding why my build.gradle does not copy locally referred jar into its cache. On Windows, I expected to see jars in C:\Users\myusername .gradle and indeed other JARs are there.
I can't import this JAR in IntelliJ as it does not find it.
Side question: did anybody figure out how to debug Gradle's DSL? I set up remote debugging and IntelliJ never hits my breakpoint. It does not the have the checkbox on it so I guess IDE does not think it is code.
Few things are not making sense to me:
1. gradle dependencies --configuration compile
\--- com.google.guava:guava:23.5-jre
+--- com.google.code.findbugs:jsr305:1.3.9
....
MY_JAR_1.0.1.jar is not present.
2. gradle copyDependencies - this task finds and copies it.
task copyDependencies(type: Copy) {
from configurations.compile
into 'dependencies'
}
3. This task also finds my jar.
task listcompile << {
configurations.compile.each { File file -> println file.name }
}
Why does #1 not find it?
apply plugin: 'java'
repositories {
mavenCentral()
//flatDir {
// dirs 'customlibs'
//}
}
dependencies {
compile group: 'com.google.guava', name: 'guava', version: '23.5-jre'
compile files('customlibs/MY_JAR_1.0.1.jar')
}
task listcompile << {
configurations.compile.each { File file -> println file.name }
}
// copy all dependencies into this folder
task copyDependencies(type: Copy) {
from configurations.compile
into 'dependencies'
}
It seems that Gradle's dependencies task will only display modules that have a defined group:name:version coordinate. You are adding a file directly, with no associated identifier.
What you can do instead is add a flat directory repository and declare your custom JAR as a normal dependency, like so:
repositories {
flatDir {
dirs 'customlibs'
}
}
dependencies {
compile ':MY_JAR:1.0.1'
}
You will need to rename the JAR so that it matches the naming convention for Maven/Gradle, i.e. MY_NAME-1.0.1.jar (replacing the last underscore with a hyphen).
Related
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?
How can I mention subproject should build before root project.
in settings.gradle
rootProject.name = 'loginmodule'
include 'servicebundle'
include 'webbundle'
include 'webredirectbundle'
When I try this build dependson subprojects:build it is giving error like circular dependency.
Currently in my root project build.gradle is bundling all subprojects like below
task createESA(type: Zip, dependsOn: generateSubSystemFile) {
subprojects.each { dependsOn("${it.name}:build") }
from subprojects.collect { "${it.buildDir}/libs" }
from (subsystemFile) {
into 'OSGI-INF'
}
from ('resources/OSGI-INF') {
into 'OSGI-INF'
}
baseName project.name
extension 'esa'
}
build.finalizedBy createESA
I am using gradle clean build to build the project.
Is there any better way to do that ?? I just want to build all subprojects first before root project build.
Have your createESA task depend on subprojects*.build, it'll say that task can't run until all of the build tasks in all of the subprojects have run. Then, declare that the root project's build task depends on createESA.
task createESA(type: Zip, dependsOn: subprojects*.build) {
// etc...
}
build.dependsOn createESA
"refresh all gradle projects" in Intellij Idea gives me following error:
Error:(15, 0) Cannot change dependencies of configuration ':util:compile' after it has been included in dependency resolution.
The problem doesn't occur when I move second if statement to build.gradle of submodule project. While I found workaround I would like to understand why original solution is not correct. The line making trouble is:
"Class-Path": (configurations.compile.collect {"$dependencyDir/$it.name"}.join(" "))
Project structure:
mcv-gradle-example
|__ submodule (gradle project)
|__ util (gradle project)
|__ build.gradle
build.gradle:
allprojects {
apply plugin: 'java'
}
subprojects {
apply plugin: 'scala'
repositories {
mavenCentral()
}
def isSpecialProject = project.name in ["submodule"]
dependencies {
compile group: 'org.scala-lang', name: 'scala-library', version: '2.12.1'
if (isSpecialProject) {
compile project(':util')
}
}
if (isSpecialProject) {
def dependencyDir = "/deps"
task setupJarManifest() {
jar.manifest.attributes(
"Class-Path": (configurations.compile.collect {"$dependencyDir/$it.name"}.join(" ")))
}
jar.dependsOn setupJarManifest
}
}
Update:
I found out that embracing jar.manifest... with afterEvaluate allows having this task in main build.gradle. However I'm still not sure what was the gradle's problem.
Update 2:
It seems moving setting manifest.attributes to the execution phase solves he problem. My final solution is:
if (isSpecialProject) {
def dependencyDir = "deps"
jar {
doFirst {
manifest.attributes(
"Class-Path": (configurations.compile.collect {"$dependencyDir/$it.name"}.join(" "))
)
}
}
}
My guess is:
When submodule project uses configurations.compile in configuration phase, it's all dependencies are resolved. Then the subprojects closure is evaluated for util project. Since util is dependency of submodule it can't have new dependency added as one moment ago we used it's all dependencies. It's reasonable but still I don't know how usage of configurations.compile "marks" util's dependencies as closed.
Explanation
After some more research I finally know what happened:
Subproject submodule is evaluated first. It puts scala and subproject util into its dependencies.
Then gradle evaluates configurations.compile.collect which internally calls iterator method calling DefaultConfiguration#getFiles. To find what files are specified for this configurations it resolves graph and artifacts (locking it's dependencies modification abilities).
Then subprojects closure is evaluated for subproject util. It is trying to put scala in its dependencies but is locked because of point 2 so it throws an error.
Moving collect to afterEvaluation or doLast executes it after correct resolution of graph and artifacts. It can be called as many times as you want in execution phase.
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 can I add an external library in gradle? My build.gradle contains:
buildscript {
repositories {
mavenCentral()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:1.1-SNAPSHOT'
}
}
My root folder is /FORGE/. I want to add /FORGE/build/libs/spigot.jar as a dependency.
As explained in the documentation:
dependencies {
compile files('libs/spigot.jar')
}
The above will add the libs/spigot.jar file to the compile configuration. You can of course add it to any other configuration (runtime, etc.).
Note that using build/libs is an extremely bad idea, since the whole build directory will be deleted as soon as you execute gradle clean. The build directory is used to store artifacts generated by the build.