Description
The practice of "double JSON encoding" JMX attributes:
- in the MXBean itself using Jetty's JSON.toString(...)
- in the JMXJsonServlet using Jackson
results in malformed JSON documents (technically not "malformed", but doesn't properly allow for traversal into nested JSON structures).
For example:
$ curl http://localhost:50070/jmx?get=Hadoop:service=NameNode,name=NameNodeInfo::NodeUsage { "beans" : [ { "name" : "Hadoop:service=NameNode,name=NameNodeInfo", "modelerType" : "org.apache.hadoop.hdfs.server.namenode.FSNamesystem", "NodeUsage" : "{\"nodeUsage\":{\"min\":\"0.00%\",\"median\":\"0.01%\",\"max\":\"0.01%\",\"stdDev\":\"0.00%\"}}" } ]
The NodeUsage attribute should instead be:
"NodeUsage" : {"nodeUsage":{"min":"0.00%","median":"0.01%","max":"0.01%","stdDev":"0.00%"}}
The Web UI seems to be aware of this and has applied a workaround:
dfshealth.js
// Workarounds for the fact that JMXJsonServlet returns non-standard JSON strings
Putting JMX aside, one fix would be to let JMXJsonServlet do all the encoding and simply have the MXBean return a Map. That would, however, likely not encode properly for native JMX access. I'm not familiar enough with how JMX is used elsewhere in Hadoop to suggest an alternative.