依赖项(module-info.java 中的“requires”)在 build.gradle 中使用自定义配置时未解决

问题描述 投票:0回答:1

对于下面的一段代码,“需要org.postgresql.jdbc;”尝试执行 Gradle-sync/assemble/build 并使用自定义配置“驱动程序”和自定义 sourceSet“驱动程序”时未解决。

build.gradle

plugins {
    id 'java-library'           //used to create java api and implementation separated libs
}

configurations{
    driver
}

dependencies {
    driver group: 'org.postgresql', name: 'postgresql', version: '42.6.0'
}

sourceSets{
    driver{
        java{ srcDirs = ['src'] }
    }
}
compileJava.dependsOn(compileDriverJava)

module-info.java

module database.driver {
    requires java.base;              // core dependencies(internal)
    requires java.sql;               // sql module (externalized) dependencies
    requires org.postgresql.jdbc;    // postgresql driver (internal) dependencies
}

当使用默认的“实现”配置和默认的“主要”源集时,它已得到解决并且可以正常构建/组装而没有问题。

build.gradle

plugins {
    id 'java-library'           //used to create java api and implementation separated libs
}

dependencies {
    implementation group: 'org.postgresql', name: 'postgresql', version: '42.6.0'
}

sourceSets{
    main{
        java{ srcDirs = ['src'] }
    }
}
compileJava.dependsOn(compileDriverJava)

为什么 module-info.java 的自定义配置依赖不可见,这是因为没有使用 sourceSet 'main' 的原因吗?

注意:在为 sourceSets 和依赖项任务使用自定义配置“驱动程序”时运行 ./gradlew dependencies,打印出依赖项已解决。

注意:compileJava 本身不执行任何操作,也没有任何 sourceSets 可以使用,因此不需要任何依赖项。但这取决于自定义配置编译'compileDriverJava'

注意:postgres 清单包含 Automatic-module-name 以表示它是一个自动模块

Manifest-Version: 1.0
Automatic-Module-Name: org.postgresql.jdbc

使用自定义配置“驱动程序”时“./gradlew dependencies”的输出

> Task :dependencies

------------------------------------------------------------
Root project 'database.driver'
------------------------------------------------------------

annotationProcessor - Annotation processors and their dependencies for source set 'main'.
No dependencies

api - API dependencies for source set 'main'. (n)
No dependencies

apiElements - API elements for main. (n)
No dependencies

compileClasspath - Compile classpath for source set 'main'.
No dependencies

compileOnly - Compile only dependencies for source set 'main'. (n)
No dependencies

compileOnlyApi - Compile only API dependencies for source set 'main'. (n)
No dependencies

default - Configuration for default artifacts. (n)
No dependencies

driver
\--- org.postgresql:postgresql:42.6.0
     \--- org.checkerframework:checker-qual:3.31.0

driverAnnotationProcessor - Annotation processors and their dependencies for source set 'driver'.
No dependencies

driverCompileClasspath - Compile classpath for source set 'driver'.
No dependencies

driverCompileOnly - Compile only dependencies for source set 'driver'. (n)
No dependencies

driverImplementation - Implementation only dependencies for source set 'driver'. (n)
No dependencies

driverRuntimeClasspath - Runtime classpath of source set 'driver'.
No dependencies

driverRuntimeOnly - Runtime only dependencies for source set 'driver'. (n)
No dependencies

implementation - Implementation only dependencies for source set 'main'. (n)
No dependencies

mainSourceElements - List of source directories contained in the Main SourceSet. (n)
No dependencies

runtimeClasspath - Runtime classpath of source set 'main'.
No dependencies

runtimeElements - Elements of runtime for main. (n)
No dependencies

runtimeOnly - Runtime only dependencies for source set 'main'. (n)
No dependencies

testAnnotationProcessor - Annotation processors and their dependencies for source set 'test'.
No dependencies

testCompileClasspath - Compile classpath for source set 'test'.
No dependencies

testCompileOnly - Compile only dependencies for source set 'test'. (n)
No dependencies

testImplementation - Implementation only dependencies for source set 'test'. (n)
No dependencies

testResultsElementsForTest - Directory containing binary results of running tests for the test Test Suite's test target. (n)
No dependencies

testRuntimeClasspath - Runtime classpath of source set 'test'.
No dependencies

testRuntimeOnly - Runtime only dependencies for source set 'test'. (n)
No dependencies

gradle build.gradle java-11 java-platform-module-system module-info
1个回答
0
投票

好的发现了问题,似乎 gradle 解析器关心令牌声明的顺序,

问题是 sourceSets 在 dependencies 块之后被声明,当 dependencies 块被解析时,除了隐式配置外,只有一个名为

driver
的配置可用
default

所以我能够使用

driver group: 'org.postgresql', name: 'postgresql', version: '42.6.0'
并且它起作用了,因为它将依赖关系与自定义配置本身相关联。

但是没有看到有一个自定义的 sourceSet

driver
,正如@Vampire 所建议的那样,
driverImplementation group: 'org.postgresql', name: 'postgresql', version: '42.6.0'
指定了它的依赖项,我在发布到这里之前已经尝试过了。

所以 将 sourceSets 声明移动到 dependencies 之上having

driverImplementation
instead of
driver
解决了这个问题。

注意: 我已将自定义 sourceSet

driver
重命名为
foo
以检查它是否与自定义配置有任何互连,答案是没有。 所以基本上,如果我在添加
fooImplementation group: 'org.postgresql', name: 'postgresql', version: '42.6.0'
后将依赖项块中的语句重命名为
sourceSets { foo }
,那么 gradle 能够将依赖项正确映射到 custom sourceSet foo.

我不确定 gradle 用户手册是否从新用户的角度准确地包含了这些细节/说明。

注意:虽然我的 gradle 问题已解决,但由于我正在使用 IntelliJ IDE 并且它仍然没有看到/识别自定义 SourceSet 中的依赖项并在 module-info.java 中显示错误但 gradle即使在 IDE 中编译也能正常工作。

IDE 可以看到依赖关系,并且在依赖关系块中使用

main
implementation group: 'org.postgresql', name: 'postgresql', version: '42.6.0'
sourceSet 设置依赖关系时,不会在视觉上产生错误。

另一个解决方法是

implementation
配置从这个自定义配置
driver
使用
implementation.extendsFrom(driver)
扩展,然后只使用
driver group: 'org.postgresql', name: 'postgresql', version: '42.6.0'
以便依赖关系关联到自定义配置驱动程序,因此也隐式关联到实现。

注意: 这样做可以解决 IntelliJ IDE 中的依赖关系,并且 IDE 红色标记已删除。

案例一:

// DOESN'T WORK:
/*
    Reasons:
        1. sourceSets block declared after dependency block which contains the dependency
        2. it will still fail because there is no implementation dependency for the custom sourceSet ie, missing `driverImplementation`
*/

configurations {
    driver
}

dependencies {
    driver 'org.postgresql:postgresql:42.6.0'
}

sourceSets{
    driver{
        java{
            srcDirs = ['src/main/java']
        }
    }
}

task compile(){                            //GRADLE-ERROR
    dependsOn compileJava                  
    dependsOn compileDriverJava            
}

案例2:

// DOESN'T WORK:
/*
    Reasons:
        1. there is no implementation dependency for the custom sourceSet ie, missing `driverImplementation` because dependencies declaration are unique for custom configuration and custom sourceSets.
        2. both sourceSets 'main' and 'driver' (custom sourceSet), FAILS
*/

configurations {
    driver
}

sourceSets{
    driver{
        java{
            srcDirs = ['src/main/java']
        }
    }
}

dependencies {
    driver 'org.postgresql:postgresql:42.6.0'
}

task compile(){
    dependsOn compileJava                  //FAILS
    dependsOn compileDriverJava            //FAILS
}

案例3:

PARTIALLY WORKS:
/*
    Reasons:
        1. there is implementation dependency for the custom sourceSet ie, `driverImplementation` contains required dependency.
    NOTE: IDE still doesn't recognize the dependency since it is not on the main sourceSet.
        2. hence compileJava for main sourceSet, FAILS.
        3. however compileDriverJava for custom sourceSet 'driver', PASSES
*/

configurations {
    driver
}

sourceSets{
    driver{
        java{
            srcDirs = ['src/main/java']
        }
    }
}

dependencies {
    driverImplementation 'org.postgresql:postgresql:42.6.0'
}

task compile(){
    dependsOn compileJava                  //FAILS
    dependsOn compileDriverJava            //PASSES
}

案例4:

PARTIALLY WORKs:
/*
    Reasons:
        1. though there is NO implementation dependency for the custom sourceSet ie, `driverImplementation`, the main sourceSet indirectly extends the custom configuration's dependency for itself.
        2. hence they become available and visible to the main sourceSet and IDE is able to resolve them too.
        3. but due to REASON-1 the compilation of custom sourceSet fails ie, task compileDriverJava fails
       4. however compileJava from main sourceSet passes and generates class files successfully.
*/

configurations {
    driver
    implementation.extendsFrom(driver)
}

sourceSets{
    driver{
        java{
            srcDirs = ['src/main/java']
        }
    }
}

dependencies {
    driver 'org.postgresql:postgresql:42.6.0'
}

task compile(){
    dependsOn compileJava                  //PASSES
    dependsOn compileDriverJava            //FAILS
}

案例5

FULLY WORKs:
/*
    Reasons:
        1. there is implementation dependency for the custom sourceSet ie, `driverImplementation`.
        2. due to REASON-1, compileDriverJava, PASSES
        3. the implementation configuration extends from custom configuration driver inheriting all its dependencies.
       4. due to REASON-3, compileJava, PASSES.
*/
configurations {
    driver
    implementation.extendsFrom(driver)
}

sourceSets{
    driver{
        java{
            srcDirs = ['src/main/java']
        }
    }
}

dependencies {
    driver 'org.postgresql:postgresql:42.6.0'
    driverImplementation 'org.postgresql:postgresql:42.6.0'
}

task compile(){
    dependsOn compileJava                  //PASSES
    dependsOn compileDriverJava            //PASSES
}
© www.soinside.com 2019 - 2024. All rights reserved.