Как добавить путь к классам в задачу Gradle JavaExec для запуска исполняемой банки?

Для моего приложения требуется библиотека 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. Это действительно смутило меня. Кто-нибудь может помочь? Спасибо!

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
0
4 584
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Примерно через 3 часа работы простая истина такова:

When you specify -jar then the -cp parameter will be ignored.

Некоторое подробное обсуждение находится в этом вопросе:

Run a JAR file from the command line and specify classpath

Есть 2 простых обходных решения:

  1. Извлеките все файлы .class прямо в исполняемый файл jar, как я уже упоминал в своем вопросе.
jar {
    manifest {
        attributes 'Main-Class': 'my.package.my.main.class'
    }

    configurations.compile.each {
        from(project.zipTree(it))
    }
}
  1. Второе решение — добавить параметры 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, пожалуйста, прочитайте этот вопрос:

Reference jars inside a jar

Другие вопросы по теме