spring-boot - Spring Boot 向 Weblogic JMS 队列发送消息失败,“weblogic.messaging.dispatcher.DispatcherImpl 未导出,或者实际上是 JRMP 存根”
问题描述
我正在使用Spring Boot(2.5.0)开发一种适用于任何 JMS 提供程序的 JMS Sender 框架(支持 Java MOM 也应该重用连接工厂)。为此,我所做的是我刚刚在服务器启动期间创建了一个 bean,它保留了所有初始上下文和连接工厂。因此,每当调用 JMS Sender(MyCode) 时,它实际上需要一些参数队列/主题和上下文名称并找到正确的 JMS 连接工厂(最初在服务器启动期间加载)并使用 JMSTemplate 发送消息。它可以正常工作,但是当 JMS 服务器出现故障时,JMS 发送方会抛出此异常 jercorba。DEFAULT .rpc.encoding:“IOP00500001:(INV_OBJREF)未指定 wchar 代码集支持”org.omg.CORBA.INV_OBJREF: IOP01210228:(BAD_OPERATION)此 ORB 实例已被销毁,因此无法对其执行任何操作“
但是当 JMS 服务器重新启动时,我再次尝试使用我的 JMS 发送方代码发布一些消息,这次我检查是否存在 JMSException,如果有,那么首先我重置连接,然后关闭初始上下文,然后重新创建 InitialContext 和 ConnectionFactory并使用新创建的连接工厂进行进一步的消息发布。但问题是当我使用新创建的连接工厂时,我得到了以下异常。这似乎是从Weblogic12c JMS 服务器端发生的。我需要一些指针来解决这个问题,即使任何可以帮助我调试这个问题的输入也是受欢迎的。
j.e.resource.corba._CORBA_.util : IOP00511403: (INV_OBJREF) Class weblogic.messaging.dispatcher.DispatcherImpl not exported, or else is actually a JRMP stub org.omg.CORBA.INV_OBJREF:
at com.sun.corba.se.impl.logging.UtilSystemException.objectNotExported(UtilSystemException.java:507) [na:1.8.0_221]
at com.sun.corba.se.impl.logging.UtilSystemException.objectNotExported(UtilSystemException.java:530) [na:1.8.0_221]
at com.sun.corba.se.impl.util.Utility.autoConnect(Utility.java:158) [na:1.8.0_221]
at com.sun.corba.se.impl.javax.rmi.CORBA.Util.writeAbstractObject(Util.java:470) [na:1.8.0_221]
at javax.rmi.CORBA.Util.writeAbstractObject(Util.java:159) [na:1.8.0_221]
at com.sun.corba.se.impl.io.IIOPOutputStream.writeObjectOverride(IIOPOutputStream.java:153) [na:1.8.0_221]
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344) [na:1.8.0_221]
at weblogic.messaging.dispatcher.DispatcherWrapper.writeExternal(DispatcherWrapper.java:156) [classes/:na]
at weblogic.jms.frontend.FEConnectionCreateRequest.writeExternal(FEConnectionCreateRequest.java:98) [classes/:na]
at com.sun.corba.se.impl.io.IIOPOutputStream.outputObject(IIOPOutputStream.java:554) [na:1.8.0_221]
at com.sun.corba.se.impl.io.IIOPOutputStream.simpleWriteObject(IIOPOutputStream.java:174) [na:1.8.0_221]
at com.sun.corba.se.impl.io.ValueHandlerImpl.writeValueInternal(ValueHandlerImpl.java:236) [na:1.8.0_221]
at com.sun.corba.se.impl.io.ValueHandlerImpl.writeValueWithVersion(ValueHandlerImpl.java:218) [na:1.8.0_221]
at com.sun.corba.se.impl.io.ValueHandlerImpl.writeValue(ValueHandlerImpl.java:150) [na:1.8.0_221]
at com.sun.corba.se.impl.encoding.CDROutputStream_1_0.writeRMIIIOPValueType(CDROutputStream_1_0.java:807) [na:1.8.0_221]
at com.sun.corba.se.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:856) [na:1.8.0_221]
at com.sun.corba.se.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:870) [na:1.8.0_221]
at com.sun.corba.se.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:665) [na:1.8.0_221]
at com.sun.corba.se.impl.encoding.CDROutputStream.write_value(CDROutputStream.java:250) [na:1.8.0_221]
at weblogic.jms.frontend._FEConnectionFactoryRemote_Stub.connectionCreateRequest(Unknown Source) [classes/:na]
at weblogic.jms.client.JMSConnectionFactory.setupJMSConnection(JMSConnectionFactory.java:224) [classes/:na]
at weblogic.jms.client.JMSConnectionFactory.createConnectionInternal(JMSConnectionFactory.java:285) [classes/:na]
at weblogic.jms.client.JMSConnectionFactory.createConnection(JMSConnectionFactory.java:191) [classes/:na]
at org.springframework.jms.connection.SingleConnectionFactory.doCreateConnection(SingleConnectionFactory.java:410) [spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.connection.SingleConnectionFactory.initConnection(SingleConnectionFactory.java:350) [spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.connection.SingleConnectionFactory.getConnection(SingleConnectionFactory.java:328) [spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.connection.SingleConnectionFactory.createConnection(SingleConnectionFactory.java:243) [spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:196) [spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:494) [spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:576) [spring-jms-5.3.6.jar:5.3.6]
at com.yc.common.jms.YCJmsSender.sendToQueue(YCJmsSender.java:43) [classes/:na]
at com.yc.module.item.event.listener.CreateItemSuccessListener.onApplicationEvent(CreateItemSuccessListener.java:38) [classes/:na]
at com.yc.module.item.event.listener.CreateItemSuccessListener.onApplicationEvent(CreateItemSuccessListener.java:1) [classes/:na]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) [spring-context-5.3.6.jar:5.3.6]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) [spring-context-5.3.6.jar:5.3.6]
at org.springframework.context.event.SimpleApplicationEventMulticaster.lambda$multicastEvent$0(SimpleApplicationEventMulticaster.java:140) [spring-context-5.3.6.jar:5.3.6]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_221]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_221]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_221]
Exception in thread getThreadPoolTaskExecutor-3 java.util.MissingResourceException: No localizer class found for message id.
at weblogic.i18ntools.L10nLookup.getLocalizer(L10nLookup.java:310)
at weblogic.i18ntools.L10nLookup.getLocalizer(L10nLookup.java:261)
at weblogic.i18n.logging.Loggable.getMessage(Loggable.java:187)
at weblogic.i18n.logging.Loggable.getMessage(Loggable.java:211)
at weblogic.jms.common.JMSException.<init>(JMSException.java:66)
at weblogic.jms.client.JMSConnectionFactory.setupJMSConnection(JMSConnectionFactory.java:258)
at weblogic.jms.client.JMSConnectionFactory.createConnectionInternal(JMSConnectionFactory.java:285)
at weblogic.jms.client.JMSConnectionFactory.createConnection(JMSConnectionFactory.java:191)
at org.springframework.jms.connection.SingleConnectionFactory.doCreateConnection(SingleConnectionFactory.java:410)
at org.springframework.jms.connection.SingleConnectionFactory.initConnection(SingleConnectionFactory.java:350)
at org.springframework.jms.connection.SingleConnectionFactory.getConnection(SingleConnectionFactory.java:328)
at org.springframework.jms.connection.SingleConnectionFactory.createConnection(SingleConnectionFactory.java:243)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:196)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:494)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:576)
at com.yc.common.jms.YCJmsSender.sendToQueue(YCJmsSender.java:43)
at com.yc.module.item.event.listener.CreateItemSuccessListener.onApplicationEvent(CreateItemSuccessListener.java:38)
at com.yc.module.item.event.listener.CreateItemSuccessListener.onApplicationEvent(CreateItemSuccessListener.java:1)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
at org.springframework.context.event.SimpleApplicationEventMulticaster.lambda$multicastEvent$0(SimpleApplicationEventMulticaster.java:140)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
注意:现在我正在为任何 JMS 异常重新创建 JMS 连接工厂,一旦我解决了这个问题,我将重构这个代码
弹簧配置
public class JmsConfig {
@Autowired
private Environment environment;
@Bean
public YCJmsConfigLoader ycJmsContextLoader() throws NamingException, JMSException {
return new YCJmsConfigLoader(environment);
}
public void resetConectionFactory(String contextName) throws NamingException, JMSException {
YCJmsConfigLoader configLoader = ycJmsContextLoader();
configLoader.resetConnectionFactory(environment,contextName);
}
@Bean
@Scope(value = "prototype")
public Destination destination(@Valid YCDestinationDtl ycDestinationDtl) throws NamingException, JMSException {
try {
Destination destination = (Destination) ycJmsContextLoader()
.getYcJmsConnnectionDtlsmap()
.get(ycDestinationDtl.getContextName())
.getInitialContext()
.lookup(ycDestinationDtl.getDestinationName());
return destination;
}catch(NamingException ex) {
resetConectionFactory(ycDestinationDtl.getContextName());
throw new RuntimeException(ex);
}
}
@Bean
@Scope(value = "prototype")
public JmsSender ycJmsSender() {
return new YCJmsSender();
}
@Bean
@Scope(value = "prototype")
public JmsTemplate jmsTemplate(String contextName,boolean isTopicTemplate) throws NamingException, JMSException {
JmsTemplate jmsTemplate = new JmsTemplate(ycJmsContextLoader().getYcJmsConnnectionDtlsmap().get(contextName).getCachingConnectionFactory());
if(isTopicTemplate)
{
jmsTemplate.setPubSubDomain(true);
}
else{
jmsTemplate.setPubSubDomain(false);
}
return jmsTemplate;
}
}
服务器启动期间的 JMS 连接配置加载器 Util
public class YCJmsConfigLoader {
private Map<String,YCJmsConfig> ycJmcConDtlsmap;
public Map<String,YCJmsConfig> getYcJmsConnnectionDtlsmap() {
return ycJmcConDtlsmap;
}
public YCJmsConfigLoader(Environment environment) throws NamingException, JMSException {
super();
String contextNameList = environment.getProperty("yc.jms.context.name.list"); //comma separated
String[] contxtNameArray = contextNameList.split(",");
for (String contextName : contxtNameArray) {
if(null==getYcJmsConnnectionDtlsmap()) {
this.ycJmcConDtlsmap = new HashMap<String, YCJmsConfig>();
}
if(environment.getProperty(contextName+".load") == null
|| "Y".equalsIgnoreCase(environment.getProperty(contextName+".load"))) {
this.ycJmcConDtlsmap.put(contextName,new YCJmsConfig(contextName,environment));
}
}
}
public void resetConnectionFactory(Environment environment, String contextName) throws NamingException, JMSException {
if(this.getYcJmsConnnectionDtlsmap().containsKey(contextName)) {
YCJmsConfig ycJmsConfig = this.getYcJmsConnnectionDtlsmap().get(contextName);
try {
ycJmsConfig.getCachingConnectionFactory().resetConnection();
ycJmsConfig.getInitialContext().close();
}finally {
if(environment.getProperty(contextName+".load") == null
|| "Y".equalsIgnoreCase(environment.getProperty(contextName+".load"))) {
this.getYcJmsConnnectionDtlsmap().put(contextName,new YCJmsConfig(contextName,environment));
}
}
}
}
}
JMS 连接配置持有者
public class YCJmsConfig {
private String contextName;
private String initialContextPropName;
private String initialContextPropValue;
private String providerURLPropName;
private String providerURLPropValue;
private String connectionFactoryPropName;
private String connectionFactoryPropValue;
private InitialContext initialContext;
private ConnectionFactory connectionFactory;
private Environment environment;
private CachingConnectionFactory cachingConnectionFactory;
public YCJmsConfig(String contextName, Environment environment) throws NamingException, JMSException {
super();
this.environment = environment;
setContextName(contextName);
setInitialContextProp();
setProviderURLPropName();
setProviderURLPropValue();
setConnectionFactoryPropName();
setConnectionFactoryPropValue();
setInitialContext();
setConnectionFactory();
setCachingConnectionFactory();
}
private void setInitialContextProp() {
setInitialContextPropName();
setInitialContextPropValue();
}
private void setCachingConnectionFactory() throws JMSException {
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
cachingConnectionFactory.setTargetConnectionFactory(getConnectionFactory());
cachingConnectionFactory.setSessionCacheSize(5);
cachingConnectionFactory.setCacheProducers(false);
this.cachingConnectionFactory = cachingConnectionFactory;
}
private void setConnectionFactory() throws NamingException {
this.connectionFactory = (ConnectionFactory) getInitialContext().lookup(getConnectionFactoryPropValue());
}
public String getConnectionFactoryPropName() {
return connectionFactoryPropName;
}
public void setConnectionFactoryPropName() {
this.connectionFactoryPropName = getContextName()+".connection.factory";
}
public String getConnectionFactoryPropValue() {
return connectionFactoryPropValue;
}
public void setConnectionFactoryPropValue() {
this.connectionFactoryPropValue = getEnvironment().getProperty(getConnectionFactoryPropName());
}
private void setProviderURLPropValue() {
this.providerURLPropValue = getEnvironment().getProperty(getProviderURLPropName());
}
private void setProviderURLPropName() {
this.providerURLPropName = getContextName()+".naming.provider.url";
}
public String getProviderURLPropName() {
return providerURLPropName;
}
public void setProvderURLPropName(String provderURLPropName) {
this.providerURLPropName = provderURLPropName;
}
public String getProvderURLPropValue() {
return providerURLPropValue;
}
public void setProvderURLPropValue(String provderURLPropValue) {
this.providerURLPropValue = provderURLPropValue;
}
private void setContextName(String contextName) {
this.contextName = contextName;
}
public void setInitialContext() throws NamingException{
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, getInitialContextPropValue());
env.put(Context.PROVIDER_URL, getProvderURLPropValue());
//env.put(Context.SECURITY_PRINCIPAL, );
//env.put(Context.SECURITY_CREDENTIALS, );
this.initialContext = new InitialContext(env);
}
public String getInitialContextPropName() {
return initialContextPropName;
}
public void setInitialContextPropName() {
this.initialContextPropName = getContextName() + ".naming.factory.initial";
}
public String getInitialContextPropValue() {
return initialContextPropValue;
}
public void setInitialContextPropValue() {
this.initialContextPropValue = getEnvironment().getProperty(getInitialContextPropName());
}
public String getContextName() {
return contextName;
}
public InitialContext getInitialContext() {
return initialContext;
}
public ConnectionFactory getConnectionFactory() {
return connectionFactory;
}
public CachingConnectionFactory getCachingConnectionFactory() {
return cachingConnectionFactory;
}
public Environment getEnvironment() {
return environment;
}
}
用于发送消息的 JMS Sender
public class YCJmsSender implements JmsSender{
@Autowired
private YCJmsConfigLoader ycContextLoader;
@Autowired
private BeanFactory beanFactory;
@Autowired
private Environment environemnt;
@Autowired
private final ObjectMapper mapper = new ObjectMapper();
@Override
public void sendToQueue(String contextName, String queueName, String queueJmsPropPrefix, Object object) {
try {
getJmsTemplate(contextName,false).send(getQueue(contextName,queueName)
, createYCJmsMessage(getYCJmsMessage(mapper.valueToTree(object))
, queueJmsPropPrefix));
}catch(JmsException ex) {
try {
ycContextLoader.resetConnectionFactory(this.environemnt, contextName);
} catch (NamingException|JMSException e) {
new RuntimeException(e);
}
throw new RuntimeException(ex);
}
}
private JmsTemplate getJmsTemplate(String contextName, boolean isTopicTemplate) {
return beanFactory.getBean(JmsTemplate.class, contextName,false);
}
private Destination getQueue(String contextName, String queueName) {
return (Queue) beanFactory.getBean(Destination.class, new YCDestinationDtl(contextName,queueName));
}
@Override
public void sendToTopic(String contextName, String topicName, String topicJmsPropPrefix, Object object) {
Topic topic = (Topic) beanFactory.getBean(Destination.class, new YCDestinationDtl(contextName,topicName));
getJmsTemplate(contextName,true).send(topic, createYCJmsMessage(getYCJmsMessage(mapper.valueToTree(object)),topicJmsPropPrefix));
}
private @NotBlank JsonNode getYCJmsMessage(JsonNode jsonMessage) {
YCJmsMessageModel jmsMessage = new YCJmsMessageModel(new Date(), jsonMessage, "YCJmsSender");
JsonNode jsonNode = mapper.valueToTree(jmsMessage);
return jsonNode;
}
private void setMessageProperties(String jmsMsgPropPrefix,Message message) throws JMSException {
int priority = Integer.parseInt(environemnt.getProperty(jmsMsgPropPrefix+".jms.priority", "0"));
message.setJMSPriority(priority);
String messageType = environemnt.getProperty(jmsMsgPropPrefix+".jms.type", "");
message.setJMSType(messageType);
String headerName = environemnt.getProperty(jmsMsgPropPrefix+".header.name", "DEFAULT");
String headerValue = environemnt.getProperty(jmsMsgPropPrefix+".header.value", "DEFAULT");
message.setStringProperty(headerName, headerValue);
}
public MessageCreator createYCJmsMessage(JsonNode jsonMessage, @NotBlank String jmsPropPrefix) {
MessageCreator messageCreator = new MessageCreator() {
@Id
private String id;
@Override
public Message createMessage(Session session) throws JMSException {
TextMessage message = session.createTextMessage(jsonMessage.toString());
message.setJMSMessageID(this.id);
setMessageProperties(jmsPropPrefix,message);
return message;
}
};
return messageCreator;
}
}
解决方案
推荐阅读
- c++ - 为什么对于简单的单个字符识别,我从 Tesseract 得到如此糟糕的结果?
- r - Mongolite 未将带有列表列的数据框正确插入 Mongo DB
- azure - 持久函数异常:“找不到用于此绑定的 Azure 存储连接字符串。”
- sas - 动态 SAS 宏变量
- javascript - 将一个 javascript 文件中评估的敏感变量值传递给另一个 javascript 文件
- .net - 本地数据库、实体框架和 WinForms
- java - 如何使用 PrintWriter 从路径创建丢失的文件夹?
- sql-server - sum(isnull(DB.budget_amount,0)) OVER(Partition by DB.ACCOUNT)as YearTotalBudget (将这一行添加到 group by 会导致问题)
- ios - IOS 12中sqlite文件的位置在哪里?
- ajax - 在 Apache 服务器上启用 ssl 后,AJAX POST 请求出现错误 301