Hey Guys,
I was recently introduced to Solace and am trying to deploy a sample Pub/Sub application using JMS API on a local Weblogic server but ran into this class cast error which I cant seem to find a solution for.
I have created a topic “MyTopic” which is subscribed by a queue, “MyQueue” and also configured the JNDI names and message_vpn settings on Solace Web Console as per requirement. Then I deployed a Resource Adapter jar on my local weblogic server with the necessary Connection Factory and other credentials. So the setup so far is:
At Solace → MyVpn:
“JNDI/Sol/mytopic” has physical name “MyTopic”
“JNDI/Sol/myqueue” has physical name “MyQueue”
At Weblogic, the Connection Factory and Destination configurations in “weblogic-ra.xml” file (apart from user credentials, url, etc.) are as follows:
<admin-objects>
<admin-object-group>
<admin-object-interface>javax.jms.Queue</admin-object-interface>
<admin-object-instance>
<jndi-name>JNDI/J2C/my/queue</jndi-name>
<properties>
<property>
<name>Destination</name>
<value>JNDI/Sol/myqueue</value>
</property>
</properties>
</admin-object-instance>
</admin-object-group>
<admin-object-group>
<admin-object-interface>javax.jms.Topic</admin-object-interface>
<admin-object-instance>
<jndi-name>JNDI/J2C/my/topic</jndi-name>
<properties>
<property>
<name>Destination</name>
<value>JNDI/Sol/mytopic</value>
</property>
</properties>
</admin-object-instance>
</admin-object-group>
</admin-objects>
<outbound-resource-adapter>
<connection-definition-group>
<connection-factory-interface>javax.jms.ConnectionFactory</connection-factory-interface>
<connection-instance>
<jndi-name>JNDI/J2C/CF</jndi-name>
<connection-properties>
<transaction-support>NoTransaction</transaction-support>
<properties>
<property>
<name>ConnectionFactoryJndiName</name>
<value>JNDI/Sol/CF</value>
</property>
<property>
<name>ConnectionValidationEnabled</name>
<value>true</value>
</property>
</properties>
</connection-properties>
</connection-instance>
</connection-definition-group>
</outbound-resource-adapter>
At the application level, I have created a EJB project with a consumer MDB that tries to read messages published on “MyTopic” by a separate Producer Java application. The code is as follows:
[ConsumerMDB.java]
package com.solace.ejb;
import java.util.Hashtable;
import javax.ejb.MessageDriven;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
@MessageDriven
public class ConsumerMDB implements MessageListener {
private final String QUEUE_JNDI_NAME = "JNDI/J2C/my/queue";
private final String CONNECTION_FACTORY_JNDI_NAME = "JNDI/J2C/CF";
public void onMessage(Message message) {
if (message instanceof TextMessage) {
try {
TextMessage textMessage = (TextMessage) message;
System.out.println("Received message: " + textMessage.getText());
message.acknowledge();
}
catch (JMSException e) {
e.printStackTrace();
}
}
}
public void initialize() throws NamingException {
try {
Hashtable<String, Object> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
InitialContext initialContext = new InitialContext(env);
ConnectionFactory connectionFactory = (ConnectionFactory) initialContext.lookup(CONNECTION_FACTORY_JNDI_NAME);
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(QUEUE_JNDI_NAME);
MessageConsumer consumer = (MessageConsumer) session.createConsumer(queue);
consumer.setMessageListener(this);
connection.start();
Thread.sleep(10000);
} catch (JMSException | InterruptedException e) {
e.printStackTrace();
}
}
public void cleanup() {
try {
if (messageConsumer != null) {
messageConsumer.close();
}
if (session != null) {
session.close();
}
if (connection != null) {
connection.close();
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
[ejb-jar.xml]
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd"
version="3.2">
<enterprise-beans>
<message-driven>
<ejb-name>ConsumerMDB</ejb-name>
<ejb-class>com.solace.ejb.ConsumerMDB</ejb-class>
</message-driven>
</enterprise-beans>
</ejb-jar>
[weblogic-ejb-jar.xml]
<?xml version='1.0' encoding='UTF-8'?>
<weblogic-ejb-jar xmlns="http://xmlns.oracle.com/weblogic/weblogic-ejb-jar"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-ejb-jar
http://xmlns.oracle.com/weblogic/weblogic-ejb-jar/1.0/weblogic-ejb-jar.xsd ">
<weblogic-enterprise-bean>
<ejb-name>ConsumerMDB</ejb-name>
<message-driven-descriptor>
<destination-jndi-name>JNDI/J2C/my/queue</destination-jndi-name>
</message-driven-descriptor>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
Now when I am deploying this consumer jar on MyServer I am getting this error without the flow even reaching my code (which might as well be flawed):
<The Message-Driven EJB ConsumerMDB is unable to connect to the JMS destination or bind to JCA resource adapter JNDI/J2C/my/queue. The connection failed after 2 attempts. The MDB will attempt to reconnect/rebind every 10 seconds. This log message wil<The Message-Driven EJB ConsumerMDB is unable to connect to the JMS destination JNDI/J2C/my/queue. The Error was:
java.lang.ClassCastException: com.solacesystems.jms.ra.outbound.QueueProxy cannot be cast to weblogic.jms.common.DestinationImplStack Trace for RuntimeException was:java.lang.ClassCastException: com.solacesystems.jms.ra.outbound.QueueProxy cannot be cast to weblogic.jms.common.DestinationImpl
at weblogic.jms.client.JMSSession.createConsumer(JMSSession.java:2882)
at weblogic.jms.client.JMSSession.createConsumer(JMSSession.java:2860)
at weblogic.jms.client.JMSSession.createReceiver(JMSSession.java:2766)
I am new to this framework and might have possibly messed up on the configuration or maybe even approaching it incorrectly.
However, any help or guidance from the fellow community members on what is going wrong here is greatly appreciated. Thanks.