Zoe*_*Zoe 7 java gradle kotlin
这个问题关系到这一个.
我得到了这个Gradle任务:
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'rpi-sense-hat-lib',
'Implementation-Version': version,
'Main-Class': 'io.github.lunarwatcher.pi.sensehat.Tests'
}
baseName = project.name
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
with jar
}
Run Code Online (Sandbox Code Playgroud)
并且只有一个依赖项,将测试依赖项放在一边:
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testImplementation group: 'junit', name: 'junit', version: '4.12'
}
Run Code Online (Sandbox Code Playgroud)
从IDE运行正常.但是,当我部署到我的Raspberry Pi(或gradlew fatJar在本地使用jar 结果)时,我得到以下异常:
$ java -jar java-sense-hat-1.0a.jar
Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
at io.github.lunarwatcher.pi.sensehat.UtilsKt.getSenseHat(Utils.kt:18)
at io.github.lunarwatcher.pi.sensehat.SenseHat.<init>(SenseHat.java:12)
at io.github.lunarwatcher.pi.sensehat.Tests.main(Tests.java:9)
Caused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
... 3 more
Run Code Online (Sandbox Code Playgroud)
这是由这一行触发的:
return Optional.empty()
Run Code Online (Sandbox Code Playgroud)
在Kotlin方法中返回Optional<File>.回答相关问题:
kotlin-runtime必须在类路径中并使用$ echo $ CLASSPATH进行验证.
或者你必须将kotlin-runtime添加到maven,然后使用mvn编译程序集在jar本身内组装:single,
这意味着kotlin-runtime不包含在类路径中.在你继续回答"将kotlin-runtime添加到你的依赖项"之前,它是stdlib的一部分:
Kotlin Runtime(不推荐使用,改为使用kotlin-stdlib工件)
我使用kotlin-stdlib-jdk8它,它在IDE中工作.仅用于测试目的,使用kotlin-stdlib而不是改变任何东西.
另外,用implementation它compile修复它.
在我在问题顶部链接的帖子中,有一个建议runtime在fatJar任务中使用.所以:
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'rpi-sense-hat-lib',
'Implementation-Version': version,
'Main-Class': 'io.github.lunarwatcher.pi.sensehat.Tests'
}
baseName = project.name
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
configurations.runtime.collect {
it.isDirectory() ? it : zipTree(it)
}
}
with jar
}
Run Code Online (Sandbox Code Playgroud)
仍然不包括依赖项,程序崩溃.
那么为什么不将实现添加为配置来复制呢?
我试过了.我最终得到了这个:
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'rpi-sense-hat-lib',
'Implementation-Version': version,
'Main-Class': 'io.github.lunarwatcher.pi.sensehat.Tests'
}
baseName = project.name
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
configurations.runtime.collect {
it.isDirectory() ? it : zipTree(it)
}
configurations.implementation.collect {
it.isDirectory() ? it : zipTree(it)
}
}
with jar
}
Run Code Online (Sandbox Code Playgroud)
还有一个例外:
不允许直接解析配置"实现"
因此,考虑:
compile而不是implementation工作implementation子句fatJar会使编译崩溃,并出现单独的异常使用implementation关键字时,如何在Gradle 4.4中生成包含所有依赖项的jar ?
解决建议的副本:它只适用于compile关键字,而不是implementation.此外,compile已被弃用赞成implementation和api,这就是为什么使用compile而不是implementation声明依赖不是一个选项.
Kon*_*tor 11
您是否尝试过Shadow Plugin:
shadowJar {
manifest {
attributes 'Implementation-Title': 'rpi-sense-hat-lib',
'Implementation-Version': version,
'Main-Class': 'io.github.lunarwatcher.pi.sensehat.Tests'
}
configurations = [project.configurations.compile, project.configurations.runtime]
}
Run Code Online (Sandbox Code Playgroud)
编辑:
您也可以这样做(如此问题的答案中所述):
configurations {
fatJar
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testImplementation group: 'junit', name: 'junit', version: '4.12'
fatJar "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'rpi-sense-hat-lib',
'Implementation-Version': version,
'Main-Class': 'io.github.lunarwatcher.pi.sensehat.Tests'
}
baseName = project.name
from {
configurations.fatJar.collect {
it.isDirectory() ? it : zipTree(it)
}
}
with jar
}
Run Code Online (Sandbox Code Playgroud)
但是你必须重复所有的实现依赖关系作为fatJar依赖.对于你当前的项目来说没关系,因为你只有一个依赖项,但对于任何更大的项目,它都会变得一团糟......
编辑2:
正如@Zoe在评论中指出的那样,这也是一个可以接受的解决方案:
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'rpi-sense-hat-lib',
'Implementation-Version': version,
'Main-Class': 'io.github.lunarwatcher.pi.sensehat.Tests'
}
baseName = project.name
from {
configurations.runtimeClasspath.collect {
it.isDirectory() ? it : zipTree(it)
}
}
with jar
}
Run Code Online (Sandbox Code Playgroud)
但是,应通知按照源代码,这runtimeClasspath是一个组合runtimeOnly,runtime并且implementation,可能会或可能不希望根据情况-例如,你可能不希望包括runtime依赖性,因为它们是由容器提供.
| 归档时间: |
|
| 查看次数: |
3977 次 |
| 最近记录: |