patternjavaMinor
Monitoring params via JMX
Viewed 0 times
paramsviajmxmonitoring
Problem
A task for hiring on a new job (I failed it with reason "very bad code").
Write a program, which will be monitoring the params via JMX.
Param should have name, type and observabale value.
Why my code is bad? And how write this task more eleganty and clear?
main.java
Starts my app
MBeanContainer.java
There is MBeanServer, where controls observable params. We can start, stop MBeanServer and pass or get params from it.
```
public class MBeanContainer
{
static MBeanServer mBeanServer;
private static HashMap mbeansList = new HashMap();
/**
* Start Mbean server
*/
public static void startMBeanServer() {
mBeanServer = ManagementFactory.getPlatformMBeanServer();
try {
LocateRegistry.createRegistry(Main.port);
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:"+Main.port+"/server");
JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mBeanServer);
cs.start();
} catch (ExportException ee) { //hide trace exception and continue work when mbean server is already run.
if (ee.getCause().getClass() == BindException.class)
Utils.showMessage("Server is already started. \n " + ee.getCau
Write a program, which will be monitoring the params via JMX.
Param should have name, type and observabale value.
Why my code is bad? And how write this task more eleganty and clear?
main.java
Starts my app
public class Main {
public static String pluginFolder;
public static Integer port = 9999;
public static void main( String args[] )
{
//directory with plugins
if (args.length>0) {
pluginFolder = args[0];
} else {
System.out.println("Please specify folder with plugins! Type path to plugins after space");
return;
}
//port number
if (args.length>1) {
try {
Integer.parseInt(args[1]);
} catch (NumberFormatException nfe) {
Utils.showMessage("Wrong port. Using default port: " + port);
}
}
MBeanContainer.startMBeanServer();
}
}MBeanContainer.java
There is MBeanServer, where controls observable params. We can start, stop MBeanServer and pass or get params from it.
```
public class MBeanContainer
{
static MBeanServer mBeanServer;
private static HashMap mbeansList = new HashMap();
/**
* Start Mbean server
*/
public static void startMBeanServer() {
mBeanServer = ManagementFactory.getPlatformMBeanServer();
try {
LocateRegistry.createRegistry(Main.port);
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:"+Main.port+"/server");
JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mBeanServer);
cs.start();
} catch (ExportException ee) { //hide trace exception and continue work when mbean server is already run.
if (ee.getCause().getClass() == BindException.class)
Utils.showMessage("Server is already started. \n " + ee.getCau
Solution
Stylistic
inconsistent indentation in some places, parameter lists sometimes
have spaces, sometimes they don't and the names aren't that great
(e.g.
the intent. I'd also either remove incomplete docstrings, or fill them
in. IMO if they don't add to the understanding of the code, they just
add clutter, but you could argue differently if you actually used the
docstrings in the IDE or docs generation.
isn't well structured. If you can't deal with the error, let it
propagate and don't just print a stack trace (or at least re-throw so
the caller can deal with it).
be changed to use
case?
write out the types, e.g.
pretty sure you don't rely on the hashing part. With one of the latest
changes in Java you can also omit a lot of the generic arguments.
object itself. Again, choose one or the other.
Structural
parameter is named
implementation. Renaming to
I guess, although for millisecond resolution it's overkill.
methods and maybe providing a singleton will make this way more
reusable.
into a method so the control flow is more obvious.
Okay, maybe others find more. Providing tests would also be something
nice to show off.
Even though this is an interview exercise, I think at least these points
would need to be addressed before considering using it in production and
later maintaining it.
Thread safety is probably okay, but is something to look out for. It
would be nice if
shutdown.
For the design itself, well, without a bit more restrictions it's hard
to see what should be changed; apart from what I wrote it looks okay to
me. JMX probably isn't the best thing to exercise anyway.
- (Always assuming this is not garbled by the pasting) there is
inconsistent indentation in some places, parameter lists sometimes
have spaces, sometimes they don't and the names aren't that great
(e.g.
not for notification, o, cs are bad).- The comments aren't very useful, except for the one in
MBeanContainer, //hide trace..., because it actually clarifiesthe intent. I'd also either remove incomplete docstrings, or fill them
in. IMO if they don't add to the understanding of the code, they just
add clutter, but you could argue differently if you actually used the
docstrings in the IDE or docs generation.
- Catching
Exceptionat every turn suggests that the error handling
isn't well structured. If you can't deal with the error, let it
propagate and don't just print a stack trace (or at least re-throw so
the caller can deal with it).
- In
MBeanContainerthe type check forBindExceptionshould probably
be changed to use
instanceof. Also, what's with the alternativecase?
- Better use the base interface instead of specific classes when you
write out the types, e.g.
Map. Again, I'mpretty sure you don't rely on the hashing part. With one of the latest
changes in Java you can also omit a lot of the generic arguments.
- If you use
finalonce, either do it always, or not at all. Same for
@Override.BaseParamcopies the values fromParamInterfaceand stores the
object itself. Again, choose one or the other.
Structural
getIntervalreturns anint,setIntervalacceptslong. The
parameter is named
time in the interface, interval in theimplementation. Renaming to
milliseconds would be good, showing offJodaTime or a cron library would be great for an interview exerciseI guess, although for millisecond resolution it's overkill.
MBeanContaineris all global andstatic. Changing that to regular
methods and maybe providing a singleton will make this way more
reusable.
BaseParam::rundoes too much, I'd split the notification creation
into a method so the control flow is more obvious.
Okay, maybe others find more. Providing tests would also be something
nice to show off.
Even though this is an interview exercise, I think at least these points
would need to be addressed before considering using it in production and
later maintaining it.
Thread safety is probably okay, but is something to look out for. It
would be nice if
stopMonitoring actually waited for threads toshutdown.
For the design itself, well, without a bit more restrictions it's hard
to see what should be changed; apart from what I wrote it looks okay to
me. JMX probably isn't the best thing to exercise anyway.
Context
StackExchange Code Review Q#67363, answer score: 6
Revisions (0)
No revisions yet.