Spring-Boot executable JAR

Читаю Spring Boot Reference Documentation. Дошел до раздела, где предлагается создать исполняемый файл JAR. Не получается. Проект запускается из IDE, а через командную строку java -jar <name> сыпятся ошибки.

Использую IntelliJ IDEA 2022.1 + Gradle.

UPD. В ответ на комментарий добавляю лог ошибки:

00:28:13.394 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: No ServletContext set
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
    at MainKt.main(Main.kt:4)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: No ServletContext set
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
    ... 18 common frames omitted
Caused by: java.lang.IllegalStateException: No ServletContext set
    at org.springframework.util.Assert.state(Assert.java:76)
    at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.resourceHandlerMapping(WebMvcConfigurationSupport.java:591)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 19 common frames omitted

Process finished with exit code 1

Но фактически тут проблема с созданием рабочего JAR-файла, и вопрос адресован в первую очередь тем, у кого получилось это сделать для проекта SpringBoot.

UPD2. Файл build.gradle.kts (безуспешно пробовал несколько мануалов, поэтому сюда публикую таким, какой он был - без изменений):

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.6.20"
    application
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web:2.6.7")
    testImplementation(kotlin("test"))
}

tasks.test {
    useJUnitPlatform()
}

tasks.withType<KotlinCompile> {
    kotlinOptions.jvmTarget = "1.8"
}

application {
    mainClass.set("MainKt")
}

JAR создаю средствами IntelliJ IDEA, через командную строку не пробовал.


Ответы (2 шт):

Автор решения: he1ex-tG

В общем вопрос частично решен. Вот, что мне удалось выяснить.

Сначала исходные данные. Я создал на сайте start.spring.io образ, в который добавил в зависимости только Spring Web. Скачал, открыл в IntelliJ IDEA. Запустил проект. Все работает. Теперь пришло время создать артефакт (запускаемый через java -jar файл): File -> Project Structure -> Artifacts -> + -> JAR -> From module with dependencies... -> Choose main class -> ОК. После этого Build -> Build Artifacts -> Build/Rebuild. В директории (по умолчанию {project root}\out\artifacts\{project name}) создался JAR-файл. При запуске через java -jar {этот файл} программа закрывается с ошибкой. Весь парадокс в том, что я не написал ни одной строчки кода. Пустой по сути проект, который отлично работает из IDE, не запускается в виде отдельного файла. Как это победить, я так и не понял, к сожалению.

Однако получить работающий JAR мне удалось. 2 пути, которые, по своей сути, делают одно и то же:

  1. Ctrl+E (в Windows) -> Gradle. В открывшемся (по умолчанию справа) окне выбрать Tasks -> build -> build.
  2. В командной строке в корневой директории проекта выполнить .\gradle build

Оба варианта создадут JAR-файлы в директории (по умолчанию) {project root}\build\libs. Они отлично запускаются при помощи java -jar.

Вопрос вроде бы решен, но почему артефакт нормально не создается через Build Artefact осталось загадкой.

→ Ссылка
Автор решения: Roman-Stop RU aggression in UA

Процедура создания выполнимого jar для spring boot очень нетривиальна (тут можно почить https://docs.spring.io/spring-boot/docs/current/reference/html/executable-jar.html). intellij не умеет делать такой jar сама, нужно пользоваться плагином к gradle или mvn.

Чтоб не нужно было покидать IDE добавьте себе конфигурацию на запуск gradle задачи. Для этого идите в меню Run -> Edit Configurations. Далее слева в дереве выбирайте Gradle и добавляйте новую конфигурацию плюсиком

добавление конфигурации

Далее задайте имя конфигурации, выберите корневой проект gradle и укажите название задачи (это может быть та, которую вы запускали из командной строки - build так и более специализированная - bootJar:

добавление gradle задачи

После сохранения запускать можно с панели инструметов:

запуск задачи

или из меню Run -> Run....

→ Ссылка