I've been trying to switch our project from running on JBoss 3.2.1 to 3.2.2 and some messaging code that worked on 3.2.1 wouldn't work anymore with 3.2.2. I've included a sample java source file we use to browse remote JBoss JMS queues, using two 3.2.1 instances on different machines, I'm able to browse remote queues from any machine. If I have 3.2.1 on machine A and 3.2.2 on machine B and try to run the queue browser on A like this:
java QueueBrowserX -s=B -q=someQueue from ant I'd get the following strange exception (output slightly edited to protect the innocent):
qbrowser:
[qbrowse] {-s=B, -q=fromCAReqQueue, -p=http}
[qbrowse] log4j:WARN No appenders could be found for logger (org.jboss.naming.HttpNamingContextFactory).
[qbrowse] log4j:WARN Please initialize the log4j system properly.
[qbrowse] javax.naming.NamingException: Failed to retrieve Naming interface [Root exception is java.lang.ClassNotFoundException: org.jboss.naming.interceptors.ExceptionInterceptor]
[qbrowse] at org.jboss.naming.HttpNamingContextFactory.getInitialContext(HttpNamingContextFactory.java:68)
[qbrowse] at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
[qbrowse] at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:243)
[qbrowse] at javax.naming.InitialContext.init(InitialContext.java:219)
[qbrowse] at javax.naming.InitialContext.<init>(InitialContext.java:195)
[qbrowse] at org.eupki.common.test.util.QueueBrowserX.displayQueueContent(QueueBrowserX.java:273)
[qbrowse] at org.eupki.common.test.util.QueueBrowserX.main(QueueBrowserX.java:143)
[qbrowse] Caused by: java.lang.ClassNotFoundException: org.jboss.naming.interceptors.ExceptionInterceptor
[qbrowse] at java.net.URLClassLoader$1.run(URLClassLoader.java:199)
[qbrowse] at java.security.AccessController.doPrivileged(Native Method)
[qbrowse] at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
[qbrowse] at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
[qbrowse] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
[qbrowse] at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
[qbrowse] at org.jboss.invocation.MarshalledValueInputStream.resolveClass(MarshalledValueInputStream.java:85)
[qbrowse] at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1513)
[qbrowse] at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1435)
[qbrowse] at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1626)
[qbrowse] at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
[qbrowse] at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
[qbrowse] at org.jboss.proxy.Interceptor.readExternal(Interceptor.java:66)
[qbrowse] at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1686)
[qbrowse] at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1644)
[qbrowse] at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
[qbrowse] at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
[qbrowse] at org.jboss.proxy.Interceptor.readExternal(Interceptor.java:66)
[qbrowse] at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1686)
[qbrowse] at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1644)
[qbrowse] at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
[qbrowse] at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
[qbrowse] at org.jboss.proxy.ClientContainer.readExternal(ClientContainer.java:111)
[qbrowse] at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1686)
[qbrowse] at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1644)
[qbrowse] at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
[qbrowse] at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1845)
[qbrowse] at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1769)
[qbrowse] at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
[qbrowse] at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
[qbrowse] at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
[qbrowse] at org.jboss.invocation.MarshalledValue.get(MarshalledValue.java:78)
[qbrowse] at org.jboss.naming.HttpNamingContextFactory.getNamingServer(HttpNamingContextFactory.java:115)
[qbrowse] at org.jboss.naming.HttpNamingContextFactory.getInitialContext(HttpNamingContextFactory.java:64)
[qbrowse] ... 6 more
The ant code used to call the QueueBrowser is:
<target name="qbrowser" depends="compile"> <java fork="yes" classname="org.eupki.common.test.util.QueueBrowserX" taskname="qbrowse" failonerror="true"> <sysproperty key="java.naming.factory.initial" value="org.jnp.interfaces.NamingContextFactory"/> <sysproperty key="java.naming.factory.url.pkgs" value="org.jboss.naming:org.jnp.interfaces"/> <!-- <sysproperty key="java.naming.provider.url" value="jnp://localhost:1099"/>//--> <arg line="-s=george.axetel.ro -p=http -q=fromCAReqQueue"/> <classpath refid="test.path"/> </java> </target>
I've commented out the provider.url to be sure that the queue browser does the look up on the correct server.
Running the run-browser.sh -s=B -q=fromCAReqQueue I'd get something even weirder:
[EMAIL PROTECTED] common]$ run-browser.sh -s=B -q=fromCAReqQueue
JAVA_OPTS=
running QueueBrowserX...
{-s=B, -q=fromCAReqQueue}
Created InitialContext, env={java.naming.provider.url=george:1099, java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces:org.jboss.naming:org.jnp.interfaces}
got the queue
browser created
these are the messages...
javax.jms.InvalidDestinationException: That destination does not exist
at org.jboss.mq.server.JMSDestinationManager.browse(JMSDestinationManager.java:652)
at org.jboss.mq.server.JMSServerInterceptorSupport.browse(JMSServerInterceptorSupport.java:211)
at org.jboss.mq.security.ServerSecurityInterceptor.browse(ServerSecurityInterceptor.java:85)
at org.jboss.mq.server.TracingInterceptor.browse(TracingInterceptor.java:442)
at org.jboss.mq.server.JMSServerInvoker.browse(JMSServerInvoker.java:213)
at org.jboss.mq.il.oil.OILServerILService$Client.run(OILServerILService.java:252)
at java.lang.Thread.run(Thread.java:534)
done
Using 3.2.2 has also affected running our interoperation tests: we use different modules running on different machines on top of JBoss. We have a communication MBean that fetches messages from a machine to another, while internat modules just use local queues, and the MBean isn't working anymore with 3.2.2, the error message being also related to a InvalidDestinationException, something quite weird. Quoting from the J2EE docs: "This exception must be thrown when a destination either is not understood by a provider or is no longer valid.". Come again?
The way we do queue lookups in the communication MBean is the same as in QueueBrowserX, we do a JNDI lookup on the remote server by the queue name, locate the queue, cast the found object to (Queue), create a QueueBrowser, and when trying to browse the queue things don't work as expected or as before. Any ideas?
I'm running JBoss using the Sun 1.4.2_02 JDK on Mandrake Linux 9.1.
/* $Id: QueueBrowserX.java,v 1.11 2003/07/09 15:22:11 florin Exp $ ******************************************************************** * Copyright © Axetel 2003 ( [EMAIL PROTECTED] http://www.axetel.com ) * All rights reserved * * EuropePKI is a libre software which has been developed under * European Commission Program referenced IST-2001-34340-EuPKI, * on an original idea from Eduard TRIC. * * Information about the project can be found at: * http://www.europepki.org/ * * EuropePKI is dual licensed: L-GPL & MPL. * For more information, please report to: * http://www.mozilla.org/MPL/MPL-1.1.html * http://www.gnu.org/copyleft/lesser.html. * * Software distributed under the License is distributed on * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. * See the License for the specific language governing rights and * limitations under the License. * ******************************************************************** */
package org.eupki.common.test.util; import java.util.*; import java.io.PrintStream; import java.net.InetAddress; import java.security.Security; import javax.jms.*; import javax.naming.InitialContext; import javax.naming.Context; /** * Browses/displays messages from a certain queue on a certain server * and using a certain communication protocol. * All options are command line customizable. * <p> * This class also contains JMS utility functions. * * TODO make new defaults, that are SSL-oriented * * @author AXETEL Consulting * (florin) * * @version <pre>$Revision: 1.11 $</pre> */ public class QueueBrowserX { /* ... */ //-- Constants ------------------------------------------------------------- //-- Static variables ------------------------------------------------------ /** configurable out stream */ public static PrintStream out; static { // initial is the default out stream out = System.out; } //-- Instance variables ---------------------------------------------------- //-- Constructors ---------------------------------------------------------- //-- Methods (by functionality) -------------------------------------------- /** * Method main. * * @param args first argument is the server and the second is the protocol * * @see #displayHelpMessage() for details of the structure of the <tt>args</tt> param */ public static void main(String[] args) { boolean isSSL = false; String providerURL = "localhost"; String providerURLProtocol = "jnp"; String queueName = "fromRAQueue"; String port = ""; String filter = null; boolean isVerbose = false; // gets the command line parameters try { Hashtable props = processArgs(args); // shows help if (props.containsKey("-h")) { displayHelpMessage(); System.exit(0); } // gets the SLL value isSSL = props.containsKey("-ssl"); // gets the server if (props.containsKey("-s")) { providerURL = (String) props.get("-s"); } // gets the server port if (props.containsKey("-port")) { port = (String) props.get("-port"); } // gets and checks the provider URL if (props.containsKey("-p")) { providerURLProtocol = (String) props.get("-p"); if( !providerURLProtocol.equals("http") && !providerURLProtocol.equals("jnp") ) { displayHelpMessage(); System.exit(0); } } // gets the queue name if (props.containsKey("-q")) { queueName = (String) props.get("-q"); } // gets the filter if (props.containsKey("-f")) { filter = (String) props.get("-f"); } // gets the verbose level isVerbose = props.containsKey("-v"); } catch (Exception e) { displayHelpMessage(); } displayQueueContent(isSSL, providerURLProtocol, providerURL, port, queueName, filter, isVerbose); } /** * Returns a Hashtable with the options passed as args in the format -<key>=<val>. * * @param args command line arguments * @return Hashtable the command line arguments in the Hastable format */ private static Hashtable processArgs(String[] args) { Hashtable h = new Hashtable(); for (int i = 0; i < args.length; i++) { if (args[i].charAt(0) == '-') { int pos = args[i].indexOf('='); if (pos >= 0) { String key = args[i].substring(0, pos); String value = args[i].substring(pos + 1); h.put(key, value); } else { h.put(args[i], ""); } } } out.println(h.toString()); return h; } /** * Displays a help message with command line options. */ private static void displayHelpMessage() { out.println("Utility to browse messages from a remote JMS."); out.println(); out.println("Optional parameters (other forms are ignored):"); out.println(" -ssl if the connection will be secure"); out.println(" -p=jnp|http what protocol to use (-p=http -ssl means https) (default jnp)"); out.println(" -s=<server> server name (default localhost)"); out.println(" -port=<port> server port (default 1099 for jnp, 8080 for http, 8443 for https)"); out.println(" -q=<queue> queue name (default fromRAQueue)"); out.println(" -f=<filter> queue filter (default null)"); out.println(" -v verbose (default false)"); out.println(" -h this information"); } /** * Displays the content of a queue. * Avoids networking on local JMS server. * * @param isSSL if the connection to the JMS server is secured * @param protocol the server protocol (http or jnp) * @param server the server machine name * @param port the server port * @param queueName the name of the queue * @param queueFilter the filter for the queue * @param isVerbose if <tt>true</tt>, the messages are displayed in detail */ public static void displayQueueContent(boolean isSSL, String protocol, String server, String port, String queueName, String queueFilter, boolean isVerbose) { String contextFactory = ""; String providerURL = server; String providerURLProtocol = protocol; String providerURLPath = ""; // gets the initial context factory and updates the provider URL if (protocol.equals("http")) { contextFactory = "org.jboss.naming.HttpNamingContextFactory"; if (isSSL) { if (port.length() == 0) { port = "8443"; } providerURLProtocol = "https"; } else { if (port.length() == 0) { port = "8080"; } providerURLProtocol = "http"; } providerURLPath = "/invoker/JNDIFactory"; } else if (protocol.equals("jnp")) { contextFactory = "org.jnp.interfaces.NamingContextFactory"; if (port.length() == 0) { port = "1099"; } } else { // ... beee // this case should be resolved in caller method before calling this } providerURL = providerURLProtocol + "://" + providerURL + ":" + port + providerURLPath; try { // Install the Sun JSSE provider since we may not have JSSE installed boolean isLocalServer = false; Context lContext = null; // looks up for localhost... or local machine name try { InetAddress i_addr = InetAddress.getByName(server); isLocalServer = (i_addr.isLoopbackAddress() || i_addr.equals(InetAddress.getLocalHost())); } catch (Exception ex) { isLocalServer = false; } // gets the initial context // avoids networking on local server if (isLocalServer) { lContext = new InitialContext(); } else { if (isSSL) { Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); out.println("Added JSSE security provider"); } Properties env = new Properties(); env.setProperty(Context.INITIAL_CONTEXT_FACTORY, contextFactory); env.setProperty(Context.PROVIDER_URL, providerURL); if (isSSL) { env.setProperty(Context.SECURITY_PROTOCOL, "ssl"); } lContext = new InitialContext(env); } out.println("Created InitialContext, env=" + lContext.getEnvironment()); // gets the queue stuff QueueConnectionFactory qcf = (QueueConnectionFactory) lContext.lookup("ConnectionFactory"); out.println ("getting the queue..."); Queue queue = (Queue) lContext.lookup("queue/" + queueName); // Queue queue = (Queue) lContext.lookup(queueName); out.println("got the queue"); QueueConnection qc = qcf.createQueueConnection(); QueueSession qss = qc.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); QueueBrowser qb = qss.createBrowser(queue, queueFilter); out.println("browser created"); out.println("these are the messages..."); // displays the queue content int count = 0; Enumeration ele = qb.getEnumeration(); while (ele.hasMoreElements()) { Message msg = (Message) ele.nextElement(); if (isVerbose) { out.println("messge: [" + msg.toString() + "]"); } else if (msg instanceof TextMessage) { out.println("messge: [" + ((TextMessage) msg).getText() + "]"); } else { out.println("message of class: [" + msg.getClass().getName() + "]"); } count++; } out.println("...that's all: " + count + " message(s)"); // closes the connection qc.close(); } catch (Exception e) { e.printStackTrace(); } } /** * Displays the content of a queue on local (searching PKIMsg). * * @param queueName the name of the queue * @param queueFilter the filter for the queue * @param isVerbose if the messages are displayed in detail * * @return the received message (or null). * * @throws Exception if something goes wrong */ public static Message getLocalQueueContent(String queueName, String queueFilter, boolean isVerbose) throws Exception { //initial context InitialContext lContext = new InitialContext(); // gets the queue stuff QueueConnectionFactory qcf = (QueueConnectionFactory) lContext.lookup("ConnectionFactory"); Queue queue = (Queue) lContext.lookup("queue/" + queueName); if (isVerbose) out.println("got the queue"); QueueConnection qc = qcf.createQueueConnection(); QueueSession qss = qc.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); qc.start(); //create browser QueueReceiver qr = qss.createReceiver(queue, queueFilter); if (isVerbose) out.println("receiver created"); //get the messages Message ret = qr.receiveNoWait(); // closes the connection qc.close(); return ret; } }
run-browser.sh
Description: Bourne shell script