依赖jar时未导入Java库依赖 [英] Java-Library dependencies not being imported when jar is depended on

查看:216
本文介绍了依赖jar时未导入Java库依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将一些常用模块移到他们自己的项目中,以便可以将它们上传到私有存储库中并在应用程序中使用.当前,它们全部处于一个多项目配置中,并且一切正常.我将它们移出,似乎一切正常.当我将它们用作应用程序中的依赖项时,会出现错误提示java.lang.module.FindException: Module X not found, required by COMMON-MODULE-Y.

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.

给我的印象是java-library插件允许我的应用程序导入声明的依赖项所需要的那些次级依赖项,而这不是正在发生的事情.

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.

如何打包常用模块以允许此操作,或者如何配置我的项目以允许此操作?我为此使用Java 11.

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.

编辑

基本上,我希望我的库是独立的,使用它们的应用程序不要包含任何其他库.

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

这是我的模块build.gradle,我遇到上述错误.

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'
}

这是上述模块所在的多项目的build.gradle.

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.

请使用以下可行代码:

settings.gradle.kts:

settings.gradle.kts:

include(":application")
include(":libraryA")
include(":libraryB")

application/gradle.build.kts:

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:

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:

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

libraryB\src\Something.kt

import kotlinx.coroutines.runBlocking

fun doSomething() {
    runBlocking { // use kotlinx-coroutines here.
        println("Yess !!!")
    }
}

application \ src \ Application.kt

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()
}

所以,我们做了什么:

  • 我们的依赖项:application-> libraryA-> libraryB
  • application是可运行的项目,所有其他都是库.
  • libraryA没有任何要重新暴露依赖项的单词.它只是引用libraryB
  • application仅引用libraryA.开发人员不知道任何隐式依赖关系(编译或运行时).
  • libraryB使用kotlinx-coroutines-reactor并将其公开为运行时依赖项.并且此信息通过libraryA发布到可运行的项目.
  • 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.

这篇关于依赖jar时未导入Java库依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆