java导入依赖库,依赖jar时未导入Java库依赖

I am attempting to move some commonly used modules into their own project so they can be uploaded to a private repository and used in applications. Currently, they are all in one multi-project configuration and everything works as expected. I moved them out and it all seems to build fine. When I use them as dependencies in my applications, I get errors that say java.lang.module.FindException: Module X not found, required by COMMON-MODULE-Y.

I was under the impression that the java-library plugin allowed my application to import those secondary dependencies that were needed by the dependencies declared, and this is not what is happening.

How can I package my commonly used modules to allow this OR how can i configure my project to allow for this? I am using Java 11 for this.

EDIT

Basically I want my libraries to be self contained and the applications that use them to not include any additional libraries.

Here is my build.gradle for the module I am getting the above error on.

plugins {

id 'java-library'

id 'idea'

}

if(project.hasProperty('javaVer') && javaVer == '8') {

sourceCompatibility = 1.8

targetCompatibility = 1.8

}

idea {

module {

inheritOutputDirs = true

}

}

def currentOS = org.gradle.internal.os.OperatingSystem.current()

def depPlatform

if (!project.hasProperty(('platform'))) {

if (currentOS.isWindows()) {

depPlatform = 'win'

} else if (currentOS.isLinux()) {

depPlatform = 'linux'

} else if (currentOS.isMacOsX()) {

depPlatform = 'mac'cd

}

}else {

depPlatform = project.getProperties().get("platform");

}

sourceSets.main {

java {

srcDir 'src/main/java' //assume that your source codes are inside this path

}

resources {

srcDirs = ['src/main/java', 'src/main/resources']

exclude "**/*.java"

}

}

ext.moduleName = 'license'

dependencies {

implementation project(':common')

implementation "org.openjfx:javafx-base:11.0.2:${depPlatform}"

implementation 'commons-io:commons-io:2.6'

implementation 'org.apache.commons:commons-lang3:3.7'

implementation 'com.google.code.gson:gson:2.8.2'

implementation 'com.github.purejavacomm:purejavacomm:1.0.1.RELEASE'

}

Here is the build.gradle for the multi-project the above module is in.

subprojects {

afterEvaluate {

repositories {

mavenCentral()

jcenter()

}

compileJava {

if (project.hasProperty(('javaVer')) && javaVer == '8') {

excludes = ['**/module-info.java']

} else {

doFirst {

options.compilerArgs = [

'--module-path', classpath.asPath,

]

}

}

}

jar {

archiveFileName = project.name + '-' + (project.hasProperty(('releaseSpec')) ? project.releaseSpec : 'SNAPSHOT') + '.jar'

}

}

}

解决方案

Short answer: you want to expose runtime dependencies. E.g. they are needed for application execution, however they shouldn't be available for compilation.

Please use the following workable code:

settings.gradle.kts:

include(":application")

include(":libraryA")

include(":libraryB")

application/gradle.build.kts:

plugins {

application

kotlin("jvm") version "1.3.61"

}

dependencies {

api(project(":libraryA")) // we reference only library, we know nothing about the dependencies.

}

libraryA/gradle.build.kts:

plugins {

kotlin("jvm") version "1.3.61"

}

dependencies {

api(project(":libraryB")) // again, we know nothing about the dependencies

}

libraryB/gradle.build.kts:

plugins {

kotlin("jvm") version "1.3.61"

}

dependencies {

api("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.61")

// api("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.3.3") - uncomment this line to expose api. You will see kotlinx-coroutines-reactor members in intellisence

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.3.3") // mark, that this dependency is needed for compilation. However it will not be exposed to other project.

runtimeOnly("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.3.3") // mark, that this dependency is required for runtime. It means, that it will be exposed as runtime dependency only

}

libraryB\src\Something.kt

import kotlinx.coroutines.runBlocking

fun doSomething() {

runBlocking { // use kotlinx-coroutines here.

println("Yess !!!")

}

}

application\src\Application.kt

package gradle.multi.application

import doSomething

fun main() {

"12314".toInt() // check, that api layer is exposed here

/* runBlocking { // this couldn't be compiled, because kotlinx-coroutines aren't exposed here

}*/

doSomething()

}

So, what we did:

Our dependencies: application --> libraryA --> libraryB

application is runnable project, all other are just libraries.

libraryA doesn't have any words to re-expose dependency. It just references libraryB

application just references libraryA. Developer doesn't know about any implicit dependencies (compile or runtime).

libraryB uses kotlinx-coroutines-reactor and exposes it as runtime dependency. And this information is published through libraryA to the runnable project.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值