Java - Библиотечные зависимости не импортируются, когда jar зависит от - PullRequest
1 голос
/ 10 января 2020

Я пытаюсь переместить некоторые часто используемые модули в их собственный проект, чтобы их можно было загрузить в частный репозиторий и использовать в приложениях. В настоящее время все они находятся в одной многопроектной конфигурации, и все работает, как ожидалось. Я переместил их, и все, кажется, строит хорошо. Когда я использую их в качестве зависимостей в своих приложениях, я получаю сообщения об ошибках java.lang.module.FindException: Module X not found, required by COMMON-MODULE-Y.

. У меня сложилось впечатление, что плагин java-library позволяет моему приложению импортировать те вторичные зависимости, которые были необходимы для зависимостей. объявлено, и это не то, что происходит.

Как я могу упаковать мои обычно используемые модули, чтобы разрешить это ИЛИ, как я могу настроить свой проект, чтобы разрешить это? Я использую Java 11 для этого.

EDIT

По сути, я хочу, чтобы мои библиотеки были автономными, а приложения, использующие их, не включали в себя никаких дополнительных библиотек. .

Вот мой build.gradle для модуля, на котором я получаю вышеуказанную ошибку.

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 для мультипроекта, в котором находится вышеупомянутый модуль.

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

1 Ответ

3 голосов
/ 10 января 2020

Краткий ответ: вы хотите выставить зависимости времени выполнения . Например, они необходимы для выполнения приложения, однако они не должны быть доступны для компиляции.

Пожалуйста, используйте следующий работающий код:

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

Итак, что мы сделали:

  • Наши зависимости: application -> libraryA -> libraryB
  • application - это исполняемый проект, все остальные - просто библиотеки.
  • libraryA не имеет любые слова, чтобы повторно раскрыть зависимость. Это просто ссылки libraryB
  • application просто ссылки libraryA. Разработчик не знает ни о каких неявных зависимостях (компиляции или времени выполнения).
  • libraryB использует kotlinx-coroutines-reactor и выставляет его как зависимость времени выполнения. И эта информация публикуется через libraryA в работоспособном проекте.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...