# HG changeset patch # User jbachorik # Date 1499453618 -3600 # Node ID 4f24be04a422aa4eebb006222d86b325907d9849 # Parent 848ccfd2774389a55da3e3c9e9d19db45ce9d30e 8139870: sun.management.LazyCompositeData.isTypeMatched() fails for composite types with items of ArrayType Reviewed-by: dfuchs diff -r 848ccfd27743 -r 4f24be04a422 src/share/classes/sun/management/LazyCompositeData.java --- a/src/share/classes/sun/management/LazyCompositeData.java Tue Jan 17 15:55:40 2012 -0800 +++ b/src/share/classes/sun/management/LazyCompositeData.java Fri Jul 07 19:53:38 2017 +0100 @@ -27,6 +27,7 @@ import java.io.Serializable; import java.util.*; +import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenType; @@ -48,39 +49,48 @@ private CompositeData compositeData; // Implementation of the CompositeData interface + @Override public boolean containsKey(String key) { return compositeData().containsKey(key); } + @Override public boolean containsValue(Object value) { return compositeData().containsValue(value); } + @Override public boolean equals(Object obj) { return compositeData().equals(obj); } + @Override public Object get(String key) { return compositeData().get(key); } + @Override public Object[] getAll(String[] keys) { return compositeData().getAll(keys); } + @Override public CompositeType getCompositeType() { return compositeData().getCompositeType(); } + @Override public int hashCode() { return compositeData().hashCode(); } + @Override public String toString() { /** FIXME: What should this be?? */ return compositeData().toString(); } + @Override public Collection values() { return compositeData().values(); } @@ -126,27 +136,31 @@ if (cd == null) throw new IllegalArgumentException("Null CompositeData"); - return ((Boolean) cd.get(itemName)).booleanValue(); + return ((Boolean) cd.get(itemName)); } static long getLong(CompositeData cd, String itemName) { if (cd == null) throw new IllegalArgumentException("Null CompositeData"); - return ((Long) cd.get(itemName)).longValue(); + return ((Long) cd.get(itemName)); } static int getInt(CompositeData cd, String itemName) { if (cd == null) throw new IllegalArgumentException("Null CompositeData"); - return ((Integer) cd.get(itemName)).intValue(); + return ((Integer) cd.get(itemName)); } /** * Compares two CompositeTypes and returns true if * all items in type1 exist in type2 and their item types * are the same. + * @param type1 the base composite type + * @param type2 the checked composite type + * @return {@code true} if all items in type1 exist in type2 and their item + * types are the same. */ protected static boolean isTypeMatched(CompositeType type1, CompositeType type2) { if (type1 == type2) return true; @@ -160,19 +174,7 @@ return false; for (String item: allItems) { - OpenType ot1 = type1.getType(item); - OpenType ot2 = type2.getType(item); - if (ot1 instanceof CompositeType) { - if (! (ot2 instanceof CompositeType)) - return false; - if (!isTypeMatched((CompositeType) ot1, (CompositeType) ot2)) - return false; - } else if (ot1 instanceof TabularType) { - if (! (ot2 instanceof TabularType)) - return false; - if (!isTypeMatched((TabularType) ot1, (TabularType) ot2)) - return false; - } else if (!ot1.equals(ot2)) { + if (!isTypeMatched(type1.getType(item), type2.getType(item))) { return false; } } @@ -192,5 +194,41 @@ return isTypeMatched(type1.getRowType(), type2.getRowType()); } + protected static boolean isTypeMatched(ArrayType type1, ArrayType type2) { + if (type1 == type2) return true; + + int dim1 = type1.getDimension(); + int dim2 = type2.getDimension(); + + // check if the array dimensions are the same + if (dim1 != dim2) + return false; + + return isTypeMatched(type1.getElementOpenType(), type2.getElementOpenType()); + } + + private static boolean isTypeMatched(OpenType ot1, OpenType ot2) { + if (ot1 instanceof CompositeType) { + if (! (ot2 instanceof CompositeType)) + return false; + if (!isTypeMatched((CompositeType) ot1, (CompositeType) ot2)) + return false; + } else if (ot1 instanceof TabularType) { + if (! (ot2 instanceof TabularType)) + return false; + if (!isTypeMatched((TabularType) ot1, (TabularType) ot2)) + return false; + } else if (ot1 instanceof ArrayType) { + if (! (ot2 instanceof ArrayType)) + return false; + if (!isTypeMatched((ArrayType) ot1, (ArrayType) ot2)) { + return false; + } + } else if (!ot1.equals(ot2)) { + return false; + } + return true; + } + private static final long serialVersionUID = -2190411934472666714L; } diff -r 848ccfd27743 -r 4f24be04a422 test/sun/management/LazyCompositeDataTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/management/LazyCompositeDataTest.java Fri Jul 07 19:53:38 2017 +0100 @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.HashMap; +import java.util.Map; +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import sun.management.LazyCompositeData; + +/** + * @test + * @bug 8139870 + * @summary sun.management.LazyCompositeData.isTypeMatched() fails for composite types with items of ArrayType + * @modules java.management/sun.management + * @author Jaroslav Bachorik + */ + +public class LazyCompositeDataTest { + private final static CompositeData dataV1, dataV2; + + static { + try { + // *** + // prepare the composite types + + // composite type stored in an array; V1 + CompositeType subtypeV1 = new CompositeType( + "Subtype1", + "Version 1", + new String[]{"item1"}, + new String[]{"Item 1"}, + new OpenType[]{ + SimpleType.STRING + } + ); + + // composite type stored in an array; V2 + CompositeType subtypeV2 = new CompositeType( + "Subtype2", + "Version 2", + new String[]{"item1", "item2"}, + new String[]{"Item 1", "Item 2"}, + new OpenType[]{ + SimpleType.STRING, + SimpleType.INTEGER + } + ); + + + // main composite type; V1 + // one of the items is array of 'subtypeV1' instances + CompositeType typeV1 = new CompositeType( + "MyDataV1", + "Version 1", + new String[]{"item1", "item2"}, + new String[]{"Item 1", "Item 2"}, + new OpenType[]{ + SimpleType.STRING, + ArrayType.getArrayType(subtypeV1) + } + ); + + // main composite type; V2 + // one of the items is array of 'subtypeV2' instances + CompositeType typeV2 = new CompositeType( + "MyDataV2", + "Version 2", + new String[]{"item1", "item2"}, + new String[]{"Item 1", "Item 2"}, + new OpenType[]{ + SimpleType.STRING, + ArrayType.getArrayType(subtypeV2) + } + ); + // *** + + // *** + // construct the data + Map subitemsV1 = new HashMap<>(); + Map subitemsV2 = new HashMap<>(); + + Map itemsV1 = new HashMap<>(); + Map itemsV2 = new HashMap<>(); + + subitemsV1.put("item1", "item1"); + subitemsV2.put("item1", "item1"); + subitemsV2.put("item2", 42); + + itemsV1.put("item1", "item1"); + itemsV1.put("item2", new CompositeData[]{new CompositeDataSupport(subtypeV1, subitemsV1)}); + + itemsV2.put("item1", "item1"); + itemsV2.put("item2", new CompositeData[]{new CompositeDataSupport(subtypeV2, subitemsV2)}); + + dataV1 = new CompositeDataSupport(typeV1, itemsV1); + dataV2 = new CompositeDataSupport(typeV2, itemsV2); + // *** + } catch (OpenDataException e) { + throw new Error(e); + } + } + + private static class MyDataV1 extends LazyCompositeData { + @Override + protected CompositeData getCompositeData() { + return dataV1; + } + + public boolean isTypeMached(CompositeType type) { + return isTypeMatched(this.getCompositeType(), type); + } + } + + private static class MyDataV2 extends LazyCompositeData { + @Override + protected CompositeData getCompositeData() { + return dataV2; + } + + } + + public static void main(String[] args) throws Exception { + System.out.println("Checking LazyCompositeData.isTypeMatched()"); + MyDataV1 v1 = new MyDataV1(); + MyDataV2 v2 = new MyDataV2(); + + if (!v1.isTypeMached(v2.getCompositeType())) { + System.err.println("=== FAILED"); + System.err.println("V1 should be matched by V2"); + System.err.println("\n=== V1"); + System.err.println(v1.getCompositeType()); + System.err.println("\n=== V2"); + System.err.println(v2.getCompositeType()); + throw new Error(); + } + System.out.println("=== PASSED"); + } +} \ No newline at end of file