JDK-6710498 : MXBeans trip over reflection bug when constructor has arrays and generics as parameters
  • Type: Bug
  • Component: core-svc
  • Sub-Component: javax.management
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2008-06-04
  • Updated: 2011-04-01
  • Resolved: 2008-09-23
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
6u10 b31Fixed
Related Reports
Relates :  
Description
If an MXBean needs to reconstruct a type T, and T has a @ConstructorProperties constructor that has an array parameter (e.g. String[]) and a generic parameter (e.g. List<String>) then it is shown as unreconstructible:

Exception in thread "main" java.lang.IllegalArgumentException: java.io.InvalidObjectException: @ConstructorProperties gives property array of type class [Ljava.lang.String; for parameter  of type java.lang.String[]: public MXBug$T(java.lang.String[],java.util.List)
	at com.sun.jmx.mbeanserver.ConvertingMethod.checkCallToOpen(ConvertingMethod.java:96)
	at com.sun.jmx.mbeanserver.MXBeanProxy$Visitor.visitAttribute(MXBeanProxy.java:53)
	at com.sun.jmx.mbeanserver.MXBeanProxy$Visitor.visitAttribute(MXBeanProxy.java:48)
	at com.sun.jmx.mbeanserver.MBeanAnalyzer.visit(MBeanAnalyzer.java:53)
	at com.sun.jmx.mbeanserver.MXBeanProxy.<init>(MXBeanProxy.java:45)
	at javax.management.MBeanServerInvocationHandler.findMXBeanProxy(MBeanServerInvocationHandler.java:318)
	at javax.management.MBeanServerInvocationHandler.invoke(MBeanServerInvocationHandler.java:247)
	at $Proxy0.getT(Unknown Source)
	at MXBug.main(MXBug.java:48)
Caused by: java.io.InvalidObjectException: @ConstructorProperties gives property array of type class [Ljava.lang.String; for parameter  of type java.lang.String[]: public MXBug$T(java.lang.String[],java.util.List)
	at com.sun.jmx.mbeanserver.OpenConverter$CompositeBuilderViaConstructor.applicable(OpenConverter.java:1178)
	at com.sun.jmx.mbeanserver.OpenConverter$CompositeConverter.makeCompositeBuilder(OpenConverter.java:856)
	at com.sun.jmx.mbeanserver.OpenConverter$CompositeConverter.checkReconstructible(OpenConverter.java:880)
	at com.sun.jmx.mbeanserver.ConvertingMethod.checkCallToOpen(ConvertingMethod.java:94)

Here is the test program:

import java.beans.*;
import java.util.*;
import javax.management.*;

public class MXBug {
    public interface TMXBean {
	public T getT();
    }

    public static class TImpl implements TMXBean {
    	private final T t = new T(new String[] {"foo"}, Arrays.asList(new String[] {"bar"}));

        public T getT() {
	    return t;
	}
    }

    public static class T {
	private final String[] array;
    	private final List<String> list;

	@ConstructorProperties({"array", "list"})
	public T(String[] array, List<String> list) {
	    this.array = array;
    	    this.list = list;
	}

	public String[] getArray() {
	    return array;
	}

	public List<String> getList() {
	    return list;
	}

	@Override
	public String toString() {
	    return Arrays.toString(array) + list;
	}
    }

    public static void main(String[] args) throws Exception {
	MBeanServer mbs = MBeanServerFactory.newMBeanServer();
	ObjectName name = new ObjectName("d:k=v");
	TImpl t = new TImpl();
	mbs.registerMBean(t, name);
	TMXBean proxy = JMX.newMXBeanProxy(mbs, name, TMXBean.class);
	System.out.println(proxy.getT());
    }
}

Comments
EVALUATION This is another manifestation of 5041784, the bug where methods like Constructor.getGenericParameterTypes() sometimes represent String[] as GenericArrayType(String) instead of String[].class. In this particular case, we have Method.getGenericReturnType() which is correctly returning String[].class for a getter, but Constructor.getGenericParameterTypes() which is returning GenericArrayType(String) for a constructor parameter of type String[] if another constructor parameter is a ParameterizedType such as List<String>. Since the fix for 5041784 is only due in JDK 7, we will need to work around this bug in an update to JDK 6.
04-06-2008

WORK AROUND Use List<String> instead of String[], etc, to replace all uses of arrays with generics. This is not always very practical.
04-06-2008