Случайное исключение BeanCreationException в проекте загрузки Java Spring, построенном с помощью Gradle

#java #spring-boot #gradle

#java #spring-boot #gradle

Вопрос:

Иногда я получаю исключение BeanCreationException при запуске приложения Java Spring Boot с одним JAR, созданного Gradle. Мои исследования показывают, что это зависит от файла JAR и от того, как он был создан Gradle. Чаще всего (но не всегда) Я вижу исключение, когда я создаю проект в системе Linux. Но я никогда не воспроизводил проблему с JAR, созданным в Windows или при запуске из IntelliJ Idea.

Я попытался сравнить содержимое рабочего JAR с JAR, выдающим исключение — все файлы * .class (включая meta и ресурсы) были двоичными, разница заключалась только в порядке хранения файлов в JAR / ZIP-архиве. Я также попытался распаковать неисправный JAR в Windows и просто перепаковать его в новый файл JAR (используя 7-zip) — приложение запустилось без каких-либо исключений. Этот странный обходной путь решил проблему, но это не то, что я хотел бы делать после каждой сборки на компьютере с Linux.

Исключение предлагает проверять циклические ссылки, поэтому я попытался заменить свойства @Autowired на конструкторы @Autowired bean, чтобы помочь мне найти проблему, но это не помогло. В stacktrace не упоминается ни один из моих классов, поэтому я не знаю, какой компонент может быть ответственен за проблему. И из-за того, что проблема возникает только иногда и решается путем переупаковки файла JAR, я не уверен, что в любом случае есть какие-либо циклические ссылки.

Не могли бы вы мне помочь? Приветствуются любые советы или предложения.

JDK: openjdk 8u262 Gradle версии 5.6 Spring boot 2.3.1

Сообщение об исключении:

 BeanCreationException: Error creating bean with name 'webConfig':
Invocation of init method failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'requestMappingHandlerAdapter' defined in class path resource
[org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: 
Unsatisfied dependency expressed through method 'requestMappingHandlerAdapter' parameter 0;
nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'mvcContentNegotiationManager':
Requested bean is currently in creation: Is there an unresolvable circular reference?
  

Ответ №1:

По умолчанию Spring управляет жизненным циклом самого компонента, а затем упорядочивает порядок их инициализации во время запуска.

Вот полный пример использования аннотации @dependsOn для упорядочения создания экземпляра компонента.

Вы также можете найти более подробную информацию в официальной документации Spring

Комментарии:

1. Основной проблемой здесь является недетерминированное поведение. Иногда сборка выполняется нормально, и приложение запускается хорошо, иногда сборка создает JAR, который не может быть запущен из-за упомянутого исключения. Я хотел бы найти способ, как создать JAR с помощью gradle, который не будет путать Spring при создании зависимостей bean. Я всегда думал, что Spring сканирует зависимости детерминированным образом и не зависит от порядка файлов классов, но теперь я вижу, что это не так. Когда я распаковываю неисправный файл JAR, упорядочиваю файлы в алфавитном порядке и упаковываю их обратно, контекст Spring инициализируется правильно.