5
votes

What might be the cause of the following ClassCastException in a standalone JMS client application when it attempts to retrieve a connection factory from the JNDI provider?

Exception in thread "main" java.lang.ClassCastException: javax.naming.Reference cannot be cast to javax.jms.ConnectionFactory

Here is an abbreviated version of the JMS client that includes only its start() and stop() methods. The exception occurs on the first line in method start() which attempts to retrieve the connection factory from the JNDI provider, a remote LDAP server. The JMS connection factory and destination objects are on a remote JMS server.

class JmsClient {
    private ConnectionFactory connectionFactory;
    private Connection connection;
    private Session session;
    private MessageConsumer consumer;
    private Topic topic;

    public void stop() throws JMSException {
        consumer.close();
        session.close();
        connection.close();
    }

    public void start(Context context, String connectionFactoryName, String topicName) throws NamingException, JMSException {
        // ClassCastException occurs when retrieving connection factory.
        connectionFactory = (ConnectionFactory) context.lookup(connectionFactoryName);
        connection = connectionFactory.createConnection("username","password");
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        topic = (Topic) context.lookup(topicName);
        consumer = session.createConsumer(topic);
        connection.start();
    }

    private static Context getInitialContext() throws NamingException, IOException {
        String filename = "context.properties";
        Properties props = new Properties();
        props.load(new FileInputStream(filename));
        return new InitialContext(props);
    }
}

Though I prefer not to disclose the specific contents of context.properties, it contains the following general entries:

java.naming.factory.initial=...
java.naming.provider.url=...
java.naming.security.principal=...
java.naming.security.credentials=...
1
This depends entirely on which JavaEE server you're using. Also, what value are you using for connectionFactoryName?skaffman
This is a standalone Java client that uses Geronimo JMS client library geronimo-jms-1.1-spec.jar and a custom supplementary JMS library and a JNDI related library.Derek Mahar
contextFactoryName follows a custom syntax that maps to an entry in an LDAP server.Derek Mahar
@Bozho: Thank you for the reference. This problem does seem to be a general JNDI lookup problem and is not JMS specific.Derek Mahar

1 Answers

9
votes

Turns out that the problem was due to a Tibco JMS jarfile, tibjms.jar, being absent from the JVM classpath. This jarfile implements the Tibco JMS protocol and so because it was missing, the JMS client could not retrieve the JMS connection factory from the LDAP JNDI service provider.