gradle war: how to force inclusion of transitively provided dep? - gradle

Having this build.gradle:
apply plugin: 'war'
repositories {
mavenCentral()
maven { url "http://repository.jboss.org/nexus/content/groups/public" }
}
configurations {
providedCompile {
exclude module: 'commons-httpclient' // here it doesn't work
}
}
dependencies {
compile 'commons-httpclient:commons-httpclient:3.1'
providedCompile ('org.jboss.resteasy:resteasy-jaxrs:2.3.3.Final') {
//exclude module: 'commons-httpclient' // here it works
}
}
I expect to have this war:
WEB-INF/
WEB-INF/lib/
WEB-INF/lib/commons-httpclient-3.1.jar
but only have this:
WEB-INF/
If I un-comment 2nd exclude and comment 1st exclude, it works as needed.
If this is expected behavior, how can I otherwise globally exclude a particular transitive from provided libs?

It turns out that this is the "right" thing to happen, as compile actually extends from providedCompile:
apply plugin: 'war'
configurations.compile.extendsFrom.each {
println "$it"
}
So, my solution was the following:
apply plugin: 'war'
repositories {
mavenCentral()
maven { url "http://repository.jboss.org/nexus/content/groups/public" }
}
configurations {
forceInclude {}
}
dependencies {
providedCompile 'org.jboss.resteasy:resteasy-jaxrs:2.3.3.Final'
forceInclude 'commons-httpclient:commons-httpclient:3.1'
}
war {
classpath += configurations.forceInclude
}

Related

Gradle doesn't copy html files into executed jar

build.gradle
buildscript {
ext {
springBootVersion = '2.0.6.RELEASE'
springRestDocsVersion = '2.0.2.RELEASE'
gradleDockerVersion = '1.2'
asciidoctorGradlePluginVersion = '1.5.9.2'
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("org.asciidoctor:asciidoctor-gradle-plugin:${asciidoctorGradlePluginVersion}")
classpath("se.transmode.gradle:gradle-docker:${gradleDockerVersion}")
}
}
plugins {
id "org.springframework.boot" version "2.0.6.RELEASE"
id "org.asciidoctor.convert" version "1.5.9.2"
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'maven'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'org.asciidoctor.convert'
apply plugin: 'application'
apply plugin: 'docker'
apply from: 'local.gradle'
mainClassName = 'class.path.package.BootApplication'
version = '0.0.3a'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
// Standard spring boot packages
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.cloud:spring-cloud-starter-config')
compile('org.springframework.boot:spring-boot-starter-jersey')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-validation')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')
compile('org.postgresql:postgresql')
compile('biz.paluch.redis:lettuce:4.4.6.Final')
compile('org.pacesys:openstack4j-core:3.1.0')
compile('org.pacesys.openstack4j.connectors:openstack4j-httpclient:3.1.0')
// Dozer object mapping
compile('net.sf.dozer:dozer:5.5.1')
// Sengrid library
compile('com.sendgrid:sendgrid-java:4.2.1')
compile('org.freemarker:freemarker:2.3.28')
// Cloudant
compile('com.cloudant:cloudant-client:2.9.0')
compile('com.squareup.okhttp3:okhttp-urlconnection:3.4.2')
compile('org.json:json:20171018')
compile('javax.validation:validation-api:2.0.1.Final')
//Swagger2
compile('io.springfox:springfox-swagger2:2.9.2')
compile('io.springfox:springfox-swagger-ui:2.9.2')
runtime('org.springframework.boot:spring-boot-devtools')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.springframework.security:spring-security-test')
testCompile("org.springframework.restdocs:spring-restdocs-mockmvc")
testCompile("org.asciidoctor:asciidoctor-gradle-plugin:1.5.9.2")
asciidoctor('org.springframework.restdocs:spring-restdocs-asciidoctor:2.0.2.RELEASE')
}
processResources {
// expand(project.properties)
}
ext {
springCloudVersion = 'Finchley.RELEASE'
snippetsDir = file('build/generated-snippets')
// springRestDocsVersion = '2.0.2.RELEASE'
}
ext['spring-restdocs.version'] = '${springRestDocsVersion}'
test {
outputs.dir snippetsDir
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
}
}
asciidoctor {
// attributes "snippets": snippetsDir
inputs.dir snippetsDir
dependsOn test
}
jar {
dependsOn asciidoctor
from ('${asciidoctor.outputDir}/html5') {
into 'static/apidocs'
}
}
my problem actually in this part:
jar {
dependsOn asciidoctor
from ('${asciidoctor.outputDir}/html5') {
into 'static/apidocs'
}
}
executed jar doesn't copy index.html file executed from asciidoctor into jar and jar executed only without this file
So how i can copy build/asciidoc/html5/index.html from build
folder into executed jar?
Also if i need to use bootJar task so how i can make it include all jar needed into /BOOT-INF/lib/
Your configuration is almost right, but you are customising the wrong task. A Spring Boot fat jar is built with the bootJar task rather than the jar task.
You need to replace jar with bootJar in your build.gradle. This will result in it looking the same as the following example:
bootJar {
dependsOn asciidoctor
from ("${asciidoctor.outputDir}/html5") {
into 'static/docs'
}
}
This is the configuration that's described in the REST Docs documentation.

Gradle Multimodule Project unable to resolve class of depending sub module

The application works fine in Eclipse. But I am not able to build the application via gradle (gradle clean build)
The structure is like:
financial-calculator (parent)
library
api
api wants to use classes of library
My parent's settings.gradle file:
rootProject.name = 'financial-calculator'
include 'library'
include 'api'
rootProject.children.each { it.name = rootProject.name + '-' + it.name }
The parent build.gradle file:
buildscript {
ext {
springBootVersion = '2.0.3.RELEASE'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "o.s.b:spring-boot-gradle-plugin:${springBootVersion}"
}
}
allprojects {
apply plugin: 'eclipse'
apply plugin: 'maven'
apply plugin: 'maven-publish'
group = 'net.hemisoft.financial.calculator'
version = "0.1.0-SNAPSHOT"
}
subprojects {
apply plugin: 'groovy'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
sourceCompatibility = JavaVersion.VERSION_1_8
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile 'o.c.g:groovy'
testCompile 'o.s.b:spring-boot-starter-test'
}
dependencyManagement {
imports { mavenBom("o.s.b:spring-boot-dependencies:${springBootVersion}") }
}
}
project(rootProject.name + '-library') {
dependencies {
compile 'o.s.b:spring-boot-starter'
}
}
project(rootProject.name + '-api') {
dependencies {
compile project (':' + rootProject.name + '-library')
compile 'o.s.b:spring-boot-starter-web'
}
}
The complete small project you will find under link
Thanks for your hints.

Sibling project seems not using it's dependency's build.gradle script

I have multi-module project with a structure like this:
|fullstack
\backend
|build.gradle
\frontend
|build.gradle
|build.gradle
|settings.gradle
Settings.gradle:
rootProject.name = 'fullstack'
include 'backend'
include 'frontend'
backend depends on ktor, so it's build.gradle contains repository:
maven { url "https://dl.bintray.com/kotlin/ktor" }
And backend module builds well.
Then I want to share some common classes between backend and frontend. I could make third module api and make others depend on it. But now I want to avoid third module and just make frontend to depend on backend.
I added the dependency to the frontend's gradle.build:
compile project (':backend')
and tried to build the whole project, but got an error:
Could not resolve all files for configuration
':frontend:compileClasspath'.
Could not find io.ktor:ktor-server-netty:0.9.1. Searched in the following locations:
https://repo.maven.apache.org/maven2/io/ktor/ktor-server-netty/0.9.1/ktor-server-netty-0.9.1.pom
https://repo.maven.apache.org/maven2/io/ktor/ktor-server-netty/0.9.1/ktor-server-netty-0.9.1.jar
Required by:
project :frontend > project :backend
It obviously didn't scan repositories of backend module. Why?
UPDATE
I've added repositories as said in answers. But when I try to import in frontend/main.kt any class from backend I get:
:frontend:compileKotlin2Jse: D:\...\frontend\src\main\kotlin\main.kt: (1, 8): Unresolved reference: com
e: D:\...\frontend\src\main\kotlin\main.kt: (2, 8): Unresolved reference: com
How to make it visible for frontend?
Root build.gradle:
group 'com.norg.parts'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_ver = '1.2.50'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_ver"
}
}
allprojects {
project.ext {
kotlin_version = kotlin_ver
ktor_version = '0.9.1'
}
repositories {
jcenter()
mavenCentral()
maven { url 'https://dl.bintray.com/kotlin/ktor' }
maven { url 'https://dl.bintray.com/kotlin/kotlinx' }
maven { url 'https://mvnrepository.com/artifac/' }
maven { url "https://dl.bintray.com/kotlin/exposed" }
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
sourceCompatibility = 1.8
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
jar {
manifest {
attributes 'Main-Class': 'com.norg.parts.MainKt'
}
//TODO include jar from frontend!
}
The problem is that there can be 2 dependencies / repositories blocks. The first one is in the buildscript which looks like this:
buildscript {
repositories {
jcenter()
mavenCentral()
maven { url "https://dl.bintray.com/kotlin/ktor" }
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
}
This is responsible for setting up tooling and plugins. Then when you set up the config of your project itself you can do several things. If you don't have a multi-module project you just dump it into your build.gradle then the file looks like this:
buildscript {
repositories {
jcenter()
mavenCentral()
maven { url "https://dl.bintray.com/kotlin/ktor" }
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
}
repositories {
jcenter()
mavenCentral()
maven { url "https://dl.bintray.com/kotlin/ktor" }
}
dependencies {
compile "io.ktor:ktor-server-core:$ktor_version"
}
In your case you should use either allprojects which means that all configuration which you put in that block will be applied to all your projects (including root), or subprojects. In the latter case, the block will be applied to only your subprojects (root not included). This looks like this:
buildscript {
repositories {
jcenter()
mavenCentral()
maven { url "https://dl.bintray.com/kotlin/ktor" }
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
}
subprojects {
repositories {
jcenter()
mavenCentral()
maven { url "https://dl.bintray.com/kotlin/ktor" }
}
dependencies {
compile "io.ktor:ktor-server-core:$ktor_version"
}
}
Your problem is that you did not add the repository itself to your project config, only your buildscript config.
If you are planning to mix frontend and backend code you can now use Kotlin Multiplatform Projects. I've written about this here.
Response to your edit:
You really need to move all this to a subprojects block:
subprojects {
apply plugin: 'java'
apply plugin: 'kotlin'
sourceCompatibility = 1.8
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
jar {
manifest {
attributes 'Main-Class': 'com.norg.parts.MainKt'
}
//TODO include jar from frontend!
}
}
and you also need to add the backend project as a dependency to your frontend project in that project's build.gradle. I'd strongly advise you to read the Gradle Documentation since this is a Gradle issue not a Kotlin issue whatsoever.
Dependencies are transitive, but repositories are not. This is why most projects have a allprojects block in the root build file defining the repositories for all subprojects at the same time.

gradle conflicting transitive dependency not being included

I have a dependency, my-project that uses two dependencies that use different versions of commons-lang3 but when I build my war artifact, commons-lang3 is not included in the artifact. What could be wrong?
My build.gradle looks like:
apply plugin: 'io.spring.dependency-management'
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'war'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'io.spring.gradle:dependency-management-plugin:0.3.0.RELEASE'
}
}
compileJava {
sourceCompatibility = 1.7
targetCompatibility = 1.7
}
configurations.all {
exclude group: 'commons-logging'
}
repositories {
jcenter()
maven {
credentials {
username = "${artifactory_user}"
password = "${artifactory_password}"
}
url "myrepo.com"
}
}
dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:1.1.2.RELEASE'
}
}
dependencies {
compile "my.project:my-project:1.0.0-SNAPSHOT"
// Spring Framework
compile 'org.springframework:spring-context'
compile 'org.springframework:spring-web'
compile 'org.springframework:spring-webmvc'
compile 'org.springframework.security:spring-security-config'
compile 'org.springframework.security:spring-security-web'
// Jackson
compile "com.fasterxml.jackson.core:jackson-annotations"
compile "com.fasterxml.jackson.core:jackson-core"
compile "com.fasterxml.jackson.core:jackson-databind"
// Logging
compile 'ch.qos.logback:logback-classic'
compile 'org.slf4j:slf4j-api'
runtime 'org.slf4j:jcl-over-slf4j'
runtime 'org.logback-extensions:logback-ext-loggly:0.1.2'
// Test
testCompile 'junit:junit'
testCompile 'org.mockito:mockito-core'
testCompile 'org.springframework:spring-test'
providedCompile 'javax.servlet:javax.servlet-api'
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.web
}
}
repositories {
maven {
credentials {
username = "${artifactory_user}"
password = "${artifactory_password}"
}
if(project.version.endsWith('-SNAPSHOT')) {
url "myrepo.com/libs-snapshot-local"
} else {
url "myrepo.com/libs-release-local"
}
}
}
}
task wrapper(type: Wrapper) {
gradleVersion = '2.4'
}
EDIT Dependency diagram of my.project:my-project
my-project is a library project that my co-worker wrote that is dependent on two other library projects that contain commons-lang3. An example diagram would be
my.project:my-project:1.0.0-SNAPSHOT
+---my.project:my-dependency-1:1.0.0
| +---org.apache.commons:commons-lang3:3.4
+---my.project:my-dependency-2:1.0.0
+---org.apache.commons:commons-lang3:3.3.2
I updated the spring gradle dependency-management-plugin to 0.5.2.RELEASE and that fixed my problem.

Cargo use installed container (Local "C:\tomcat) instead of AppData/Local/Temp

I want to use local tomcat container which is already installed in c:\tomcat instead of cargo downloading container automatically in temp folder. Please help me here. What am i doing wrong?
Here is my build.gradle so far
group = "com.biw.hc"
version = "0.1.0_SNAPSHOT"
buildscript {
ext {
springBootVersion = "1.2.3.RELEASE"
tomcatVersion = "8.0.20"
logbackJaninoVersion = "2.7.8"
}
repositories {
jcenter()
maven { url "http://repo.spring.io/snapshot" }
maven { url "http://repo.spring.io/milestone" }
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
classpath "net.saliman:gradle-cobertura-plugin:2.2.7"
classpath "com.bmuschko:gradle-cargo-plugin:2.1"
}
}
apply plugin: "spring-boot"
apply plugin: "java"
apply plugin: "groovy"
apply plugin: 'war'
apply plugin: "eclipse"
apply plugin: "idea"
apply plugin: 'com.bmuschko.cargo'
apply plugin: "net.saliman.cobertura"
bootRepackage {
mainClass = 'com.biw.hc.admin.Application'
}
war {
archiveName 'hcadmin.war'
}
repositories {
mavenLocal()
jcenter()
maven { url "http://repo.spring.io/snapshot" }
maven { url "http://repo.spring.io/milestone" }
}
dependencies {
providedRuntime "org.apache.tomcat.embed:tomcat-embed-core"
providedRuntime "org.apache.tomcat.embed:tomcat-embed-el"
providedRuntime "org.apache.tomcat.embed:tomcat-embed-logging-juli"
providedRuntime "org.apache.tomcat.embed:tomcat-embed-websocket"
providedRuntime "org.apache.tomcat:tomcat-jdbc:${tomcatVersion}"
providedRuntime "org.apache.tomcat:tomcat-juli:${tomcatVersion}"
providedRuntime "org.apache.tomcat:tomcat-dbcp:${tomcatVersion}"
compile ("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") {
exclude module: "spring-boot-starter-tomcat:${springBootVersion}"
}
compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}"
compile "org.springframework.boot:spring-boot-starter-thymeleaf:${springBootVersion}"
compile "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}"
compile("org.codehaus.janino:janino:${logbackJaninoVersion}")
// BIW dependencies...
compile "com.biw.hc:hc-core:0.1.0-SNAPSHOT"
// security dependencies...
compile "org.springframework.boot:spring-boot-starter-security:${springBootVersion}"
// testing dependencies...
testCompile "org.codehaus.groovy:groovy-all:2.2.0"
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
testCompile "org.spockframework:spock-spring:0.7-groovy-2.0"
testCompile "org.springframework:spring-test:2.5"
testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}"
compile('org.codehaus.groovy.modules.http-builder:http-builder:0.5.1')
def cargoVersion = '1.4.5'
cargo "org.codehaus.cargo:cargo-core-uberjar:$cargoVersion",
"org.codehaus.cargo:cargo-ant:$cargoVersion"
}
cargo {
containerId = 'tomcat8x'
port = 8080
deployable {
file = file('build/libs/hcadmin.war')
context = 'hcadmin'
}
local {
homeDir = file('C:\\apache-tomcat-8.0.21')
outputFile = file('build/output.log')
containerProperties {
property 'cargo.tomcat.webappsDirectory', 'build/libs'
}
}
}
I came up with a solution like this instead of using cargo plugin
build.mustRunAfter clean
task deploy(dependsOn: ['clean', 'build', 'deployWar']) << {
println '*********************'
println 'hcadmin.war installed'
println '*********************'
}
task deployWar(type: Copy) {
from war
into System.env.'TOMCAT_HOME' + "\\webapps"
}

Resources