【问题标题】:gradle creating jar does not work with 'implementation' depedenciesgradle 创建 jar 不适用于“实现”依赖项
【发布时间】:2020-05-18 18:35:32
【问题描述】:

我是 gradle 新手,正在尝试从一个简单的 hello world java grpc 生成一个 jar 下面是我的 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”时,我开始遇到问题,当我运行 jar 时,它会在 build/libs 中构建一个 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,它可以通过依赖项生成它实现任何帮助或指针都非常感谢。

【问题讨论】:

  • 能否尝试运行gradle build,然后查看build/libs目录下是否有生成jar文件?
  • @keweixia gradle build 也生成与 jar 命令相同的内容,并且其中没有 grpc 库。

标签: java gradle grpc grpc-java


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2015-06-28
    • 2018-08-23
    • 2020-08-19
    • 1970-01-01
    • 2022-01-05
    • 2022-10-20
    • 1970-01-01
    • 2020-12-06
    • 2015-06-06
    相关资源
    最近更新 更多