How can I publish many dependant subprojects in a certain order with gradle? - gradle

I'm trying to publish two subprojects with gradle. I have two subprojects: SubprojectA is dependant on SubprojectB. I want to publish them both using maven-publish. I have this in build.gradle:
plugins {
id 'java'
id 'maven-publish'
}
publishing {
publications {
SubprojectA(MavenPublication) {
println(project(':subprojectA').tasks)
groupId group
artifactId 'subjprojectA'
version version
artifact project(':subprojectA').tasks.getByName('jar')
}
SubprojectB(MavenPublication) {
groupId group
artifactId 'subjprojectB'
version version
artifact project(':subjprojectB').tasks.getByName('jar')
}
}
repositories {
maven {
url "http://some-url"
}
}
}
Gradle tries to publish them in alphabetical order: Since subprojectA depends on subprojectB, it doesn't work because subprojectB hasn't been published yet. If I rename subprojectA to ZSubprojectA, like this:
ZSubprojectA(MavenPublication) {
println(project(':subprojectA').tasks)
groupId group
artifactId 'subprojectA'
version version
artifact project(':subprojectA').tasks.getByName('jar')
}
then it works, but I don't like this solution. I've tried something like this:
project(':subprojectA') {
publish.dependsOn(":subprojectB:build")
}
but it doesn't work, and :subprojectB:publish doesn't exist.

I've been able to solve it. This was the problem:
Both subprojects had their respective build.gradle files. In subprojectA's build.gradle there was something like this:
plugins {
id 'java'
}
sourceCompatibility = 1.8
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
implementation group: 'com.neovisionaries', name: 'nv-i18n', version: '1.22'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.1'
implementation group: 'com.myorg.something', name: 'subprojectB', version: '1.0.0-SNAPSHOT'
}
Therefore it was trying to get subprojectB from my organization private repository, and I should have done something like this:
compile project(":subprojectB")
I should have include both build.gradle files in my question. But the problem is solved.

Related

Groovy compilation fails: Unable to load class 'org.grails.io.support.Resource'

I'm developing a JavaFX application written in Groovy and using Gradle. When I started up my application in IntelliJ recently, it seemingly from out of the blue started failing to compile with the error:
Unable to load class 'org.grails.io.support.Resource'.
This is an unexpected error. Please file a bug containing the idea.log file.
This is from running the "run" gradle task.
This is my build file:
plugins {
id 'groovy'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.7'
}
group 'redacted'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
maven { url "https://m2proxy.atlassian.com/repository/public" } // Atlassian repository
maven { url "https://maven.atlassian.com/content/repositories/atlassian-public/"} // Atlassian public
maven { url "https://download.java.net/maven/2/"}
}
dependencies {
implementation 'org.codehaus.groovy:groovy-all:3.0.5'
// Logback log-annotation
implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.6'
// https://mvnrepository.com/artifact/org.controlsfx/controlsfx
implementation group: 'org.controlsfx', name: 'controlsfx', version: '11.1.0'
testImplementation 'org.spockframework:spock-core:2.0-groovy-3.0'
// ---- GPars concurrency lib ----
// https://mvnrepository.com/artifact/org.codehaus.gpars/gpars
implementation group: 'org.codehaus.gpars', name: 'gpars', version: '1.2.1'
// ---- Jira Client ----
// https://mvnrepository.com/artifact/com.atlassian.jira/jira-rest-java-client-app
implementation group: 'com.atlassian.jira', name: 'jira-rest-java-client-app', version: '5.2.0'
// https://mvnrepository.com/artifact/com.atlassian.jira/jira-rest-java-client-api
implementation group: 'com.atlassian.jira', name: 'jira-rest-java-client-api', version: '5.2.0'
// ---- Misc ----
// https://mvnrepository.com/artifact/io.github.cdimascio/java-dotenv
implementation group: 'io.github.cdimascio', name: 'java-dotenv', version: '5.2.2'
// https://mvnrepository.com/artifact/org.jsoup/jsoup
implementation group: 'org.jsoup', name: 'jsoup', version: '1.14.3'
// ---- REST ----
// https://mvnrepository.com/artifact/org.springframework/spring-web
implementation group: 'org.springframework', name: 'spring-web', version: '3.0.2.RELEASE'
// https://mvnrepository.com/artifact/org.grails/grails-datastore-rest-client
implementation group: 'org.grails', name: 'grails-datastore-rest-client', version: '6.1.9.RELEASE'
// https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api
implementation group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
// https://mvnrepository.com/artifact/net.dongliu/requests
implementation group: 'net.dongliu', name: 'requests', version: '5.0.8'
// https://mvnrepository.com/artifact/io.jsondb/jsondb-core
implementation group: 'io.jsondb', name: 'jsondb-core', version: '1.0.115-j11'
}
test {
useJUnitPlatform()
}
javafx {
modules = ['javafx.controls', 'javafx.fxml']
version = '11.0.2'
}
mainClassName = 'redacted'
Has anyone seen this before? The things I've tried:
Invalidating caches in IntelliJ
Clean + Rebuild
Rollback code to a point I know compiled.
Update gradlew to use gradle 7.4
UPDATE
I seem to have found the culprit. My company has recently changed stuff related to how we build our projects, which requires using a init.gradle file in the .gradle/ folder, which contains some standard repository definitions. This is the content (with company repositories redacted):
allprojects {
apply plugin: 'java'
apply plugin: 'maven-publish'
buildscript {
repositories {
maven {
url "https://<redacted>"
credentials {
username mavenUser
password mavenPassword
}
}
}
}
repositories {
mavenLocal()
maven {
url "https://<redacted>"
credentials {
username mavenUser
password mavenPassword
}
}
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
repositories {
maven {
credentials {
username mavenUser
password mavenPassword
}
url "https://<redacted>"
}
}
}
}
Removing it fixed the problem for the project in question, but will obviously not work for all the other work related projects. So the question remains...how does this cause such an error?
UPDATE 2
I have not exactly found the source of the error, but it seems to have something to do with the repositories being declared in a wrong way. To fix this, one can call clear() in the project build.gradle file at the top of the repositories definition, effectively ignoring what's declared in init.gradle. So, just update the repositories {} clause to:
repositories {
clear() // This is needed in order for init.gradle to not cause errors
mavenCentral()
maven { url "https://m2proxy.atlassian.com/repository/public" } // Atlassian repository
maven { url "https://maven.atlassian.com/content/repositories/atlassian-public/"} // Atlassian public
maven { url "https://download.java.net/maven/2/"}
}
I have not exactly found the source of the error, but it seems to have something to do with the repositories being declared in a wrong way. To fix this, one can call clear() in the project build.gradle file at the top of the repositories definition, effectively ignoring what's declared in init.gradle. So, just update the repositories closure to:
repositories {
clear() // This is needed in order for init.gradle to not cause errors
mavenCentral()
maven { url "https://m2proxy.atlassian.com/repository/public" } // Atlassian repository
maven { url "https://maven.atlassian.com/content/repositories/atlassian-public/"} // Atlassian public
maven { url "https://download.java.net/maven/2/"}
}

Gradle dependency resolution issue

I am converting a project from Maven to Gradle.
Here is my gradle.build file
plugins {
id 'java'
id 'maven-publish'
id "org.jetbrains.kotlin.jvm" version "1.5.30"
id "org.jetbrains.kotlin.plugin.spring" version "1.5.30"
id 'org.springframework.boot' version "2.5.4"
id 'io.spring.dependency-management' version "1.0.11.RELEASE"
}
group = 'com.aeonai.lib'
version = '1.0.0'
description = 'Aeon AI Library'
java.sourceCompatibility = JavaVersion.VERSION_1_8
repositories {
mavenCentral()
maven {
url = uri 'https://repo.osgeo.org/repository/release/'
}
maven {
url = uri 'https://repo.maven.apache.org/maven2/'
}
}
dependencies {
...
implementation 'org.geotools:gt-cql:25.2:sources#jar'
implementation 'org.geotools:gt-epsg-hsql:25.2:sources#jar'
implementation 'org.geotools:gt-geojson:25.2:sources#jar'
implementation 'org.geotools:gt-main:25.2:sources#jar'
implementation 'org.geotools:gt-opengis:25.2:sources#jar'
implementation 'org.geotools:gt-shapefile:25.2:sources#jar'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
...
}
configurations {
all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
bootRun.enabled = false
bootJar {
mainClass.set('NONE')
}
publishing {
publications {
maven(MavenPublication) {
from(components.java)
}
}
}
test {
useJUnitPlatform()
}
I am importing many of the geotools from https://repo.osgeo.org/repository/release/.
When I run gradle build all of my dependency show up as they should, but the build still fails. The compiler cannot find some of the dependencies (which I have added in a screenshot below), although I can see the files in the External Libraries tree (also in a screenshot below). I can also see the libraries in the ~/.gradle/caches.
Here is a screenshot of the files not being found.
Here is another screenshot of the files in the tree.
Why is gradle/compiler not recognizing the file is there? What else am I missing?

Gradle war plugin pulls in javadoc and sources

I have a strange problem. I have a project which creates a war file with some custom inclusions like images etc. So far it looks good. The only problem left is that gradle pulls in source jars/zips and javadoc jars/zip into my WEB-INF/lib/ folder of my war.
I thought it might be a problem with Idea but same results with the command line. I guess it has something to do with the dependency configuration?
I use compile and runtime scopes and my artifacts are resolved from Artifactory.
Can anyone point me to a direction where to fix that?
Update:
When i create a task:
task copyAllDependencies(type: Copy) {
from configurations.runtime
into 'allRuntime'
}
or
task copyAllDependencies(type: Copy) {
from configurations.compile
into 'allCompile'
}
I'll get the sources as well. So it seems that it has something to do with the compile/runtime configuration. They're pulling the sources and javadoc. But why?!
Dependencies are declared like this:
dependencies {
compile group: 'org.drools', name: 'drools-core', version: DROOLS_VERSION
compile group: 'org.drools', name: 'drools-compiler', version: DROOLS_VERSION
...
runtime group: 'net.sourceforge.barbecue', name: 'barbecue', version: '1.5-beta1', ext: 'jar'
...
testCompile group: 'org.fitnesse', name: 'fitnesse', version: '20130531'
...
}
Here's another attempt... a bit hacky but might work
configurations {
tempCompile
tempRuntime
tempTestCompile
}
dependencies {
tempCompile "org.drools:drools-core:${DROOLS_VERSION}"
tempRuntime "net.sourceforge.barbecue:barbecue:1.5-beta1#jar"
tempTestCompile "org.fitnesse:fitnesse:20130531"
...
compile configurations.tempCompile.asFileTree.matching {
exclude '**/*-sources.jar'
exclude '**/*-javadoc.jar'
}
runtime configurations.tempRuntime.asFileTree.matching {
exclude '**/*-sources.jar'
exclude '**/*-javadoc.jar'
}
testCompile configurations.tempTestCompile.asFileTree.matching {
exclude '**/*-sources.jar'
exclude '**/*-javadoc.jar'
}
}
As we discovered in the comments, your dependencies are bringing in javadoc and sources as transitive dependencies. You can possibly exclude these by
configurations.all { Configuration config ->
['com.group1', 'com.group2', ..., 'com.groupN'].each { groupId ->
config.exclude [group: groupId, classifier: 'javadoc']
config.exclude [group: groupId, classifier: 'sources']
}
}
Note: I'm not an ivy user so the selector (classifier: 'javadoc' etc) may need tweaking

Can there be multiple war tasks in build.gradle to generate multiple wars with different dependencies

I am trying to do similar thing as: Create multiple .WAR files with different dependencies in Gradle
But the solution given in this post is not working. I am using gradle 2.5 to achieve this.
Expectation is to generate 3 different wars as output of the script. I created a simplest project with minimal dependencies. When i execute build.gradle, it just gives me single war named: Test-1.0.war. Test is name of the sample project i created.
Here is build.gradle:
apply plugin: 'java'
apply plugin: 'war'
sourceCompatibility = 1.5
version = '1.0'
task createStandardWar(type: War, dependsOn: classes) {
baseName = 'standard'
destinationDir = file("$buildDir/libs")
classifier = 'Functional'
}
task createStandardWarQasOnly(type: War, dependsOn: classes) {
baseName = 'standard-qas-only'
destinationDir = file("$buildDir/libs")
classifier = 'Functional2'
}
task createStandardWarQasAndLog4J(type: War, dependsOn: classes) {
baseName = 'standard-qas-log4j'
destinationDir = file("$buildDir/libs")
classifier = 'Functional3'
}
task createDists(dependsOn: [createStandardWar, createStandardWarQasOnly, createStandardWarQasAndLog4J])
repositories {
mavenCentral()
}
dependencies {
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
test {
systemProperties 'property': 'value'
}

Spring-Boot html in /templates don't render from command line

I have read several online posts about this issue, but for some reason none of those helped me solve this. I looked at the spring-boot examples and I don't think I am doing much different than those.
I am using Spring-boot 1.2.1, Thymeleaf, embedded tomcat without issue in IntelliJ. However, when I do a "gradle clean build", move the jar file, and an application.properties file to a deploy directory. I then start on the command with:
java -jar edm-0.1.0.jar
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/loginPage", template might not exist or might not be accessible by any of the configured Template Resolvers
at org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:245)
I am letting spring-boot configure my site for the most part. I am using the recommended directory structure:
I can hit the index page, and the REST calls seem to work just fine.
UPDATE based upon feedback:
I don't know if this is a broken jar issue, but when I extract it the structure and files appear correct. I can run "gradle bootRun" from the top of my project structure just fine. But if I deploy the jar file and run it, I get an error:
Task 'bootRun' not found in root project 'edm'
Here is my build.gradle file in case there might be an issue in it:
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'jacoco'
apply plugin: 'maven'
idea {
project {
//if you want to set specific jdk and language level
jdkName = '1.8'
languageLevel = '1.8'
}
}
jacoco {
toolVersion = "0.7.0.201403182114"
}
project.ext {
springBootVersion = '1.2.1.RELEASE'
}
configurations {
querydslapt
}
buildscript {
repositories {
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
maven { url "http://repo.spring.io/libs-milestone" }
maven { url "http://repo.spring.io/libs-snapshot" }
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion")
}
}
jar {
baseName = 'edm'
version = '0.1.0'
}
dependencies {
querydslapt group: 'com.mysema.querydsl', name: 'querydsl-jpa', version: '2.8.0', classifier: 'apt-one-jar', transitive: false
compile("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion")
compile("org.springframework.security:spring-security-web:4.0.0.M1")
compile("org.springframework.security:spring-security-config:4.0.0.M1")
compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity3:2.1.1.RELEASE')
compile('com.android.tools.build:gradle:1.0.1')
compile("org.hibernate:hibernate-core:4.3.4.Final")
compile("org.hibernate:hibernate-entitymanager:4.3.4.Final")
compile("org.hibernate:hibernate-validator")
compile("org.apache.velocity:velocity:1.7")
compile('javax.mail:mail:1.4.1')
compile("org.springframework:spring-context-support")
compile("com.h2database:h2:1.3.172")
compile("joda-time:joda-time:2.3")
compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.5.0")
compile("org.codehaus.groovy.modules.http-builder:http-builder:0.7.1")
compile('org.codehaus.groovy:groovy-all:2.2.1')
compile('org.jadira.usertype:usertype.jodatime:2.0.1')
compile("postgresql:postgresql:9.1-901.jdbc4")
testCompile('org.spockframework:spock-core:1.0-groovy-2.0-SNAPSHOT') {
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
}
testCompile('org.spockframework:spock-spring:1.0-groovy-2.0-SNAPSHOT') {
exclude group: 'org.spockframework', module: 'spock-core'
exclude group: 'org.spockframework', module: 'spring-beans'
exclude group: 'org.spockframework', module: 'spring-test'
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
}
testCompile("org.springframework.boot:spring-boot-starter-test:$springBootVersion")
testCompile('org.codehaus.groovy.modules.http-builder:http-builder:0.7+')
testCompile("junit:junit")
// for the anontation processor
querydslapt group: 'com.mysema.querydsl', name: 'querydsl-jpa', version: '2.8.0', classifier: 'apt-one-jar', transitive: false
// for compiling
compile("com.mysema.querydsl:querydsl-jpa:3.3.3")
compile("com.mysema.querydsl:querydsl-apt:3.3.3")
}
task wrapper(type: Wrapper) {
gradleVersion = '2.0'
}
project.configurations {
providedRuntime
}
project.bootRepackage {
enabled = true
}
I also tried adding some thymeleaf configuration (even though I am not explicitly using Thymeleaf) to my application.properties file:
liquibase.changeLog=classpath:/db/changelog/db.changelog-master.xml
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.check-template-location=true
So I guess my question is, why does running the "java -jar" not let me view the webpages?
It turns out that my REST controllers were proceeded by "/" so login page became "//loginPage" and that was causing the problem. I found the answer here but it took me a while to realize that was the issue. Hopefully this answer will help out someone in the future as it as a bear to figure out.

Resources