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