Я находился в процессе обновления приложения Apache Tomcat 9.0.83 до 10.1.6-1.
Я разобрался с большинством изменений пространства имен Jakarta, но заметил, что Beans, внедренные с аннотацией @Service, недоступны.
Приложение у нас старое, поэтому большинство классов зарегистрированы через XML и работают. Однако те немногие, которые используют аннотации, недоступны.
Ресурсы, использующие @AutoWire, имеют значение null, и попытка явного получения компонента через aplicationContext.getBean("Foo")
приводит к следующей ошибке.
[ERROR] [Mon Apr 08 11:10:35.258 2024] [ajp-nio-127.0.0.1-8009-exec-2|BackupServiceImpl] Error: checking if chosen file name Backup-20244811:10 already exists for the host 127.0.0.1
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'FOO' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:893) ~[spring-beans-6.0.11.jar:6.0.11]
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1318) ~[spring-beans-6.0.11.jar:6.0.11]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) ~[spring-beans-6.0.11.jar:6.0.11]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.11.jar:6.0.11]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1155) ~[spring-context-6.0.11.jar:6.0.11]
at com.myCompany.AppContextUtil.getFoo(AppContextUtil.java:48) ~[myCompany-services-impl.jar:?]
Другие аннотации, такие как PostConstruct, работают.
Фу.класс:
import org.springframework.stereotype.Service;
@Service("Foo")
public class FooImpl extends FooIAbstract {
public FooImpl() {
}
}
В соответствии с верхним ответом на этот вопрос, проверяя наличие повторяющихся экземпляров jakarta.annotation.Resource, я нашел следующие два jar-файла, содержащие класс jakarta.annotation.Resource, и исключил его jakarta.annotation-api-2.0.0 .jar безуспешно.
~/eclipse-workspace09/DEVELOP_5_1_8_8_BRANCH/base/dist/usr/local/tomcat (DEVELOP_5_1_8_8_BRANCH)
$ find ./ -type f -iname '*.jar' | xargs grep --text --ignore-case --files-with-matches '.*jakarta.annotation.Resource.*'
./lib/jakarta.annotation-api-2.0.0.jar
./lib/tomcat-annotations-api-10.1.6.jar
В нашем предыдущем коде не было аннотации ComponentScan, поэтому я попытался добавить ее, но безрезультатно.
@ComponentScan("com.Company")
public class AppContextListener implements ServletContextListener, HttpSessionListener {
Если я добавлю определение XML в наш существующий файл applicationContent.xml, ошибок при попытке извлечь компонент по имени из контекста не возникнет.
<bean id = "Foo" class = "com.Company.FooImpl" lazy-init = "true">
</bean>
Соответствующие зависимости из основного pom.xml:
<org.springframework.version>6.0.11</org.springframework.version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${org.springframework.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>6.2.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${org.springframework.version}</version>
</dependency>
</dependencies>
@M.Deinum Да, мы уже обновились до Spring 6.x (и, возможно, еще что-то, включая спящий режим). Это одна из последних проблем, с которыми мы столкнулись.
Ошибка, вероятно, связана с вашей конфигурацией, поскольку я уже говорил, что ваш bean-компонент имеет имя Foo
и не foo
не уверен, является ли это копированием/вставкой или чем-то еще. Удаление jar-файлов — это не решение, а исправление вашей конфигурации. Добавьте полную трассировку стека и конфигурацию, в которой есть сканирование компонентов и т. д. Также добавьте свои зависимости (файл maven или файл gradle).
@M.Deinum Извините, «foo» было опечаткой при попытке очистить информацию. Благодарим вас за ваш вклад и предложенные правки.
@ComponentScan
находится не в том месте, он должен быть в классе @Configuration
. Вы также заявляете, что используете XML, поэтому там должен быть <context:component-scan />
.
Как отметил М. Дейнум в комментариях выше, добавление @Configuratio
решило эту проблему.
@Configuratio
@ComponentScan("com.Company")
public class AppContextListener implements ServletContextListener, HttpSessionListener {
Однако добавление <context:component-scan base-package = "com.mycompany"/>
сломало мое приложение.
Я совершенно не уверен, как это работало в Tomcat 9.
Далее чтение для всех, кто найдет это в будущем.
Ваш компонент называется
Foo
, а неfoo
. При этом вы не можете просто обновить Tomcat, вам также потребуется обновить Spring до версии 6.x, иначе это не будет работать. Другие версии несовместимы с Tomcat 10 (или, скорее, с JakartaEE).