Ah. Looks like this is not a problem anymore if we run it with a JDK instead of 
JRE. That will cause the String jmxUrl = findJMXUrlByProcessId(pid) to get a 
proper value.

Hope it helps some people.

Thanks,

Ton Wessling


On 01/13/2012 01:59 PM, Wessling, Ton wrote:

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