ClassNotFoundException для смешанного кода Java и Kotlin при запуске из командной строки - PullRequest
0 голосов
/ 15 декабря 2018

Я смешал код Java & Kotlin в демонстрационном проекте, который я хочу запустить с command line.Только для Java, я могу запустить программу с java -jar foo.jar, но когда я использую любой класс из Kotlin кода, , он генерирует java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics

Я пробовал разные решения ипроверил файл jar.Он содержит оба класса, но, я думаю, kotlin-runtime отсутствует в jar.

Вот build.gradle file

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

Исключение, которое я получаю при запуске jar командной строки формы

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

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Проблема в том, как вы строите свой толстый кувшин.В то время как вы используете более свежую и рекомендованную область действия implementation для своих зависимостей, вы только добавляете в банку содержимого содержимое конфигурации compile.

Вы должны заменить конфигурацию, которая будет использоваться в журнале.jar от runtimeClasspath, который является полным набором компонентов времени выполнения.

То есть:

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

Просмотрите документацию , чтобы понять различные конфигурации зависимостейдля проекта Java.

0 голосов
/ 16 декабря 2018

Итак, я нашел решение.В build.gradle файле я заменил конфигурацию implementation на compile, и теперь она работает.Я считаю, что это должно работать с implementation тоже, но это не так.Теперь jar выглядит так

.
├── com
├── kotlin
├── META-INF
└── org
...