// Create a single dispatcher
 private RequestDispatcher createDispatcher(
     String pDispatcherClass,
     Converters pConverters,
     ServerHandle pServerHandle,
     Restrictor pRestrictor) {
   try {
     Class clazz = this.getClass().getClassLoader().loadClass(pDispatcherClass);
     Constructor constructor =
         clazz.getConstructor(Converters.class, ServerHandle.class, Restrictor.class);
     return (RequestDispatcher) constructor.newInstance(pConverters, pServerHandle, pRestrictor);
   } catch (ClassNotFoundException e) {
     throw new IllegalArgumentException("Couldn't load class " + pDispatcherClass + ": " + e, e);
   } catch (NoSuchMethodException e) {
     throw new IllegalArgumentException(
         "Class " + pDispatcherClass + " has invalid constructor: " + e, e);
   } catch (IllegalAccessException e) {
     throw new IllegalArgumentException(
         "Constructor of " + pDispatcherClass + " couldn't be accessed: " + e, e);
   } catch (InvocationTargetException e) {
     throw new IllegalArgumentException(e);
   } catch (InstantiationException e) {
     throw new IllegalArgumentException(pDispatcherClass + " couldn't be instantiated: " + e, e);
   }
 }
  public static void main(String[] args) throws Exception {
    System.out.println(
        "Checking that all known MBeans that are "
            + "NotificationBroadcasters have sane "
            + "MBeanInfo.getNotifications()");

    System.out.println("Checking platform MBeans...");
    checkPlatformMBeans();

    URL codeBase = ClassLoader.getSystemResource("javax/management/MBeanServer.class");
    if (codeBase == null) {
      throw new Exception("Could not determine codeBase for " + MBeanServer.class);
    }

    System.out.println();
    System.out.println("Looking for standard MBeans...");
    String[] classes = findStandardMBeans(codeBase);

    System.out.println("Testing standard MBeans...");
    for (int i = 0; i < classes.length; i++) {
      String name = classes[i];
      Class<?> c;
      try {
        c = Class.forName(name);
      } catch (Throwable e) {
        System.out.println(name + ": cannot load (not public?): " + e);
        continue;
      }
      if (!NotificationBroadcaster.class.isAssignableFrom(c)) {
        System.out.println(name + ": not a NotificationBroadcaster");
        continue;
      }
      if (Modifier.isAbstract(c.getModifiers())) {
        System.out.println(name + ": abstract class");
        continue;
      }

      NotificationBroadcaster mbean;
      Constructor<?> constr;
      try {
        constr = c.getConstructor();
      } catch (Exception e) {
        System.out.println(name + ": no public no-arg constructor: " + e);
        continue;
      }
      try {
        mbean = (NotificationBroadcaster) constr.newInstance();
      } catch (Exception e) {
        System.out.println(name + ": no-arg constructor failed: " + e);
        continue;
      }

      check(mbean);
    }

    System.out.println();
    System.out.println("Testing some explicit cases...");

    check(new RelationService(false));
    /*
      We can't do this:
        check(new RequiredModelMBean());
      because the Model MBean spec more or less forces us to use the
      names GENERIC and ATTRIBUTE_CHANGE for its standard notifs.
    */
    checkRMIConnectorServer();

    System.out.println();
    if (!suspicious.isEmpty()) System.out.println("SUSPICIOUS CLASSES: " + suspicious);

    if (failed.isEmpty()) System.out.println("TEST PASSED");
    else {
      System.out.println("TEST FAILED: " + failed);
      System.exit(1);
    }
  }