6692027: Custom subclasses of QueryEval don't serialize
Remove non-public superclass of QueryEval Reviewed-by: dfuchs
This commit is contained in:
parent
3c827ac2b0
commit
1ca7f71818
jdk
src/share/classes/javax/management
AndQueryExp.javaBetweenQueryExp.javaBinaryRelQueryExp.javaNotQueryExp.javaObjectName.javaOrQueryExp.javaQuery.javaQueryEval.java
test/javax/management/query
@ -100,12 +100,13 @@ class AndQueryExp extends QueryEval implements QueryExp {
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
@ -135,6 +135,7 @@ class BetweenQueryExp extends QueryEval implements QueryExp {
|
||||
/**
|
||||
* Returns the string representing the object.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + exp1 + ") between (" + exp2 + ") and (" + exp3 + ")";
|
||||
}
|
||||
|
@ -187,11 +187,11 @@ class BinaryRelQueryExp extends QueryEval implements QueryExp {
|
||||
/**
|
||||
* Returns the string representing the object.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + exp1 + ") " + relOpString() + " (" + exp2 + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
String toQueryString() {
|
||||
return exp1 + " " + relOpString() + " " + exp2;
|
||||
}
|
||||
|
@ -91,7 +91,6 @@ class NotQueryExp extends QueryEval implements QueryExp {
|
||||
return "not (" + exp + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
String toQueryString() {
|
||||
return "not (" + Query.toString(exp) + ")";
|
||||
}
|
||||
|
@ -223,8 +223,7 @@ import javax.management.QueryExp;
|
||||
* @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 @@ public class ObjectName extends ToQueryString
|
||||
return getSerializedNameString();
|
||||
}
|
||||
|
||||
@Override
|
||||
String toQueryString() {
|
||||
return "LIKE " + Query.value(toString());
|
||||
}
|
||||
|
@ -100,6 +100,7 @@ class OrQueryExp extends QueryEval implements QueryExp {
|
||||
/**
|
||||
* Returns a string representation of this OrQueryExp
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + exp1 + ") or (" + exp2 + ")";
|
||||
}
|
||||
|
@ -979,8 +979,18 @@ package javax.management;
|
||||
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();
|
||||
}
|
||||
|
@ -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 abstract class QueryEval extends ToQueryString implements Serializable {
|
||||
public static MBeanServer getMBeanServer() {
|
||||
return server.get();
|
||||
}
|
||||
|
||||
// Subclasses in this package can override this method to return a different
|
||||
// string.
|
||||
String toQueryString() {
|
||||
return toString();
|
||||
}
|
||||
}
|
||||
|
116
jdk/test/javax/management/query/CustomQueryTest.java
Normal file
116
jdk/test/javax/management/query/CustomQueryTest.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user