src/share/jaxws_classes/com/sun/xml/internal/ws/server/MonitorBase.java

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 368
0989ad8c0860
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

ohair@286 1 /*
ohair@286 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
ohair@286 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ohair@286 4 *
ohair@286 5 * This code is free software; you can redistribute it and/or modify it
ohair@286 6 * under the terms of the GNU General Public License version 2 only, as
ohair@286 7 * published by the Free Software Foundation. Oracle designates this
ohair@286 8 * particular file as subject to the "Classpath" exception as provided
ohair@286 9 * by Oracle in the LICENSE file that accompanied this code.
ohair@286 10 *
ohair@286 11 * This code is distributed in the hope that it will be useful, but WITHOUT
ohair@286 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ohair@286 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ohair@286 14 * version 2 for more details (a copy is included in the LICENSE file that
ohair@286 15 * accompanied this code).
ohair@286 16 *
ohair@286 17 * You should have received a copy of the GNU General Public License version
ohair@286 18 * 2 along with this work; if not, write to the Free Software Foundation,
ohair@286 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ohair@286 20 *
ohair@286 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@286 22 * or visit www.oracle.com if you need additional information or have any
ohair@286 23 * questions.
ohair@286 24 */
ohair@286 25
ohair@286 26 package com.sun.xml.internal.ws.server;
ohair@286 27
ohair@286 28 import com.sun.istack.internal.NotNull;
ohair@286 29 import com.sun.istack.internal.Nullable;
ohair@286 30 import com.sun.xml.internal.ws.api.EndpointAddress;
ohair@286 31 import com.sun.xml.internal.ws.api.config.management.policy.ManagedClientAssertion;
ohair@286 32 import com.sun.xml.internal.ws.api.config.management.policy.ManagedServiceAssertion;
ohair@286 33 import com.sun.xml.internal.ws.api.config.management.policy.ManagementAssertion.Setting;
ohair@286 34 import com.sun.xml.internal.ws.api.server.BoundEndpoint;
ohair@286 35 import com.sun.xml.internal.ws.api.server.Container;
ohair@286 36 import com.sun.xml.internal.ws.api.server.Module;
ohair@286 37 import com.sun.xml.internal.ws.api.server.WSEndpoint;
ohair@286 38 import com.sun.xml.internal.ws.client.Stub;
ohair@286 39 import com.sun.org.glassfish.external.amx.AMXGlassfish;
ohair@286 40 import com.sun.org.glassfish.gmbal.Description;
ohair@286 41 import com.sun.org.glassfish.gmbal.InheritedAttribute;
ohair@286 42 import com.sun.org.glassfish.gmbal.InheritedAttributes;
ohair@286 43 import com.sun.org.glassfish.gmbal.ManagedData;
ohair@286 44 import com.sun.org.glassfish.gmbal.ManagedObjectManager;
ohair@286 45 import com.sun.org.glassfish.gmbal.ManagedObjectManagerFactory;
ohair@286 46 import java.io.IOException;
ohair@286 47 import java.lang.reflect.*;
ohair@286 48 import java.net.URL;
ohair@286 49 import java.util.List;
ohair@286 50 import java.util.logging.Level;
ohair@286 51 import java.util.logging.Logger;
ohair@286 52 import javax.management.ObjectName;
ohair@286 53 import javax.xml.namespace.QName;
ohair@286 54
ohair@286 55 // BEGIN IMPORTS FOR RewritingMOM
ohair@286 56 import java.util.ResourceBundle ;
ohair@286 57 import java.io.Closeable ;
ohair@286 58 import java.lang.reflect.AnnotatedElement ;
ohair@286 59 import java.lang.annotation.Annotation ;
ohair@286 60 import javax.management.ObjectName ;
ohair@286 61 import javax.management.MBeanServer ;
ohair@286 62 import com.sun.org.glassfish.gmbal.AMXClient;
ohair@286 63 import com.sun.org.glassfish.gmbal.GmbalMBean;
ohair@286 64 // END IMPORTS FOR RewritingMOM
ohair@286 65
ohair@286 66 /**
ohair@286 67 * @author Harold Carr
ohair@286 68 */
ohair@286 69 public abstract class MonitorBase {
ohair@286 70
ohair@286 71 private static final Logger logger = Logger.getLogger(
ohair@286 72 com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".monitoring");
ohair@286 73
ohair@286 74 /**
ohair@286 75 * Endpoint monitoring is ON by default.
ohair@286 76 *
ohair@286 77 * prop | no assert | assert/no mon | assert/mon off | assert/mon on
ohair@286 78 * -------------------------------------------------------------------
ohair@286 79 * not set | on | on | off | on
ohair@286 80 * false | off | off | off | off
ohair@286 81 * true | on | on | off | on
ohair@286 82 */
ohair@286 83 @NotNull public ManagedObjectManager createManagedObjectManager(final WSEndpoint endpoint) {
ohair@286 84 // serviceName + portName identifies the managed objects under it.
ohair@286 85 // There can be multiple services in the container.
ohair@286 86 // The same serviceName+portName can live in different apps at
ohair@286 87 // different endpoint addresses.
ohair@286 88 //
ohair@286 89 // In general, monitoring will add -N, where N is unique integer,
ohair@286 90 // in case of collisions.
ohair@286 91 //
ohair@286 92 // The endpoint address would be unique, but we do not know
ohair@286 93 // the endpoint address until the first request comes in,
ohair@286 94 // which is after monitoring is setup.
ohair@286 95
ohair@286 96 String rootName =
ohair@286 97 endpoint.getServiceName().getLocalPart()
ohair@286 98 + "-"
ohair@286 99 + endpoint.getPortName().getLocalPart();
ohair@286 100
ohair@286 101 if (rootName.equals("-")) {
ohair@286 102 rootName = "provider";
ohair@286 103 }
ohair@286 104
ohair@286 105 // contextPath is not always available
ohair@286 106 final String contextPath = getContextPath(endpoint);
ohair@286 107 if (contextPath != null) {
ohair@286 108 rootName = contextPath + "-" + rootName;
ohair@286 109 }
ohair@286 110
ohair@286 111 final ManagedServiceAssertion assertion =
ohair@286 112 ManagedServiceAssertion.getAssertion(endpoint);
ohair@286 113 if (assertion != null) {
ohair@286 114 final String id = assertion.getId();
ohair@286 115 if (id != null) {
ohair@286 116 rootName = id;
ohair@286 117 }
ohair@286 118 if (assertion.monitoringAttribute() == Setting.OFF) {
ohair@286 119 return disabled("This endpoint", rootName);
ohair@286 120 }
ohair@286 121 }
ohair@286 122
ohair@286 123 if (endpointMonitoring.equals(Setting.OFF)) {
ohair@286 124 return disabled("Global endpoint", rootName);
ohair@286 125 }
ohair@286 126 return createMOMLoop(rootName, 0);
ohair@286 127 }
ohair@286 128
ohair@286 129 private String getContextPath(final WSEndpoint endpoint) {
ohair@286 130 try {
ohair@286 131 Container container = endpoint.getContainer();
ohair@286 132 Method getSPI =
ohair@286 133 container.getClass().getDeclaredMethod("getSPI", Class.class);
ohair@286 134 getSPI.setAccessible(true);
ohair@286 135 Class servletContextClass =
ohair@286 136 Class.forName("javax.servlet.ServletContext");
ohair@286 137 Object servletContext =
ohair@286 138 getSPI.invoke(container, servletContextClass);
ohair@286 139 if (servletContext != null) {
ohair@286 140 Method getContextPath = servletContextClass.getDeclaredMethod("getContextPath");
ohair@286 141 getContextPath.setAccessible(true);
ohair@286 142 return (String) getContextPath.invoke(servletContext);
ohair@286 143 }
ohair@286 144 return null;
ohair@286 145 } catch (Throwable t) {
ohair@286 146 logger.log(Level.FINEST, "getContextPath", t);
ohair@286 147 }
ohair@286 148 return null;
ohair@286 149 }
ohair@286 150
ohair@286 151 /**
ohair@286 152 * Client monitoring is OFF by default because there is
ohair@286 153 * no standard stub.close() method. Therefore people do
ohair@286 154 * not typically close a stub when they are done with it
ohair@286 155 * (even though the RI does provide a .close).
ohair@286 156 * <pre>
ohair@286 157 * prop | no assert | assert/no mon | assert/mon off | assert/mon on
ohair@286 158 * -------------------------------------------------------------------
ohair@286 159 * not set | off | off | off | on
ohair@286 160 * false | off | off | off | off
ohair@286 161 * true | on | on | off | on
ohair@286 162 * </pre>
ohair@286 163 */
ohair@286 164 @NotNull public ManagedObjectManager createManagedObjectManager(final Stub stub) {
ohair@286 165 EndpointAddress ea = stub.requestContext.getEndpointAddress();
ohair@286 166 if (ea == null) {
ohair@286 167 return ManagedObjectManagerFactory.createNOOP();
ohair@286 168 }
ohair@286 169
ohair@286 170 String rootName = ea.toString();
ohair@286 171
ohair@286 172 final ManagedClientAssertion assertion =
ohair@286 173 ManagedClientAssertion.getAssertion(stub.getPortInfo());
ohair@286 174 if (assertion != null) {
ohair@286 175 final String id = assertion.getId();
ohair@286 176 if (id != null) {
ohair@286 177 rootName = id;
ohair@286 178 }
ohair@286 179 if (assertion.monitoringAttribute() == Setting.OFF) {
ohair@286 180 return disabled("This client", rootName);
ohair@286 181 } else if (assertion.monitoringAttribute() == Setting.ON &&
ohair@286 182 clientMonitoring != Setting.OFF) {
ohair@286 183 return createMOMLoop(rootName, 0);
ohair@286 184 }
ohair@286 185 }
ohair@286 186
ohair@286 187 if (clientMonitoring == Setting.NOT_SET ||
ohair@286 188 clientMonitoring == Setting.OFF)
ohair@286 189 {
ohair@286 190 return disabled("Global client", rootName);
ohair@286 191 }
ohair@286 192 return createMOMLoop(rootName, 0);
ohair@286 193 }
ohair@286 194
ohair@286 195 @NotNull private ManagedObjectManager disabled(final String x, final String rootName) {
ohair@286 196 final String msg = x + " monitoring disabled. " + rootName + " will not be monitored";
ohair@286 197 logger.log(Level.CONFIG, msg);
ohair@286 198 return ManagedObjectManagerFactory.createNOOP();
ohair@286 199 }
ohair@286 200
ohair@286 201 private @NotNull ManagedObjectManager createMOMLoop(final String rootName, final int unique) {
ohair@286 202 final boolean isFederated = AMXGlassfish.getGlassfishVersion() != null;
ohair@286 203 ManagedObjectManager mom = createMOM(isFederated);
ohair@286 204 mom = initMOM(mom);
ohair@286 205 mom = createRoot(mom, rootName, unique);
ohair@286 206 return mom;
ohair@286 207 }
ohair@286 208
ohair@286 209 private @NotNull ManagedObjectManager createMOM(final boolean isFederated) {
ohair@286 210 try {
ohair@286 211 return new RewritingMOM(isFederated ?
ohair@286 212 ManagedObjectManagerFactory.createFederated(
ohair@286 213 AMXGlassfish.DEFAULT.serverMon(AMXGlassfish.DEFAULT.dasName()))
ohair@286 214 :
ohair@286 215 ManagedObjectManagerFactory.createStandalone("com.sun.metro"));
ohair@286 216 } catch (Throwable t) {
ohair@286 217 if (isFederated) {
ohair@286 218 logger.log(Level.CONFIG, "Problem while attempting to federate with GlassFish AMX monitoring. Trying standalone.", t);
ohair@286 219 return createMOM(false);
ohair@286 220 } else {
ohair@286 221 logger.log(Level.WARNING, "Ignoring exception - starting up without monitoring", t);
ohair@286 222 return ManagedObjectManagerFactory.createNOOP();
ohair@286 223 }
ohair@286 224 }
ohair@286 225 }
ohair@286 226
ohair@286 227 private @NotNull ManagedObjectManager initMOM(final ManagedObjectManager mom) {
ohair@286 228 try {
ohair@286 229 if (typelibDebug != -1) {
ohair@286 230 mom.setTypelibDebug(typelibDebug);
ohair@286 231 }
ohair@286 232 if (registrationDebug.equals("FINE")) {
ohair@286 233 mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.FINE);
ohair@286 234 } else if (registrationDebug.equals("NORMAL")) {
ohair@286 235 mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.NORMAL);
ohair@286 236 } else {
ohair@286 237 mom.setRegistrationDebug(ManagedObjectManager.RegistrationDebugLevel.NONE);
ohair@286 238 }
ohair@286 239
ohair@286 240 mom.setRuntimeDebug(runtimeDebug);
ohair@286 241
ohair@286 242 // Instead of GMBAL throwing an exception and logging
ohair@286 243 // duplicate name, just have it return null.
ohair@286 244 mom.suppressDuplicateRootReport(true);
ohair@286 245
ohair@286 246 mom.stripPrefix(
ohair@286 247 "com.sun.xml.internal.ws.server",
ohair@286 248 "com.sun.xml.internal.ws.rx.rm.runtime.sequence");
ohair@286 249
ohair@286 250 // Add annotations to a standard class
ohair@286 251 mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(ManagedData.class));
ohair@286 252 mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(Description.class));
ohair@286 253 mom.addAnnotation(javax.xml.ws.WebServiceFeature.class, DummyWebServiceFeature.class.getAnnotation(InheritedAttributes.class));
ohair@286 254
ohair@286 255 // Defer so we can register "this" as root from
ohair@286 256 // within constructor.
ohair@286 257 mom.suspendJMXRegistration();
ohair@286 258
ohair@286 259 } catch (Throwable t) {
ohair@286 260 try {
ohair@286 261 mom.close();
ohair@286 262 } catch (IOException e) {
ohair@286 263 logger.log(Level.CONFIG, "Ignoring exception caught when closing unused ManagedObjectManager", e);
ohair@286 264 }
ohair@286 265 logger.log(Level.WARNING, "Ignoring exception - starting up without monitoring", t);
ohair@286 266 return ManagedObjectManagerFactory.createNOOP();
ohair@286 267 }
ohair@286 268 return mom;
ohair@286 269 }
ohair@286 270
ohair@286 271 private ManagedObjectManager createRoot(final ManagedObjectManager mom, final String rootName, int unique) {
ohair@286 272 final String name = rootName + (unique == 0 ? "" : "-" + String.valueOf(unique));
ohair@286 273 try {
ohair@286 274 final Object ignored = mom.createRoot(this, name);
ohair@286 275 if (ignored != null) {
ohair@286 276 ObjectName ignoredName = mom.getObjectName(mom.getRoot());
ohair@286 277 // The name is null when the MOM is a NOOP.
ohair@286 278 if (ignoredName != null) {
ohair@286 279 logger.log(Level.INFO, "Metro monitoring rootname successfully set to: " + ignoredName);
ohair@286 280 }
ohair@286 281 return mom;
ohair@286 282 }
ohair@286 283 try {
ohair@286 284 mom.close();
ohair@286 285 } catch (IOException e) {
ohair@286 286 logger.log(Level.CONFIG, "Ignoring exception caught when closing unused ManagedObjectManager", e);
ohair@286 287 }
ohair@286 288 final String basemsg ="Duplicate Metro monitoring rootname: " + name + " : ";
ohair@286 289 if (unique > maxUniqueEndpointRootNameRetries) {
ohair@286 290 final String msg = basemsg + "Giving up.";
ohair@286 291 logger.log(Level.INFO, msg);
ohair@286 292 return ManagedObjectManagerFactory.createNOOP();
ohair@286 293 }
ohair@286 294 final String msg = basemsg + "Will try to make unique";
ohair@286 295 logger.log(Level.CONFIG, msg);
ohair@286 296 return createMOMLoop(rootName, ++unique);
ohair@286 297 } catch (Throwable t) {
ohair@286 298 logger.log(Level.WARNING, "Error while creating monitoring root with name: " + rootName, t);
ohair@286 299 return ManagedObjectManagerFactory.createNOOP();
ohair@286 300 }
ohair@286 301 }
ohair@286 302
ohair@286 303 public static void closeMOM(ManagedObjectManager mom) {
ohair@286 304 try {
ohair@286 305 final ObjectName name = mom.getObjectName(mom.getRoot());
ohair@286 306 // The name is null when the MOM is a NOOP.
ohair@286 307 if (name != null) {
ohair@286 308 logger.log(Level.INFO, "Closing Metro monitoring root: " + name);
ohair@286 309 }
ohair@286 310 mom.close();
ohair@286 311 } catch (java.io.IOException e) {
ohair@286 312 logger.log(Level.WARNING, "Ignoring error when closing Managed Object Manager", e);
ohair@286 313 }
ohair@286 314 }
ohair@286 315
ohair@286 316 private static Setting clientMonitoring = Setting.NOT_SET;
ohair@286 317 private static Setting endpointMonitoring = Setting.NOT_SET;
ohair@286 318 private static int typelibDebug = -1;
ohair@286 319 private static String registrationDebug = "NONE";
ohair@286 320 private static boolean runtimeDebug = false;
ohair@286 321 private static int maxUniqueEndpointRootNameRetries = 100;
ohair@286 322 private static final String monitorProperty = "com.sun.xml.internal.ws.monitoring.";
ohair@286 323
ohair@286 324 private static Setting propertyToSetting(String propName) {
ohair@286 325 String s = System.getProperty(propName);
ohair@286 326 if (s == null) {
ohair@286 327 return Setting.NOT_SET;
ohair@286 328 }
ohair@286 329 s = s.toLowerCase();
ohair@286 330 if (s.equals("false") || s.equals("off")) {
ohair@286 331 return Setting.OFF;
ohair@286 332 } else if (s.equals("true") || s.equals("on")) {
ohair@286 333 return Setting.ON;
ohair@286 334 }
ohair@286 335 return Setting.NOT_SET;
ohair@286 336 }
ohair@286 337
ohair@286 338 static {
ohair@286 339 try {
ohair@286 340 endpointMonitoring = propertyToSetting(monitorProperty + "endpoint");
ohair@286 341
ohair@286 342 clientMonitoring = propertyToSetting(monitorProperty + "client");
ohair@286 343
ohair@286 344 Integer i = Integer.getInteger(monitorProperty + "typelibDebug");
ohair@286 345 if (i != null) {
ohair@286 346 typelibDebug = i;
ohair@286 347 }
ohair@286 348
ohair@286 349 String s = System.getProperty(monitorProperty + "registrationDebug");
ohair@286 350 if (s != null) {
ohair@286 351 registrationDebug = s.toUpperCase();
ohair@286 352 }
ohair@286 353
ohair@286 354 s = System.getProperty(monitorProperty + "runtimeDebug");
ohair@286 355 if (s != null && s.toLowerCase().equals("true")) {
ohair@286 356 runtimeDebug = true;
ohair@286 357 }
ohair@286 358
ohair@286 359 i = Integer.getInteger(monitorProperty + "maxUniqueEndpointRootNameRetries");
ohair@286 360 if (i != null) {
ohair@286 361 maxUniqueEndpointRootNameRetries = i;
ohair@286 362 }
ohair@286 363 } catch (Exception e) {
ohair@286 364 logger.log(Level.WARNING, "Error while reading monitoring properties", e);
ohair@286 365 }
ohair@286 366 }
ohair@286 367 }
ohair@286 368
ohair@286 369
ohair@286 370 // This enables us to annotate the WebServiceFeature class even thought
ohair@286 371 // we can't explicitly put the annotations in the class itself.
ohair@286 372 @ManagedData
ohair@286 373 @Description("WebServiceFeature")
ohair@286 374 @InheritedAttributes({
ohair@286 375 @InheritedAttribute(methodName="getID", description="unique id for this feature"),
ohair@286 376 @InheritedAttribute(methodName="isEnabled", description="true if this feature is enabled")
ohair@286 377 })
ohair@286 378 interface DummyWebServiceFeature {}
ohair@286 379
ohair@286 380 class RewritingMOM implements ManagedObjectManager
ohair@286 381 {
ohair@286 382 private final ManagedObjectManager mom;
ohair@286 383
ohair@286 384 private final static String gmbalQuotingCharsRegex = "\n|\\|\"|\\*|\\?|:|=|,";
ohair@286 385 private final static String jmxQuotingCharsRegex = ",|=|:|\"";
ohair@286 386 private final static String replacementChar = "-";
ohair@286 387
ohair@286 388 RewritingMOM(final ManagedObjectManager mom) { this.mom = mom; }
ohair@286 389
ohair@286 390 private String rewrite(final String x) {
ohair@286 391 return x.replaceAll(gmbalQuotingCharsRegex, replacementChar);
ohair@286 392 }
ohair@286 393
ohair@286 394 // The interface
ohair@286 395
ohair@286 396 public void suspendJMXRegistration() { mom.suspendJMXRegistration(); }
ohair@286 397 public void resumeJMXRegistration() { mom.resumeJMXRegistration(); }
ohair@286 398 public GmbalMBean createRoot() { return mom.createRoot(); }
ohair@286 399 public GmbalMBean createRoot(Object root) { return mom.createRoot(root); }
ohair@286 400 public GmbalMBean createRoot(Object root, String name) {
ohair@286 401 return mom.createRoot(root, rewrite(name));
ohair@286 402 }
ohair@286 403 public Object getRoot() { return mom.getRoot(); }
ohair@286 404 public GmbalMBean register(Object parent, Object obj, String name) {
ohair@286 405 return mom.register(parent, obj, rewrite(name));
ohair@286 406 }
ohair@286 407 public GmbalMBean register(Object parent, Object obj) { return mom.register(parent, obj);}
ohair@286 408 public GmbalMBean registerAtRoot(Object obj, String name) {
ohair@286 409 return mom.registerAtRoot(obj, rewrite(name));
ohair@286 410 }
ohair@286 411 public GmbalMBean registerAtRoot(Object obj) { return mom.registerAtRoot(obj); }
ohair@286 412 public void unregister(Object obj) { mom.unregister(obj); }
ohair@286 413 public ObjectName getObjectName(Object obj) { return mom.getObjectName(obj); }
ohair@286 414 public AMXClient getAMXClient(Object obj) { return mom.getAMXClient(obj); }
ohair@286 415 public Object getObject(ObjectName oname) { return mom.getObject(oname); }
ohair@286 416 public void stripPrefix(String... str) { mom.stripPrefix(str); }
ohair@286 417 public void stripPackagePrefix() { mom.stripPackagePrefix(); }
ohair@286 418 public String getDomain() { return mom.getDomain(); }
ohair@286 419 public void setMBeanServer(MBeanServer server){mom.setMBeanServer(server); }
ohair@286 420 public MBeanServer getMBeanServer() { return mom.getMBeanServer(); }
ohair@286 421 public void setResourceBundle(ResourceBundle rb) { mom.setResourceBundle(rb); }
ohair@286 422 public ResourceBundle getResourceBundle() { return mom.getResourceBundle(); }
ohair@286 423 public void addAnnotation(AnnotatedElement element, Annotation annotation) { mom.addAnnotation(element, annotation); }
ohair@286 424 public void setRegistrationDebug(RegistrationDebugLevel level) { mom.setRegistrationDebug(level); }
ohair@286 425 public void setRuntimeDebug(boolean flag) { mom.setRuntimeDebug(flag); }
ohair@286 426 public void setTypelibDebug(int level) { mom.setTypelibDebug(level); }
ohair@286 427 public String dumpSkeleton(Object obj) { return mom.dumpSkeleton(obj); }
ohair@286 428 public void suppressDuplicateRootReport(boolean suppressReport) { mom.suppressDuplicateRootReport(suppressReport); }
ohair@286 429 public void close() throws IOException { mom.close(); }
ohair@286 430 public void setJMXRegistrationDebug(boolean x) { mom.setJMXRegistrationDebug(x); }
ohair@286 431 public boolean isManagedObject(Object x) { return mom.isManagedObject(x); }
ohair@286 432 }
ohair@286 433
ohair@286 434 // End of file.

mercurial