Hi all,

just new to the mailing list, becasue of an issue we are experiencing 
with shutting down ActiveMQ.
We are running AMQ version 5.5.1 and java version 1.6.0.26 (JRE only).
Since the upgrade of AMQ from 5.5.0 to 5.5.1 we experience a NPE on 
shutdown through the console:

java.lang.NullPointerException
         at 
javax.management.remote.JMXServiceURL.<init>(JMXServiceURL.java:122)
         at 
org.apache.activemq.console.command.AbstractJmxCommand.handleOption(AbstractJmxCommand.java:350)
         at 
org.apache.activemq.console.command.ShutdownCommand.handleOption(ShutdownCommand.java:156)
         at 
org.apache.activemq.console.command.AbstractCommand.parseOptions(AbstractCommand.java:73)
         at 
org.apache.activemq.console.command.AbstractCommand.execute(AbstractCommand.java:45)
         at 
org.apache.activemq.console.command.AbstractJmxCommand.execute(AbstractJmxCommand.java:380)
         at 
org.apache.activemq.console.command.ShellCommand.runTask(ShellCommand.java:148)
         at 
org.apache.activemq.console.command.AbstractCommand.execute(AbstractCommand.java:57)
         at 
org.apache.activemq.console.command.ShellCommand.main(ShellCommand.java:90)
         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
         at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
         at java.lang.reflect.Method.invoke(Method.java:597)
         at org.apache.activemq.console.Main.runTaskClass(Main.java:251)
         at org.apache.activemq.console.Main.main(Main.java:107)


If I look at the code surrounding the origins of the NPE (constuction of 
the JMXServiceURL) I see the following snippet in AbstractJmxCommand.java:

335           if (isSunJVM()) {
336               if (tokens.isEmpty() || ((String) 
tokens.get(0)).startsWith("-")) {
337                   context.printException(new 
IllegalArgumentException("pid not specified"));
338                   return;
339               }
340               int pid = Integer.parseInt(tokens.remove(0));
341               context.print("Connecting to pid: " + pid);
342
343               String jmxUrl = findJMXUrlByProcessId(pid);
344               // If jmx url already specified
345               if (getJmxServiceUrl() != null) {
346                   context.printException(new 
IllegalArgumentException("JMX URL already specified."));
347                   tokens.clear();
348               }
349               try {
350                   this.setJmxServiceUrl(new JMXServiceURL(jmxUrl));
351               } catch (MalformedURLException e) {
352                   context.printException(e);
353                   tokens.clear();
354               }
355           }


1) this is the Sun JVM. That evals to True.
2) the String jmxUrl = findJMXUrlByProcessId(pid); on line 343 calls 
some nifty code which is only available in a JDK (not in a JRE), so that 
returns null all the time.
3) the if (getJmxServiceUrl() != null) { on line 345 does not really 
_do_ anything, and the value which can be obtained through 
getJmxServiceUrl() is also never used in this snippet.

The above combination causes a this.setJmxServiceUrl(new 
JMXServiceURL(jmxUrl)); to throw a NPE, since jmxUrl is always null.
When the start / stop commands are configured with a --jmxUrl parameter, 
the "JMX URL already specified" error is logged, followed by the NPE on 
line 350.

Should this piece of code not be changed to use either the one returned 
by findJMXUrlByProcessId if available, and the getJmxServiceUrl() result 
(which gets defaulted to a certain value) otherwise?

A fix could be something like this:

345               if (getJmxServiceUrl() != null && jmxUrl != null) {
346                   context.printException(new 
IllegalArgumentException("JMX URL already specified by process."));
347                   tokens.clear();
348               }
349               if(getJmxServiceUrl() == null && jmxUrl != null) { // 
otherwise it is already set in this class
350                   try {
351                       this.setJmxServiceUrl(new JMXServiceURL(jmxUrl));
352                   } catch (MalformedURLException e) {
353                       context.printException(e);
354                       tokens.clear();
355                   }
356               }


Please correct me if I am wrong or misunderstanding something.

Thanks,

Ton Wessling

Reply via email to