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.
Related
Im trying to get Proguard to work but Im still new to Gradle.
My build gradle.kts haves an error (Unresolved reference: proguard), I cant create a proguard Task:
plugins {
id("com.github.johnrengelman.shadow") version "5.2.0"
java
kotlin("jvm") version "1.3.61"
}
group = "*...*"
version = "*...*"
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation(kotlin("stdlib-jdk8"))
//*...*
implementation("net.sf.proguard","proguard-gradle","6.2.2") //is this correct?
}
configure<JavaPluginConvention> {
sourceCompatibility = JavaVersion.VERSION_1_8
}
tasks {
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
jar{
manifest {
attributes["Main-Class"] = "*...*"
}
}
shadowJar{
archiveBaseName.set("*...*")
archiveClassifier.set("")
archiveVersion.set("")
}
register<proguard.gradle.ProGuardTask>("myProguardTask") { //Unresolved reference: proguard
}
}
This is not an Android Project
Because Stackoverflow wants me to write more than just code: Im planing to somehow link the proguard output to the shadowjar task. If you know how to do it Im also interested to that (and I could not try it myself because of this problem).
You declared a dependency of proguard in project rather than for Gradle itself.
Move the dependency to the buildscript block:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'net.sf.proguard:proguard-gradle:6.2.2'
}
}
Then you should be able to create your task.
Alternatively, you can declare the repository in settings.gradle.kts:
pluginManagement {
repositories {
jcenter()
}
}
which will trim down the buildscript block in build.gradle.kts:
buildscript {
dependencies {
classpath("net.sf.proguard:proguard-gradle:6.2.2")
}
}
A multi module project with Kotlin source code, which used to work, stops working after upgrading to Gradle 5.2, because the Kotlin classes from the compile project('depend-test') dependency are not found.
Attempted to change plugin version
already viewed https://github.com/gradle/gradle/issues/8980
i defind Test class in project('depend-test')
object Test {
const val test = "123"
}
i want to use Test class in project('test-test')
package com.example.test.controller
import com.example.dependtest.Test
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
#RestController
#RequestMapping
class TestController {
private val log = LoggerFactory.getLogger(TestController::class.java)
#GetMapping(value = ["/test"])
fun test() {
log.info(Test.test)
}
}
when i want to build project('test-test') to jar where i used gradle bootJar。 I get this error:
> Task :test-test:compileKotlin FAILED
e: /Users/houshuai/Documents/dev/demo/test/test-test/src/main/kotlin/com/example/test/controller/TestController.kt: (3, 20): Unresolved reference: dependtest
e: /Users/houshuai/Documents/dev/demo/test/test-test/src/main/kotlin/com/example/test/controller/TestController.kt: (22, 18): Unresolved reference: Test
Expected Behavior
The Kotlin classes in the compile project('depend-test') dependency should be found.
Current Behavior
The Kotlin classes in the compile project('depend-test') dependency are not found:
Try adding this to your build.gradle file
bootJar {
enabled = false
}
jar {
enabled = true
}
Just in case someone else comes across this problem.
I created two modules, test-test and depend-test.
The depend-test project is test-test 's dependency.
I tried to call the parameters of depend-test, but it failed to compile and package.
Env
gradle-5.2.1
Kotlin 1.3.31
Springboot 2.1.4
java 1.8
step one
Edit settings.gradle
rootProject.name = 'demo'
include ":depend-test"
include ":test-test"
project(":depend-test").projectDir = file("depend/depend-test")
project(":test-test").projectDir = file("test/test-test")
I used the 1.3.31 version of the kotlin plug-in. The build.gradle file reads as follows
buildscript {
ext {
kotlinVersion = '1.3.31'
}
repositories {
mavenCentral()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/'}
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion"
}
}
plugins {
id 'org.springframework.boot' version '2.1.4.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.2.71'
id 'org.jetbrains.kotlin.plugin.spring' version '1.2.71'
}
allprojects {
apply plugin: 'idea'
apply plugin: 'kotlin'
repositories {
mavenCentral()
}
}
subprojects {
apply plugin: 'kotlin'
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: "application"
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
repositories {
mavenLocal()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/'}
maven { url "https://plugins.gradle.org/m2/" }
mavenCentral()
jcenter()
maven { url "http://repo.spring.io/snapshot" }
maven { url "http://repo.spring.io/milestone" }
maven { url 'http://maven.springframework.org/release' }
maven { url 'http://maven.springframework.org/milestone' }
}
version = '1.0'
apply plugin: 'io.spring.dependency-management'
group = 'com.mutil.test'
sourceCompatibility = '1.8'
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
implementation 'org.jetbrains.kotlin:kotlin-reflect'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
}
dependencies {
subprojects.forEach {
archives(it)
}
}
repositories {
mavenCentral()
}
step two
build jar for test-test project ,I used two ways, but the results were the same.
terminal use cmd is ./gradlew :test-test:bootJar
user IDEA gradle tool
result
The class file written by kotlin in the submodule cannot be found.
I do not know if the lack of necessary plug-ins caused the failure to package properly.
I have a working build.gradle that I'd like to refactor into the buildSrc directory but I'm having trouble finding the dependencies.
Working build.gradle:
import groovyx.net.http.HTTPBuilder
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'org.codehaus.groovy.modules.http-builder:http-builder:0.7.2'
}
}
plugins {
id 'groovy'
}
group "com.example"
version "0.0.1"
class Foo {
Foo() {
new HTTPBuilder('http://www.example.com')
}
}
Non-working refactored build.gradle:
However, when I try to split into the following:
build.gradle
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'org.codehaus.groovy.modules.http-builder:http-builder:0.7.2'
}
}
plugins {
id 'groovy'
}
group "com.example"
version "0.0.1"
and buildSrc/src/main/groovy/Foo.groovy
import groovyx.net.http.HTTPBuilder
class Foo {
Foo() {
new HTTPBuilder('http://www.example.com')
}
}
Gives the error:
C:\Project\buildSrc\src\main\groovy\Foo.groovy: 7: unable to resolve
class HTTPBuilder # line 5, column 26.
HTTPBuilder client = new HTTPBuilder('http://www.example.com')
How can I get gradle to recognise the dependencies?
You need to create a build.gradle file for buildSrc directory. Try this:
C:\Project\buildSrc\build.gradle
apply plugin: 'groovy'
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile 'org.codehaus.groovy.modules.http-builder:http-builder:0.7.2'
}
There is more details in this documentation section.
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.
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
}