Для моего приложения требуется библиотека spring-context. Итак, в моем файле build.gradle я добавляю эту зависимость,
dependencies {
compile 'org.springframework:spring-context:5.1.6.RELEASE'
}
Я также хочу создать исполняемый jar-файл, задача jar выглядит так:
jar {
manifest {
attributes 'Main-Class': 'my.package.my.main.class'
}
}
Все в порядке, когда я запустил файл сборки,
gradle build
Но когда я попытался запустить это работающее приложение jar,
task runJar(dependsOn: jar, type: JavaExec) {
classpath(configurations.compile)
main = '-jar'; args 'build/libs/my-runnable.jar'
}
Консоль брошена NoClassDefFoundError,
Exception in thread "main" java.lang.NoClassDefFoundError:
org/springframework/context/ConfigurableApplicationContext
...
...
Я пробовал sourceSets.main.runtimeClasspath, проблема осталась прежней,
task runJar(dependsOn: jar, type: JavaExec) {
classpath(sourceSets.main.runtimeClasspath)
main = '-jar'; args 'build/libs/my-runnable.jar'
}
Я проверил коллекцию файлов classpath,
classpath.each {
println it.name
}
spring-context посылка была тут же,
spring-context-5.1.6.RELEASE.jar
spring-aop-5.1.6.RELEASE.jar
spring-beans-5.1.6.RELEASE.jar
spring-expression-5.1.6.RELEASE.jar
spring-core-5.1.6.RELEASE.jar
spring-jcl-5.1.6.RELEASE.jar
Затем я попробовал другой обходной подход, чтобы решить эту проблему. Я извлек все файлы классов из этих .jar библиотек и включил их непосредственно в свой окончательный runnable.jar,
jar {
manifest {
attributes 'Main-Class': 'my.package.my.main.class'
}
configurations.compile.each {
from(project.zipTree(it))
}
}
И это решение работает. Но такая "толстая банка" мне не нужна.
Я новичок в Gradle. Это действительно смутило меня. Кто-нибудь может помочь? Спасибо!




Примерно через 3 часа работы простая истина такова:
When you specify -jar then the -cp parameter will be ignored.
Некоторое подробное обсуждение находится в этом вопросе:
Есть 2 простых обходных решения:
.class прямо в исполняемый файл jar, как я уже упоминал в своем вопросе.jar {
manifest {
attributes 'Main-Class': 'my.package.my.main.class'
}
configurations.compile.each {
from(project.zipTree(it))
}
}
Class-Path в файл manifest.jar {
manifest {
attributes 'Main-Class': 'your.main.class.full.name'
attributes 'Class-Path': configurations.compile.collect { it.name }.join(' ')
}
}
Убедитесь, что вы можете найти библиотеки .jar в вашей локальной системе. Ex, просто скопируйте их в тот же каталог,
task copyLibs(type: Copy) {
from configurations.compile
into 'build/libs/'
}
После этого мой каталог build/libs/ выглядит так:
build
├── libs
│ ├── my-runnable-app.jar
│ ├── spring-aop-5.1.6.RELEASE.jar
│ ├── spring-beans-5.1.6.RELEASE.jar
│ ├── spring-context-5.1.6.RELEASE.jar
│ ├── spring-core-5.1.6.RELEASE.jar
│ ├── spring-expression-5.1.6.RELEASE.jar
│ └── spring-jcl-5.1.6.RELEASE.jar
Обратите внимание, что все библиотеки .jar находятся вне my-runnable-app.jar. Если вы хотите включить их в себя my-runnable-app.jar, вам нужен One-Jar инструментарий. Для получения дополнительной информации о One-Jar, пожалуйста, прочитайте этот вопрос: