JDK-6190628 : Standard MBeans should support covariant return types in MBean interfaces.
  • Type: Enhancement
  • Component: core-svc
  • Sub-Component: javax.management
  • Affected Version: 5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: solaris_9
  • CPU: sparc
  • Submitted: 2004-11-04
  • Updated: 2017-05-16
  • Resolved: 2005-06-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b40Fixed
Related Reports
Relates :  
Relates :  
Description
MBean compliance test doesn't support covariant return types in MBean interfaces.

For instance:

public interface ParentMBean {
    public Object getState();
    public void setState(Object state);
}

public interface ChildMBean extends ParentMBean {
    public String getState();
    public void setState(String state);
}

The code above compiles but when trying to register a ChildMBean
in the MBeanServer the following exception is thrown:

Exception in thread "main" javax.management.NotCompliantMBeanException: Type mismatch between parameters of get or isState, setState methods
	at com.sun.jmx.mbeanserver.Introspector.testConsistency(Introspector.java:399)
	at com.sun.jmx.mbeanserver.Introspector.introspect(Introspector.java:348)
	at com.sun.jmx.mbeanserver.Introspector.testCompliance(Introspector.java:208)
	at com.sun.jmx.mbeanserver.Introspector.testCompliance(Introspector.java:150)
	at com.sun.jmx.mbeanserver.StandardMetaDataImpl.buildMBeanInfo(StandardMetaDataImpl.java:116)
	at com.sun.jmx.mbeanserver.StandardMetaDataImpl.testCompliance(StandardMetaDataImpl.java:149)
	at com.sun.jmx.mbeanserver.MetaDataImpl.testCompliance(MetaDataImpl.java:125)
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.createMBean(DefaultMBeanServerInterceptor.java:300)
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.createMBean(DefaultMBeanServerInterceptor.java:211)
	at com.sun.jmx.mbeanserver.JmxMBeanServer.createMBean(JmxMBeanServer.java:301)
	at Main.main(Main.java:26)
###@###.### 11/4/04 09:36 GMT

Comments
EVALUATION Will require some spec work. In particular this is tricky when you change the type of a read/write attribute: public interface ParentMBean { public Number getNumber(); public void setNumber(Number n); } public interface ChildMBean extends ParentMBean { public Integer getNumber(); public void setNumber(Integer n); } ChildMBean overrides getNumber, but overloads setNumber. An implementation of ChildMBean will need to implement both setNumber methods. Additionally, it must probably accept any Number argument to setNumber, which is inconsistent with the fact that it will return Integer from getNumber. Probably this case must be outlawed. What we can allow is for a subclass to override a read-only attribute covariantly. It can make the attribute read/write if it wants -- a user of the superclass still sees the attribute as read-only. Potentially we could also allow a subclass to overload a write-only attribute contravariantly. For instance: public interface ParentMBean { public void setNumber(Integer n); } public interface ChildMBean { public void setNumber(Number n); } However, the checks for this are more difficult and this case seems unlikely in practice. ###@###.### 11/4/04 10:15 GMT The formal rules are as follows. These rules are intended to cover even interfaces that could not have been generated by the Java compiler (for example with two methods called getX() that have unrelated return types). If the Java interface for a standard MBean is I, then we construct the set S of all methods in I and in all superinterfaces of I. Given two methods msuper and msub with the same name, if the parameters of the two methods are identical (ignoring generics), and if the return type of msuper is a supertype of the return type of msub, and if the most specific interface in which msuper is declared is a superinterface of the most specific interface in which msub is declared, then msub "covariantly overrides" msuper. Methods in S that are covariantly overridden are ignored when constructing the MBean interface from I. A method is a "getter" if its name is "getX" for some non-empty string X, and it has no parameters, and its return type is not void. A method is a "setter" if its name is "setX" for some non-empty string X, and it has one parameter, and its return type is void. The operations in the MBean interface are the methods in S that are neither getters nor setters. If, after eliminating covariantly overridden methods, two operations have the same name and the same parameters (ignoring generics) then the Standard MBean is illegal. If there exists a getter called getX but no setter called setX then the MBean interface has a read-only attribute called X whose type is the return type of getX. If, after eliminating covariantly overridden methods, there are two methods called getX with different return types (ignoring generics) then the Standard MBean is illegal. If there exists a setter called setX but no getter called getX then the MBean interface has a write-only attribute called X whose type is the parameter type of setX. If there are two methods called setX with different parameter types (ignoring generics) then the Standard MBean is illegal. If there exist both a getter called getX and a setter called setX then the MBean interface has a read-write attribute called X. The return type of getX must be the same as the parameter type of setX (ignoring generics), and this is the the type of the attribute X. If this condition is not met, the Standard MBean is illegal. These rules imply that operations and read-only attributes can be covariantly overridden, but read-write and write-only attributes cannot. This makes sense because if a subinterface changed the type of a writable attribute to a subtype then it would violate substitutability. ###@###.### 2005-03-22 15:56:20 GMT ###@###.### 2005-03-22 17:13:06 GMT
04-11-2004