# HG changeset patch # User jbachorik # Date 1445367193 -7200 # Node ID af1ca24593aaab5550b2a4f5a5933139f79c7027 # Parent bbb84c5a1228858a114c66f76af5ac3af0cfbc34 8139870: sun.management.LazyCompositeData.isTypeMatched() fails for composite types with items of ArrayType Reviewed-by: dfuchs diff -r bbb84c5a1228 -r af1ca24593aa jdk/src/java.management/share/classes/sun/management/LazyCompositeData.java --- a/jdk/src/java.management/share/classes/sun/management/LazyCompositeData.java Tue Oct 20 10:33:41 2015 -0700 +++ b/jdk/src/java.management/share/classes/sun/management/LazyCompositeData.java Tue Oct 20 20:53:13 2015 +0200 @@ -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)); } public 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)); } public 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; @@ -159,24 +173,9 @@ if (!type2.keySet().containsAll(allItems)) 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)) { - return false; - } - } - return true; + return allItems.stream().allMatch( + item -> isTypeMatched(type1.getType(item), type2.getType(item)) + ); } protected static boolean isTypeMatched(TabularType type1, TabularType type2) { @@ -192,5 +191,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 bbb84c5a1228 -r af1ca24593aa jdk/test/sun/management/LazyCompositeDataTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/management/LazyCompositeDataTest.java Tue Oct 20 20:53:13 2015 +0200 @@ -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