Java Dynamic Management Kit 5.1 Tutorial

2.2.3 Generic Attribute Getters and Setters

Generic getters and setters take a parameter that indicates the name of the attribute to read or write. There are two issues to keep in mind when implementing these methods:

The getAttribute method is the simplest, since only the attribute name must be verified.


Example 2–3 Implementation of the getAttribute Method

public Object getAttribute(String attribute_name) 
    throws AttributeNotFoundException,
           MBeanException,
           ReflectionException {

    // Check attribute_name to avoid NullPointerException later on
    if (attribute_name == null) {
        throw new RuntimeOperationsException(
            new IllegalArgumentException("Attribute name cannot be null"), 
            "Cannot invoke a getter of " + dClassName +
                " with null attribute name");
    }

    // Call the corresponding getter for a recognized attribute_name
    if (attribute_name.equals("State")) {
        return getState();
    } 
    if (attribute_name.equals("NbChanges")) {
        return getNbChanges();
    }

    // If attribute_name has not been recognized
    throw(new AttributeNotFoundException(
        "Cannot find " + attribute_name + " attribute in " + dClassName));
}

// internal methods for getting attributes
public String getState() {
    return state;
}

public Integer getNbChanges() {
    return new Integer(nbChanges);
}

// internal variables representing attributes
private String      state = "initial state";
private int         nbChanges = 0;

The setAttribute method is more complicated, since you must also ensure that the given type can be assigned to the attribute and handle the special case for a null value.


Example 2–4 Implementation of the setAttribute Method

public void setAttribute(Attribute attribute)
    throws AttributeNotFoundException,
           InvalidAttributeValueException,
           MBeanException, 
           ReflectionException {

    // Check attribute to avoid NullPointerException later on
    if (attribute == null) {
        throw new RuntimeOperationsException(
            new IllegalArgumentException("Attribute cannot be null"),
            "Cannot invoke a setter of " + dClassName +
                " with null attribute");
    }
    String name = attribute.getName();
    Object value = attribute.getValue();

    if (name.equals("State")) {
        // if null value, try and see if the setter returns any exception
        if (value == null) {
            try {
                setState( null );
            } catch (Exception e) {
                throw(new InvalidAttributeValueException(
                    "Cannot set attribute "+ name +" to null")); 
            }
        }
        // if non null value, make sure it is assignable to the attribute
        else if (String.class.isAssignableFrom(value.getClass())) {
                    setState((String) value);
        } else {
                    throw new InvalidAttributeValueException(
                        "Cannot set attribute "+ name +
                            " to a " + value.getClass().getName() +
                            " object, String expected");
                }
            } 
    // recognize an attempt to set a read-only attribute
    else if (name.equals("NbChanges")) {
        throw new AttributeNotFoundException(
            "Cannot set attribute "+ name +
                " because it is read-only");
    }

    // unrecognized attribute name
    else {
        throw new AttributeNotFoundException(
            "Attribute " + name + " not found in " +
                this.getClass().getName());
    }
}

// internal method for setting attribute
public void setState(String s) {
    state = s;
    nbChanges++;
}

Notice that if a change in your management solution requires you to change your management interface, it will be harder to do with a dynamic MBean. In a standard MBean, each attribute and operation is a separate method, so unchanged attributes are unaffected. In a dynamic MBean, you must modify the generic methods that encode all attributes.