Spring JMS HornetQ 用户为空
Spring JMS HornetQ user is null
我正在尝试连接到 spring boot/spring jms 应用程序中的远程 HornetQ 代理并设置 @JmsListener
。
HornetQ ConnectionFactory
正在从 HornetQ 实例托管的 JNDI 注册表中获取。只要关闭 HornetQ 安全性,一切都可以正常工作,但是当它打开时,我会收到此错误
WARN o.s.j.l.DefaultMessageListenerContainer : Setup of JMS message listener invoker failed for destination 'jms/MI/Notification/Queue' - trying to recover. Cause: User: null doesn't have permission='CONSUME' on address jms.queue.MI/Notification/Queue
我 运行 一个调试会话来确定返回的 ConnectionFactory
实例是 HornetQXAConnectionFactory
但未设置用户和密码字段,我相信这就是用户为空的原因。我验证了用户主体和凭据是在 JNDI 属性中设置的,但不知何故它没有被传递到 ConnectionFactory 实例。非常感谢任何有关如何使此设置正常工作的帮助。
这是我的jms相关配置
@Configuration
@EnableJms
public class JmsConfig {
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
factory.setDestinationResolver(destinationResolver());
return factory;
}
@Bean // Serialize message content to json using TextMessage
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.BYTES);
converter.setTypeIdPropertyName("_type");
return converter;
}
@Value("${jms.jndi.provider.url}")
private String jndiProviderURL;
@Value("${jms.jndi.principal}")
private String jndiPrincipal;
@Value("${jms.jndi.credentials}")
private String jndiCredential;
@Bean
public JndiTemplate jndiTemplate() {
Properties env = new Properties();
env.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
env.put("java.naming.provider.url", jndiProviderURL);
env.put("java.naming.security.principal", jndiPrincipal);
env.put("java.naming.security.credentials", jndiCredential);
return new JndiTemplate(env);
}
@Bean
public DestinationResolver destinationResolver() {
JndiDestinationResolver destinationResolver = new JndiDestinationResolver();
destinationResolver.setJndiTemplate(jndiTemplate());
return destinationResolver;
}
@Value("${jms.connectionfactory.jndiname}")
private String connectionFactoryJNDIName;
@Bean
public JndiObjectFactoryBean connectionFactoryFactory() {
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiTemplate(jndiTemplate());
jndiObjectFactoryBean.setJndiName(connectionFactoryJNDIName);
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setProxyInterface(ConnectionFactory.class);
return jndiObjectFactoryBean;
}
@Bean
public ConnectionFactory connectionFactory(JndiObjectFactoryBean connectionFactoryFactory) {
return (ConnectionFactory) connectionFactoryFactory.getObject();
}
}
JNDI 和 JMS 是 100% 独立的,因为它们是完全不同的规范,以可能完全不同的方式实现。因此,您用于 JNDI 查找的凭据不适用于您的 JMS 资源。您需要在 JMS 连接上明确设置用户名和密码凭据。这很容易直接使用 JMS API(例如通过 javax.jms.ConnectionFactory#createConnection(String username, String password)
)。因为你使用的是 Spring 你可以使用这样的东西:
@Bean
public ConnectionFactory connectionFactory(JndiObjectFactoryBean connectionFactoryFactory) {
UserCredentialsConnectionFactoryAdapter cf = new UserCredentialsConnectionFactoryAdapter();
cf.setTargetConnectionFactory((ConnectionFactory) connectionFactoryFactory.getObject());
cf.setUsername("yourJmsUsername");
cf.setPassword("yourJmsPassword");
return cf;
}
另外,the HornetQ code-base was donated to the Apache ActiveMQ project three and a half years ago now and it lives on as the Apache ActiveMQ Artemis 经纪人,物有所值。从那时起已经发布了 22 个版本,其中包含许多新功能和错误修复。我强烈建议您尽可能迁移。
将连接工厂包装在 UserCredentialsConnectionFactoryAdapter
中。
/**
* An adapter for a target JMS {@link javax.jms.ConnectionFactory}, applying the
* given user credentials to every standard {@code createConnection()} call,
* that is, implicitly invoking {@code createConnection(username, password)}
* on the target. All other methods simply delegate to the corresponding methods
* of the target ConnectionFactory.
* ...
我正在尝试连接到 spring boot/spring jms 应用程序中的远程 HornetQ 代理并设置 @JmsListener
。
HornetQ ConnectionFactory
正在从 HornetQ 实例托管的 JNDI 注册表中获取。只要关闭 HornetQ 安全性,一切都可以正常工作,但是当它打开时,我会收到此错误
WARN o.s.j.l.DefaultMessageListenerContainer : Setup of JMS message listener invoker failed for destination 'jms/MI/Notification/Queue' - trying to recover. Cause: User: null doesn't have permission='CONSUME' on address jms.queue.MI/Notification/Queue
我 运行 一个调试会话来确定返回的 ConnectionFactory
实例是 HornetQXAConnectionFactory
但未设置用户和密码字段,我相信这就是用户为空的原因。我验证了用户主体和凭据是在 JNDI 属性中设置的,但不知何故它没有被传递到 ConnectionFactory 实例。非常感谢任何有关如何使此设置正常工作的帮助。
这是我的jms相关配置
@Configuration
@EnableJms
public class JmsConfig {
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
factory.setDestinationResolver(destinationResolver());
return factory;
}
@Bean // Serialize message content to json using TextMessage
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.BYTES);
converter.setTypeIdPropertyName("_type");
return converter;
}
@Value("${jms.jndi.provider.url}")
private String jndiProviderURL;
@Value("${jms.jndi.principal}")
private String jndiPrincipal;
@Value("${jms.jndi.credentials}")
private String jndiCredential;
@Bean
public JndiTemplate jndiTemplate() {
Properties env = new Properties();
env.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
env.put("java.naming.provider.url", jndiProviderURL);
env.put("java.naming.security.principal", jndiPrincipal);
env.put("java.naming.security.credentials", jndiCredential);
return new JndiTemplate(env);
}
@Bean
public DestinationResolver destinationResolver() {
JndiDestinationResolver destinationResolver = new JndiDestinationResolver();
destinationResolver.setJndiTemplate(jndiTemplate());
return destinationResolver;
}
@Value("${jms.connectionfactory.jndiname}")
private String connectionFactoryJNDIName;
@Bean
public JndiObjectFactoryBean connectionFactoryFactory() {
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiTemplate(jndiTemplate());
jndiObjectFactoryBean.setJndiName(connectionFactoryJNDIName);
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setProxyInterface(ConnectionFactory.class);
return jndiObjectFactoryBean;
}
@Bean
public ConnectionFactory connectionFactory(JndiObjectFactoryBean connectionFactoryFactory) {
return (ConnectionFactory) connectionFactoryFactory.getObject();
}
}
JNDI 和 JMS 是 100% 独立的,因为它们是完全不同的规范,以可能完全不同的方式实现。因此,您用于 JNDI 查找的凭据不适用于您的 JMS 资源。您需要在 JMS 连接上明确设置用户名和密码凭据。这很容易直接使用 JMS API(例如通过 javax.jms.ConnectionFactory#createConnection(String username, String password)
)。因为你使用的是 Spring 你可以使用这样的东西:
@Bean
public ConnectionFactory connectionFactory(JndiObjectFactoryBean connectionFactoryFactory) {
UserCredentialsConnectionFactoryAdapter cf = new UserCredentialsConnectionFactoryAdapter();
cf.setTargetConnectionFactory((ConnectionFactory) connectionFactoryFactory.getObject());
cf.setUsername("yourJmsUsername");
cf.setPassword("yourJmsPassword");
return cf;
}
另外,the HornetQ code-base was donated to the Apache ActiveMQ project three and a half years ago now and it lives on as the Apache ActiveMQ Artemis 经纪人,物有所值。从那时起已经发布了 22 个版本,其中包含许多新功能和错误修复。我强烈建议您尽可能迁移。
将连接工厂包装在 UserCredentialsConnectionFactoryAdapter
中。
/**
* An adapter for a target JMS {@link javax.jms.ConnectionFactory}, applying the
* given user credentials to every standard {@code createConnection()} call,
* that is, implicitly invoking {@code createConnection(username, password)}
* on the target. All other methods simply delegate to the corresponding methods
* of the target ConnectionFactory.
* ...