You can't construct a JMX ObjectName without handling     MalformedObjectNameException, which is a checked exception.  Here's     why that is a pain, how to relieve that pain, and what we're doing     to make it less painful in the next version.

 

If you've done any programming at all with the JMX API, you'll     have noticed that all of     the ObjectName     constructors, and all of     the getInstance     methods, are declared as     throwing MalformedObjectNameException.

 

MalformedObjectNameException is a checked exception, which means     that you have to either declare it in the throws     clause of your method, or catch it within the method.  Having this     exception be a checked one was a mistake, in the light of modern     practice.  For example, Effective Java 2 says: Use checked     exceptions for recoverable conditions and runtime exceptions for     programming errors. Clearly a malformed ObjectName is a     programming error.

 

When the ancestor of the JMX API was being designed about ten     years ago this was all much less clear, and there were plenty of     misleading precedents     like MalformedURLException.     If the API were being designed over again,     MalformedObjectNameException would surely be a subclass of     IllegalArgumentException, or perhaps the constructors would just     throw IllegalArgumentException itself.

 

As it stands, this is painful, especially when you want to     initialize a static final field to be an ObjectName.  For example,     you might want to write something like this:

 
    public interface EventClientDelegateMBean {
        public static final ObjectName OBJECT_NAME =
            new ObjectName("javax.management.event:type=EventClientDelegate");
        ...
    }
  
 

Alas, that doesn't compile, because field initializers can't     throw checked exceptions.  You might try to write this:

 
    public interface EventClientDelegateMBean {
        public static final ObjectName OBJECT_NAME;
        static {
            try {
                OBJECT_NAME =
                    new ObjectName("javax.management.event:type=EventClientDelegate");
            } catch (MalformedObjectNameException e) {
                throw new IllegalArgumentException(e);
            }
        }
        ...
    }
  
 

But that doesn't compile either, because interfaces can't have     static initializers.  Don't ask me why not.

 

So the solution today is to write a simple     static newObjectName method that wraps the     MalformedObjectNameException as an IllegalArgumentException, park     it in some class, say Util, and call that every time     you need to construct an ObjectName:

 
    public class Util {
        ...
        public static ObjectName newObjectName(String s) {
            try {
                return ObjectName.getInstance(s);
            } catch (MalformedObjectNameException e) {
                throw new IllegalArgumentException(e);
            }
        }
        ...
    }
  
 

Thus our troublesome interface becomes:

 
    public interface EventClientDelegateMBean {
        public static final ObjectName OBJECT_NAME =
            Util.newObjectName("javax.management.event:type=EventClientDelegate");
        ...
    }
  
 

That does compile, and it does work.  (Although if the string     really is incorrect you will get bashed with     an ExceptionInInitializerError     when you first reference the interface.)

 

My favourite tiny change in the JMX 2.0 API is that we do now     provide standard methods to do this, so you no longer need to define     them.  The hardest part was to decide what to call them!  As of     JDK 7, you can write:

 
    public interface EventClientDelegateMBean {
        public static final ObjectName OBJECT_NAME =
            ObjectName.valueOf("javax.management.event:type=EventClientDelegate");
        ...
    }
  
 

[Tags: jmx     java.]