从命令行运行时混合java和kotlin代码的ClassNotFoundException

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

我在一个演示项目中混合了JavaKotlin代码,我想从command line运行。对于只有java,我能够用java -jar foo.jar运行程序但是当我使用Kotlin代码中的任何类时,它会生成java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics

我尝试了不同的解决方案并检查了jar文件。它包含两个类但我想jar中缺少kotlin-runtime

这是build.gradle文件

plugins {
    id 'java-library'
    id 'org.jetbrains.kotlin.jvm'
}

sourceSets {
    main.java.srcDirs += 'src/main/kotlin/'
    test.java.srcDirs += 'src/test/kotlin/'
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    testImplementation 'junit:junit:4.12'
}

jar {
    manifest {
        attributes 'Main-Class': 'com.mallaudin.App'
    }
    from {
        configurations.compile.collect {
            it.isDirectory()? it: zipTree(it)
        }
    }
}

生成的jar文件的内容

.
├── com
│   └── mallaudin
│       ├── App.class
│       └── User.class
└── META-INF
    ├── basics.kotlin_module
    └── MANIFEST.MF

MANIFEST.MF的内容

Manifest-Version: 1.0
Main-Class: com.mallaudin.App

我从命令行运行qazxsw poi时得到的异常

jar
java gradle command-line kotlin compilation
2个回答
1
投票

问题在于你制造胖罐的方式。虽然您对依赖项使用了更新的和推荐的allaudin@geek ~/Desktop/KotlinLab (master) $ java -jar basics/build/libs/basics.jar Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics at com.mallaudin.User.<init>(User.kt) at com.mallaudin.App.main(App.java:5) Caused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:190) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499) ... 2 more 作用域,但您只是向fat jar添加了implementation配置的内容。

您应该通过compile替换要在胖jar中使用的配置,runtimeClasspath是完整的运行时组件集。

那是:

jar {
  manifest {
    attributes 'Main-Class': 'com.mallaudin.App'
  }
  from {
    configurations.runtimeClasspath.collect {
      it.isDirectory()? it: zipTree(it)
    }
  }
}  

查看the documentation以了解java项目的不同依赖配置。


0
投票

所以,我找到了一个解决方案。在build.gradle文件中,我用implementation替换了compile配置,现在可以使用了。我相信它也应该与implementation合作,但事实并非如此。现在jar看起来像这样

.
├── com
├── kotlin
├── META-INF
└── org
© www.soinside.com 2019 - 2024. All rights reserved.