Mercurial > hg > shenandoah-preopenjdk-archive > openjdk8 > jdk
changeset 248:92ea0ac77d2f
6692027: Custom subclasses of QueryEval don't serialize
Summary: Remove non-public superclass of QueryEval
Reviewed-by: dfuchs
author | emcmanus |
---|---|
date | Tue, 22 Apr 2008 18:58:40 +0200 |
parents | 79b594e72df0 |
children | d3af7105cc15 |
files | src/share/classes/javax/management/AndQueryExp.java src/share/classes/javax/management/BetweenQueryExp.java src/share/classes/javax/management/BinaryRelQueryExp.java src/share/classes/javax/management/NotQueryExp.java src/share/classes/javax/management/ObjectName.java src/share/classes/javax/management/OrQueryExp.java src/share/classes/javax/management/Query.java src/share/classes/javax/management/QueryEval.java test/javax/management/query/CustomQueryTest.java |
diffstat | 9 files changed, 145 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/javax/management/AndQueryExp.java Mon Apr 21 11:24:04 2008 -0400 +++ b/src/share/classes/javax/management/AndQueryExp.java Tue Apr 22 18:58:40 2008 +0200 @@ -100,12 +100,13 @@ /** * Returns a string representation of this AndQueryExp */ - public String toString() { - return "(" + exp1 + ") and (" + exp2 + ")"; - } + @Override + public String toString() { + return "(" + exp1 + ") and (" + exp2 + ")"; + } - @Override - String toQueryString() { + @Override + String toQueryString() { // Parentheses are only added if needed to disambiguate. return parens(exp1) + " and " + parens(exp2); }
--- a/src/share/classes/javax/management/BetweenQueryExp.java Mon Apr 21 11:24:04 2008 -0400 +++ b/src/share/classes/javax/management/BetweenQueryExp.java Tue Apr 22 18:58:40 2008 +0200 @@ -135,6 +135,7 @@ /** * Returns the string representing the object. */ + @Override public String toString() { return "(" + exp1 + ") between (" + exp2 + ") and (" + exp3 + ")"; }
--- a/src/share/classes/javax/management/BinaryRelQueryExp.java Mon Apr 21 11:24:04 2008 -0400 +++ b/src/share/classes/javax/management/BinaryRelQueryExp.java Tue Apr 22 18:58:40 2008 +0200 @@ -187,11 +187,11 @@ /** * Returns the string representing the object. */ + @Override public String toString() { return "(" + exp1 + ") " + relOpString() + " (" + exp2 + ")"; } - @Override String toQueryString() { return exp1 + " " + relOpString() + " " + exp2; }
--- a/src/share/classes/javax/management/NotQueryExp.java Mon Apr 21 11:24:04 2008 -0400 +++ b/src/share/classes/javax/management/NotQueryExp.java Tue Apr 22 18:58:40 2008 +0200 @@ -91,7 +91,6 @@ return "not (" + exp + ")"; } - @Override String toQueryString() { return "not (" + Query.toString(exp) + ")"; }
--- a/src/share/classes/javax/management/ObjectName.java Mon Apr 21 11:24:04 2008 -0400 +++ b/src/share/classes/javax/management/ObjectName.java Tue Apr 22 18:58:40 2008 +0200 @@ -223,8 +223,7 @@ * @since 1.5 */ @SuppressWarnings("serial") // don't complain serialVersionUID not constant -public class ObjectName extends ToQueryString - implements Comparable<ObjectName>, QueryExp { +public class ObjectName implements Comparable<ObjectName>, QueryExp { /** * A structure recording property structure and @@ -1781,7 +1780,6 @@ return getSerializedNameString(); } - @Override String toQueryString() { return "LIKE " + Query.value(toString()); }
--- a/src/share/classes/javax/management/OrQueryExp.java Mon Apr 21 11:24:04 2008 -0400 +++ b/src/share/classes/javax/management/OrQueryExp.java Tue Apr 22 18:58:40 2008 +0200 @@ -100,6 +100,7 @@ /** * Returns a string representation of this OrQueryExp */ + @Override public String toString() { return "(" + exp1 + ") or (" + exp2 + ")"; }
--- a/src/share/classes/javax/management/Query.java Mon Apr 21 11:24:04 2008 -0400 +++ b/src/share/classes/javax/management/Query.java Tue Apr 22 18:58:40 2008 +0200 @@ -979,8 +979,18 @@ if (query == null) return null; - if (query instanceof ToQueryString) - return ((ToQueryString) query).toQueryString(); + // This is ugly. At one stage we had a non-public class called + // ToQueryString with the toQueryString() method, and every class + // mentioned here inherited from that class. But that interfered + // with serialization of custom subclasses of e.g. QueryEval. Even + // though we could make it work by adding a public constructor to this + // non-public class, that seemed fragile because according to the + // serialization spec it shouldn't work. If only non-public interfaces + // could have non-public methods. + if (query instanceof ObjectName) + return ((ObjectName) query).toQueryString(); + if (query instanceof QueryEval) + return ((QueryEval) query).toQueryString(); return query.toString(); }
--- a/src/share/classes/javax/management/QueryEval.java Mon Apr 21 11:24:04 2008 -0400 +++ b/src/share/classes/javax/management/QueryEval.java Tue Apr 22 18:58:40 2008 +0200 @@ -25,20 +25,15 @@ package javax.management; - // java import import java.io.Serializable; -// RI import -import javax.management.MBeanServer; - - /** * Allows a query to be performed in the context of a specific MBean server. * * @since 1.5 */ -public abstract class QueryEval extends ToQueryString implements Serializable { +public abstract class QueryEval implements Serializable { /* Serial version */ private static final long serialVersionUID = 2675899265640874796L; @@ -80,4 +75,10 @@ public static MBeanServer getMBeanServer() { return server.get(); } + + // Subclasses in this package can override this method to return a different + // string. + String toQueryString() { + return toString(); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/query/CustomQueryTest.java Tue Apr 22 18:58:40 2008 +0200 @@ -0,0 +1,116 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6692027 + * @summary Check that custom subclasses of QueryEval can be serialized. + * @author Eamonn McManus + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.management.ManagementFactory; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.QueryEval; +import javax.management.QueryExp; + +public class CustomQueryTest { + public static interface CountMBean { + public int getCount(); + public void increment(); + } + + public static class Count implements CountMBean { + private AtomicInteger count = new AtomicInteger(); + + public int getCount() { + return count.get(); + } + + public void increment() { + count.incrementAndGet(); + } + + } + + public static final ObjectName countName; + static { + try { + countName = new ObjectName("d:type=Count"); + } catch (MalformedObjectNameException e) { + throw new AssertionError(e); + } + } + + /* A query that calls the increment method of the Count MBean every time + * it is evaluated. If there is no ObjectName filter, the query will be + * evaluated for every MBean in the MBean Server, so the count will be + * incremented by the number of MBeans. + */ + public static class IncrQuery extends QueryEval implements QueryExp { + public boolean apply(ObjectName name) { + try { + getMBeanServer().invoke(countName, "increment", null, null); + return true; + } catch (Throwable t) { + t.printStackTrace(); + System.exit(1); + throw new AssertionError(); // not reached + } + } + } + + public static void main(String[] args) throws Exception { + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + mbs.registerMBean(new Count(), countName); + int mbeanCount = mbs.getMBeanCount(); + QueryExp query = new IncrQuery(); + Set<ObjectName> names = mbs.queryNames(null, query); + assertEquals(mbeanCount, names.size()); + assertEquals(mbeanCount, mbs.getAttribute(countName, "Count")); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + ObjectOutputStream oout = new ObjectOutputStream(bout); + oout.writeObject(query); + oout.close(); + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream oin = new ObjectInputStream(bin); + query = (QueryExp) oin.readObject(); + names = mbs.queryNames(null, query); + assertEquals(mbeanCount * 2, mbs.getAttribute(countName, "Count")); + } + + private static void assertEquals(Object expected, Object actual) + throws Exception { + if (!expected.equals(actual)) { + String failure = "FAILED: expected " + expected + ", got " + actual; + throw new Exception(failure); + } + } +}