Spring-boot + mail/Session JNDI 资源 = NoSuchBeanDefinitionException (JavaMailSender)
Spring-boot + mail/Session JNDI resource = NoSuchBeanDefinitionException (JavaMailSender)
我已经为 mail/Session 配置为 JNDI 资源(在 Tomcat 端声明)而苦苦挣扎了几天(没有任何进展),将被拾起通过 spring-boot 应用程序。这个想法是为了避免在应用程序中包含任何关键信息,例如 user/password 数据。
(注意 1:通过 SMTP 的凭据和连接已经过测试,具有应用程序端配置,硬编码在 application.properties 中,因此这不是问题)。
我当前使用的配置如下:
server.xml ($TOMCAT/conf)
<Resource
name="mail/Session"
auth="Container"
type="javax.mail.Session"
username="user@test.com"
password="XXX"
mail.user="user@test.com"
mail.password="XXX"
mail.transport.protocol="smtp"
mail.smtp.host="smtp.test.com"
mail.smtp.auth="true"
mail.smtp.port="587"/>
context.xml (webapp/META-INF)
<Context>
<ResourceLink
name="mail/Session"
global="mail/Session"
auth="Container"
type="javax.mail.Session"/>
</Context>
application.properties
spring.mail.jndi-name=java:comp/env/mail/Session
在 pom.xml 我有 spring-boot-starter-mail
依赖(以及其他必要的依赖)。我在其中输入 JavaMailSender
bean 的 class 是这个(简化):
(注意 2: 使用的 spring-boot 版本是 1.2.8.RELEASE)
@Service("emailService")
public class EmailService {
@Autowired
public JavaMailSender javaMailSender;
public void sendSimpleMail(/* ... */) throws MessagingException {
//Create message
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setFrom(fromAddress);
helper.setTo(toAddress);
helper.setSubject(subject);
helper.setText(body);
//Send message
javaMailSender.send(message);
}
}
我知道 spring-boot 自动配置应该在找到 jndiName 或主机、端口、用户名、密码后创建 JavaMailSender bean...spring.mail properties(当我设置主机时,后者会起作用,端口,用户名和密码 application.properties),但是当我使用 jndiName 选项时它会抛出以下堆栈:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'emailService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public org.springframework.mail.javamail.JavaMailSender com.testapp.service.EmailService.javaMailSender; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSender] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1208)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:690)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
at org.springframework.boot.context.web.SpringBootServletInitializer.run(SpringBootServletInitializer.java:135)
at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:126)
at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:82)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5240)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
... 10 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public org.springframework.mail.javamail.JavaMailSender com.testapp.service.EmailService.javaMailSender; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSender] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 29 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSender] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 31 more
我以同样的方式将数据源配置为 JNDI 资源,并且它运行良好。 (mail)Session 是否需要不同的方法,或者我是否遗漏了它的配置?
正如 @m-deinum 在评论中指出的那样,问题不在于配置,而是 spring-boot 1.3.x[= 下的版本缺少 JNDI 支持11=]
为了解决这个问题,我最终听取了@m-deinum的提示并将spring-boot从1.2.8升级到1.3.5。 .. 处理一些已弃用的 类 和新配置并准备就绪!
我已经为 mail/Session 配置为 JNDI 资源(在 Tomcat 端声明)而苦苦挣扎了几天(没有任何进展),将被拾起通过 spring-boot 应用程序。这个想法是为了避免在应用程序中包含任何关键信息,例如 user/password 数据。
(注意 1:通过 SMTP 的凭据和连接已经过测试,具有应用程序端配置,硬编码在 application.properties 中,因此这不是问题)。
我当前使用的配置如下:
server.xml ($TOMCAT/conf)
<Resource
name="mail/Session"
auth="Container"
type="javax.mail.Session"
username="user@test.com"
password="XXX"
mail.user="user@test.com"
mail.password="XXX"
mail.transport.protocol="smtp"
mail.smtp.host="smtp.test.com"
mail.smtp.auth="true"
mail.smtp.port="587"/>
context.xml (webapp/META-INF)
<Context>
<ResourceLink
name="mail/Session"
global="mail/Session"
auth="Container"
type="javax.mail.Session"/>
</Context>
application.properties
spring.mail.jndi-name=java:comp/env/mail/Session
在 pom.xml 我有 spring-boot-starter-mail
依赖(以及其他必要的依赖)。我在其中输入 JavaMailSender
bean 的 class 是这个(简化):
(注意 2: 使用的 spring-boot 版本是 1.2.8.RELEASE)
@Service("emailService")
public class EmailService {
@Autowired
public JavaMailSender javaMailSender;
public void sendSimpleMail(/* ... */) throws MessagingException {
//Create message
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setFrom(fromAddress);
helper.setTo(toAddress);
helper.setSubject(subject);
helper.setText(body);
//Send message
javaMailSender.send(message);
}
}
我知道 spring-boot 自动配置应该在找到 jndiName 或主机、端口、用户名、密码后创建 JavaMailSender bean...spring.mail properties(当我设置主机时,后者会起作用,端口,用户名和密码 application.properties),但是当我使用 jndiName 选项时它会抛出以下堆栈:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'emailService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public org.springframework.mail.javamail.JavaMailSender com.testapp.service.EmailService.javaMailSender; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSender] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1208)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:690)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
at org.springframework.boot.context.web.SpringBootServletInitializer.run(SpringBootServletInitializer.java:135)
at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:126)
at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:82)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5240)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
... 10 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public org.springframework.mail.javamail.JavaMailSender com.testapp.service.EmailService.javaMailSender; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSender] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 29 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSender] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 31 more
我以同样的方式将数据源配置为 JNDI 资源,并且它运行良好。 (mail)Session 是否需要不同的方法,或者我是否遗漏了它的配置?
正如 @m-deinum 在评论中指出的那样,问题不在于配置,而是 spring-boot 1.3.x[= 下的版本缺少 JNDI 支持11=]
为了解决这个问题,我最终听取了@m-deinum的提示并将spring-boot从1.2.8升级到1.3.5。 .. 处理一些已弃用的 类 和新配置并准备就绪!