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) }
}
...
}
我是 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) }
}
...
}