United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6710498 MXBeans trip over reflection bug when constructor has arrays and generics as parameters
JDK-6710498 : MXBeans trip over reflection bug when constructor has arrays and generics as parameters

Details
Type:
Bug
Submit Date:
2008-06-04
Status:
Closed
Updated Date:
2011-04-01
Project Name:
JDK
Resolved Date:
2008-09-23
Component:
core-svc
OS:
generic
Sub-Component:
javax.management
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:
6u10 (b31)

Related Reports
Relates:

Sub Tasks

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
WORK AROUND

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



Hardware and Software, Engineered to Work Together