gradle 创建 jar 不适用于 'implementation' 依赖项

gradle creating jar does not work with 'implementation' depedencies

我是 gradle 的新手,正在尝试从简单的 hello world 生成一个 jar java grpc 下面是我的 build.gradle

plugins {
    id 'application'
    id 'com.google.protobuf' version '0.8.12'
    id 'idea'
    id 'java'
}

version '1.0'

sourceCompatibility = 1.8

repositories {
    mavenLocal()
    maven { // The google mirror is less flaky than mavenCentral()
        url "https://maven-central.storage-download.googleapis.com/repos/central/data/" }
    mavenCentral()
}

dependencies {
    implementation 'io.grpc:grpc-netty-shaded:1.29.0'
    implementation 'io.grpc:grpc-protobuf:1.29.0'
    implementation 'io.grpc:grpc-stub:1.29.0'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}


protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:3.11.0"
    }
    plugins {
        grpc {
            artifact = 'io.grpc:protoc-gen-grpc-java:1.29.0'
        }
    }
    generateProtoTasks {
        all()*.plugins {
            grpc {}
        }
    }
}

sourceSets {
    main {
        java {
            srcDirs 'build/generated/source/proto/main/grpc'
            srcDirs 'build/generated/source/proto/main/java'
        }
    }
}

startScripts.enabled = false

task helloWorldServer(type: CreateStartScripts) {
    mainClassName = 'com.javagrpc.HelloWorldServer'
    applicationName = 'hello-world-server'
    outputDir = new File(project.buildDir, 'tmp')
    classpath = startScripts.classpath
}

applicationDistribution.into('bin') {
    from(helloWorldServer)
    fileMode = 0755
}

distZip.shouldRunAfter(build)

jar {
    manifest {
        attributes 'Main-Class': 'com.examples.javagrpc.HelloWorldServer',
        'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
    }

    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
}

当我 运行 任务 'gradle jar' 它在 build/libs 构建一个 jar 时,我开始 运行 遇到问题 当我 运行 jar 失败时java.lang.NoClassDefFoundError: io/grpc/BindableService 我解压了 jar 并没有在里面找到 grpc 依赖项。 我尝试 运行直接生成文件

./build/install/java-grpc/bin/hello-world-server

并且它按预期工作。 为了解决 jar 问题,我决定将上述依赖项从 implementation 更改为 api,如下所示。

dependencies {
    api 'io.grpc:grpc-netty-shaded:1.29.0'
    api 'io.grpc:grpc-protobuf:1.29.0'
    api 'io.grpc:grpc-stub:1.29.0'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

现在一切都按预期工作,依赖项在 jar 中,我可以 运行 jar。 但是我不确定我是否应该在我的依赖项中使用 api ,因为官方 example 不使用它? 也许我没有正确生成 jar,它可以仅通过依赖项 实现 生成,非常感谢任何帮助或指示。

问题是您使用的 jar 任务修改没有利用新的依赖配置。

与其从 compile 收集依赖项,不如从你的 uber JAR 中收集 runtimeClasspath 的依赖项。毕竟,为了 运行,它需要在 implementation 中声明的所有依赖项,但也需要 runtimeOnly 中声明的所有依赖项。请参阅 the documentation 以更好地理解这些配置之间的关系。

jar {
    ...
    from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
    ...
}