public synchronized IHostedThread getLoadingRobotProxy(Thread t) {
   if (t != null
       && robotLoaderThread != null
       && (t.equals(robotLoaderThread)
           || (t.getThreadGroup() != null
               && t.getThreadGroup().equals(robotLoaderThread.getThreadGroup())))) {
     return loadingRobot;
   }
   return null;
 }
    private String stringFromTracesAndNames(
        Map<Thread, StackTraceElement[]> traces, Map<Thread, String> names) {
      String trace = null;
      if (traces != null) {
        String capturedThreadName = null;
        if (names == null) {
          capturedThreadName = Thread.currentThread().getName();
        } else {
          capturedThreadName = names.get(Thread.currentThread());
        }

        StringBuilder sb = new StringBuilder();
        sb.append("\nRequest Thread Name: ").append(capturedThreadName).append("\n\n");
        for (Iterator iterator = traces.keySet().iterator(); iterator.hasNext(); ) {
          Thread t = (Thread) iterator.next();
          StackTraceElement stack[] = traces.get(t);
          String name = t.getName() != null ? t.getName() : "No name";
          String groupName = t.getThreadGroup() != null ? t.getThreadGroup().getName() : "No group";

          if (stack != null
              && stack.length > 2
              && !name.equals("main")
              && !name.equals("ERXStopWatchTimer")
              && !groupName.equals("system")) {
            StackTraceElement func = stack[0];
            if (func != null
                && func.getClassName() != null
                && !func.getClassName().equals("java.net.PlainSocketImpl")) {
              if (names != null) {
                String customThreadName = names.get(t);
                if (customThreadName != null) {
                  sb.append(customThreadName).append(":\n");
                }
              }
              sb.append(t).append(":\n");
              for (int i = 0; i < stack.length; i++) {
                StackTraceElement stackTraceElement = stack[i];
                sb.append("\tat ").append(stackTraceElement).append('\n');
              }
            }
          }
        }
        sb.insert(0, '\n');
        trace = sb.toString();
        // trace =
        // trace.replaceAll("at\\s+(com.webobjects|java|er|sun)\\..*?\\n",
        // "...\n");
        // trace = trace.replaceAll("(\t\\.\\.\\.\n+)+", "\t...\n");
      } else {
        trace = "";
      }
      return trace;
    }
  @Override
  public void checkAccess(ThreadGroup g) {
    if (!isSecutityOn) {
      return;
    }
    Thread c = Thread.currentThread();

    if (isSafeThread(c)) {
      return;
    }
    super.checkAccess(g);

    final ThreadGroup cg = c.getThreadGroup();

    if (cg == null) {
      // What the heck is going on here?  JDK 1.3 is sending me a dead thread.
      // This crashes the entire jvm if I don't return here.
      return;
    }

    IHostedThread robotProxy = threadManager.getLoadedOrLoadingRobotProxy(c);

    if (robotProxy == null) {
      throw new AccessControlException(
          "Preventing " + c.getName() + " from access to " + g.getName());
    }

    if (cg.activeCount() > 5) {
      String message = "Robots are only allowed to create up to 5 threads!";

      robotProxy.punishSecurityViolation(message);
      throw new AccessControlException(message);
    }
  }
Example #4
1
  @Test
  public void testShutdownWithSleepReturnsAfterAllThreadsAreStopped() throws Exception {
    Map<Thread, StackTraceElement[]> allThreadsStart = Thread.getAllStackTraces();
    int threadPoolSize = 5;
    Scheduler scheduler =
        createScheduler("testShutdownWithSleepReturnsAfterAllThreadsAreStopped", threadPoolSize);

    Map<Thread, StackTraceElement[]> allThreadsRunning = Thread.getAllStackTraces();

    scheduler.shutdown(true);

    Map<Thread, StackTraceElement[]> allThreadsEnd = Thread.getAllStackTraces();
    Set<Thread> endingThreads = new HashSet<Thread>(allThreadsEnd.keySet());
    // remove all pre-existing threads from the set
    for (Thread t : allThreadsStart.keySet()) {
      allThreadsEnd.remove(t);
    }
    // remove threads that are known artifacts of the test
    for (Thread t : endingThreads) {
      if (t.getName().contains("derby") && t.getThreadGroup().getName().contains("derby")) {
        allThreadsEnd.remove(t);
      }
      if (t.getThreadGroup() != null && t.getThreadGroup().getName().equals("system")) {
        allThreadsEnd.remove(t);
      }
      if (t.getThreadGroup() != null && t.getThreadGroup().getName().equals("main")) {
        allThreadsEnd.remove(t);
      }
    }
    if (allThreadsEnd.size() > 0) {
      // log the additional threads
      for (Thread t : allThreadsEnd.keySet()) {
        System.out.println(
            "*** Found additional thread: "
                + t.getName()
                + " (of type "
                + t.getClass().getName()
                + ")  in group: "
                + t.getThreadGroup().getName()
                + " with parent group: "
                + (t.getThreadGroup().getParent() == null
                    ? "-none-"
                    : t.getThreadGroup().getParent().getName()));
      }
      // log all threads that were running before shutdown
      for (Thread t : allThreadsRunning.keySet()) {
        System.out.println(
            "- Test runtime thread: "
                + t.getName()
                + " (of type "
                + t.getClass().getName()
                + ")  in group: "
                + (t.getThreadGroup() == null
                    ? "-none-"
                    : (t.getThreadGroup().getName()
                        + " with parent group: "
                        + (t.getThreadGroup().getParent() == null
                            ? "-none-"
                            : t.getThreadGroup().getParent().getName()))));
      }
    }
    assertTrue(
        "Found unexpected new threads (see console output for listing)", allThreadsEnd.size() == 0);
  }
  /**
   * Returns the clone of <code>o_</code>. It calls <code>o_.clone()</code>, if possible, and either
   * raises an exception or returns null if fails.
   *
   * @param raiseException_ set to true if one wishes to get exception instead of receiving null
   *     when this method fails to call <code>o_.clone()</code>.
   */
  public static Object clone(Object o_, boolean raiseException_) {
    if (o_ == null) return null;
    if (o_ instanceof String) return o_;

    try {
      if (o_ instanceof drcl.ObjectCloneable) return ((drcl.ObjectCloneable) o_).clone();
      if (o_.getClass().isArray()) {
        int length_ = Array.getLength(o_);
        Class componentType_ = o_.getClass().getComponentType();
        Object that_ = Array.newInstance(componentType_, length_);
        if (componentType_.isPrimitive()) System.arraycopy(o_, 0, that_, 0, length_);
        else {
          for (int i = 0; i < length_; i++)
            Array.set(that_, i, clone(Array.get(o_, i), raiseException_));
        }
        return that_;
      }
      Method m_ = o_.getClass().getMethod("clone", null);
      return m_.invoke(o_, null);
    } catch (Exception e_) {
      if (raiseException_) {
        Thread t_ = Thread.currentThread();
        t_.getThreadGroup().uncaughtException(t_, e_);
      }
      return null;
    }
  }
  @Override
  public void checkAccess(Thread t) {
    if (!isSecutityOn) {
      return;
    }

    Thread c = Thread.currentThread();

    if (isSafeThread(c)) {
      return;
    }
    super.checkAccess(t);

    // Threads belonging to other thread groups is not allowed to access threads belonging to other
    // thread groups
    // Bug fix [3021140] Possible for robot to kill other robot threads.
    // In the following the thread group of the current thread must be in the thread group hierarchy
    // of the
    // attacker thread; otherwise an AccessControlException must be thrown.

    boolean found = false;

    ThreadGroup cg = c.getThreadGroup();
    ThreadGroup tg = t.getThreadGroup();

    while (tg != null) {
      if (tg == cg) {
        found = true;
        break;
      }
      try {
        tg = tg.getParent();
      } catch (AccessControlException e) {
        // We expect an AccessControlException due to missing RuntimePermission modifyThreadGroup
        break;
      }
    }
    if (!found) {
      String message = "Preventing " + c.getName() + " from access to " + t.getName();
      IHostedThread robotProxy = threadManager.getLoadedOrLoadingRobotProxy(c);

      if (robotProxy != null) {
        robotProxy.punishSecurityViolation(message);
      }
      throw new AccessControlException(message);
    }
  }
Example #7
0
 public static String getThreadSignature() {
   Thread t = Thread.currentThread();
   long l = t.getId();
   String name = t.getName();
   long p = t.getPriority();
   String gname = t.getThreadGroup().getName();
   return (name + ":(id)" + l + ":(priority)" + p + ":(group)" + gname);
 }
 public static void main(String[] args) {
   Thread thread = Thread.currentThread();
   System.out.println("Thread: " + thread);
   System.out.println("Thread Id: " + thread.getId());
   System.out.println("Thread Name: " + thread.getName());
   System.out.println("Thread Group: " + thread.getThreadGroup());
   System.out.println("Thread Priority: " + thread.getPriority());
 }
Example #9
0
  protected void printFullThreadDump() {
    StringBundler sb = new StringBundler();

    sb.append("Full thread dump ");
    sb.append(System.getProperty("java.vm.name"));
    sb.append(" ");
    sb.append(System.getProperty("java.vm.version"));
    sb.append("\n\n");

    Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();

    for (Map.Entry<Thread, StackTraceElement[]> entry : stackTraces.entrySet()) {

      Thread thread = entry.getKey();
      StackTraceElement[] elements = entry.getValue();

      sb.append("\"");
      sb.append(thread.getName());
      sb.append("\"");

      if (thread.getThreadGroup() != null) {
        sb.append(" (");
        sb.append(thread.getThreadGroup().getName());
        sb.append(")");
      }

      sb.append(", priority=");
      sb.append(thread.getPriority());
      sb.append(", id=");
      sb.append(thread.getId());
      sb.append(", state=");
      sb.append(thread.getState());
      sb.append("\n");

      for (int i = 0; i < elements.length; i++) {
        sb.append("\t");
        sb.append(elements[i]);
        sb.append("\n");
      }

      sb.append("\n");
    }

    System.out.println(sb);
  }
Example #10
0
 public static void showThreads(PrintStream pw) {
   Thread current = Thread.currentThread();
   ThreadGroup group = current.getThreadGroup();
   while (true) {
     if (group.getParent() == null) break;
     group = group.getParent();
   }
   showThreads(pw, group, current);
 }
Example #11
0
 @Override
 public void uncaughtException(Thread t, Throwable e) {
   try {
     _logger.error("Uncaught exception in thread \"{}\"", t.getName(), e);
   } finally {
     // Invoke the thread group's handler too for compatibility with any
     // existing clients who are already scraping stderr for such conditions.
     t.getThreadGroup().uncaughtException(t, e);
   }
 }
 public NamedThreadFactory(final int priority) {
   this.priority = priority;
   final SecurityManager securityManager = System.getSecurityManager();
   if (securityManager == null) {
     final Thread currentThread = Thread.currentThread();
     this.parentGroup = currentThread.getThreadGroup();
   } else {
     this.parentGroup = securityManager.getThreadGroup();
   }
   this.namePrefix = "pool-" + poolNumber.getAndIncrement();
 }
Example #13
0
  private void threads() {
    printer.println("All threads: ");
    for (Thread t : getAllThreads()) {
      if (t == null) {
        break;
      }
      if (t.getThreadGroup() != null) {
        printer.println("  " + t.getName() + " (" + t.getThreadGroup().getName() + ")");
      } else {
        printer.println("  " + t.getName());
      }

      StackTraceElement[] elems = t.getStackTrace();
      if (elems != null) {
        for (StackTraceElement e : elems) {
          printer.println("    " + e.toString());
        }
      }
    }
  }
 private void listThreads() {
   final Set<Thread> threads = Thread.getAllStackTraces().keySet();
   final Map<String, Thread> sorted = Maps.newTreeMap();
   for (final Thread t : threads) {
     final ThreadGroup tg = t.getThreadGroup();
     if (t.isAlive() && (tg == null || !tg.getName().equals("system"))) {
       sorted.put(t.getName(), t);
     }
   }
   log.info("= THREADS " + Strings.repeat("=", 70));
   for (final Thread t : sorted.values()) {
     final ThreadGroup tg = t.getThreadGroup();
     log.info(
         "{}: \"{}\" ({}{})",
         t.getId(),
         t.getName(),
         (tg == null ? "" : tg.getName() + " "),
         (t.isDaemon() ? "daemon" : ""));
   }
   log.info(Strings.repeat("=", 80));
 }
Example #15
0
  /**
   * Return a user friendly description of the thread. We could use Thread.toString(), but that is
   * hard to read.
   *
   * @param thread The thread
   * @return A user friendly description of the thread.
   */
  public static String toThreadDescription(Thread thread) {
    String name = "Unnamed thread";
    String group = "Unnamed group";

    try {
      if (thread == null) {
        return "PrintThreads.toThreadDescription(): "
            + "thread argument == null\n   "
            + "This can happen if the thread was "
            + "killed while PrintThreads was called";
      }

      if (thread.getName() != null) {
        name = thread.getName();
      }

      if ((thread.getThreadGroup() != null) && (thread.getThreadGroup().getName() != null)) {
        group = thread.getThreadGroup().getName();
      }

      return _stringFormat(name, 35)
          + " "
          + _stringFormat(group, 20)
          + " "
          + _stringFormat(Integer.toString(thread.getPriority()), 3)
          + " "
          + _stringFormat(Boolean.valueOf(thread.isDaemon()).toString(), 6)
          + " "
          + _stringFormat(Boolean.valueOf(thread.isAlive()).toString(), 5)
          + (Thread.currentThread().equals(thread) ? " *" : "  ");
    } catch (Exception e) {
      return _stringFormat(name, 35)
          + " "
          + _stringFormat(group, 20)
          + " "
          + "PrintThread.toThreadDescription(): Bad State!: "
          + e;
    }
  }
  public IHostedThread getRobotProxy(Thread t) {
    ThreadGroup g = t.getThreadGroup();

    if (g == null) {
      return null;
    }
    int index = groups.indexOf(g);

    if (index == -1) {
      return null;
    }
    return robots.get(index);
  }
 @Override
 public void run() {
   Thread thread = Thread.currentThread();
   ClassLoader classLoader = thread.getContextClassLoader();
   try {
     Class<?> startClass = classLoader.loadClass(this.startClassName);
     Method mainMethod = startClass.getMethod("main", String[].class);
     if (!mainMethod.isAccessible()) {
       mainMethod.setAccessible(true);
     }
     mainMethod.invoke(null, new Object[] {this.args});
   } catch (NoSuchMethodException ex) {
     Exception wrappedEx =
         new Exception(
             "The specified mainClass doesn't contain a "
                 + "main method with appropriate signature.",
             ex);
     thread.getThreadGroup().uncaughtException(thread, wrappedEx);
   } catch (Exception ex) {
     thread.getThreadGroup().uncaughtException(thread, ex);
   }
 }
Example #18
0
 /**
  * Create a thread, ignore the stack size
  *
  * @param group the group
  * @param target the target
  * @param name the name
  */
 public Thread(ThreadGroup group, Runnable target, String name) {
   if (group == null) {
     Thread thread = Thread.currentThread();
     if (thread != null) {
       group = thread.getThreadGroup();
     }
   }
   if (group == null) {
     group = ThreadGroup.getRootGroup();
   }
   this.group = group;
   this.target = target;
   system = new org.pjos.common.runtime.Thread(this, name);
 }
  synchronized void uncaughtException(Throwable e) {
    mTotalUncaughtExceptions++;

    if (mExceptionListeners.size() > 0) {
      UncaughtExceptionEvent event = new UncaughtExceptionEvent(this, e);

      Iterator it = mExceptionListeners.iterator();
      while (it.hasNext()) {
        ((UncaughtExceptionListener) it.next()).uncaughtException(event);
      }
    } else {
      Thread current = Thread.currentThread();
      current.getThreadGroup().uncaughtException(current, e);
    }
  }
Example #20
0
 private static void threadInfo(final Thread t, final StringBuilder sb) {
   sb.append("\"");
   sb.append(t.getName());
   sb.append("\"");
   if (!t.isAlive()) sb.append(" DEAD");
   if (t.isInterrupted()) sb.append(" INTERRUPTED");
   if (t.isDaemon()) sb.append(" daemon");
   sb.append(" prio=");
   sb.append(t.getPriority());
   sb.append(" id=");
   sb.append(t.getId());
   sb.append(" group=");
   sb.append(t.getThreadGroup().getName());
   sb.append(NL);
   sb.append("   java.lang.Thread.State: ");
   sb.append(t.getState());
   sb.append(NL);
 }
Example #21
0
  public static void main(String[] args) {
    // 현재 이 명령을 수행하는 스레드 알아내기
    Thread t = Thread.currentThread();
    System.out.println("1) main() 호출 스레드 : " + t.getName());

    // main 스레드가 소속되어 있는 스레드 그룹 알아내기
    ThreadGroup g = t.getThreadGroup();
    System.out.println("2) main 스레드가 소속된 그룹 : " + g.getName());

    // main 스레드 그룹의 상위 그룹 알아내기
    ThreadGroup parent = g.getParent();
    System.out.println("3) main ThreadGroup의 상위 그룹 : " + parent.getName());

    // system 스레드 그룹의 상위 그룹 알아내기
    // system Thread Group이 최상위 그룹이다.
    // parent = parent.getParent();
    // System.out.println("4) system ThreadGroup의 상위 그룹 : " + parent.getName());

    browseThreadInfo(parent, 0);
  }
  public boolean isSafeThread(Thread c) {
    try {
      if (safeThreads.contains(c)) {
        return true;
      }

      for (ThreadGroup tg : safeThreadGroups) {
        if (c.getThreadGroup() == tg) {
          safeThreads.add(c);
          return true;
        }
      }

      return false;
    } catch (Exception e) {
      syserr.println("Exception checking safe thread: ");
      e.printStackTrace(syserr);
      return false;
    }
  }
Example #23
0
 // Join threads, return false if only our own threads are left.
 private boolean joinThreads(Thread pThreads[]) {
   for (int i = 0; i < pThreads.length; i++) {
     final Thread t = pThreads[i];
     if (t.isDaemon()
         || t.getThreadGroup().equals(threadGroup)
         || t.getName().startsWith("DestroyJavaVM")) {
       // These are threads which should not prevent the server from stopping.
       continue;
     }
     try {
       t.join();
     } catch (Exception ex) {
       // Ignore that one.
     } finally {
       // We just joined a 'foreign' thread, so we redo the loop
       return true;
     }
   }
   // All 'foreign' threads has finished, hence we are prepared to stop
   return false;
 }
Example #24
0
class EarlyReturnTarg {
  static boolean debuggerWatching = false;
  static int failureCount = 0;
  /*
   * These are the values that will be used by methods
   * returning normally.
   */
  static URL[] urls = new URL[1];
  public static byte byteValue = 89;
  public static char charValue = 'x';
  public static double doubleValue = 2.2;
  public static float floatValue = 3.3f;
  public static int intValue = 1;
  public static long longValue = Long.MAX_VALUE;
  public static short shortValue = 8;
  public static boolean booleanValue = false;

  public static Class classValue = Object.class;
  public static ClassLoader classLoaderValue;

  {
    try {
      urls[0] = new URL("hi there");
    } catch (java.net.MalformedURLException ee) {
    }
    classLoaderValue = new URLClassLoader(urls);
  }

  public static Thread threadValue = Thread.currentThread();
  public static ThreadGroup threadGroupValue = threadValue.getThreadGroup();
  public static String stringValue = "abc";
  public static int[] intArrayValue = new int[] {1, 2, 3};

  public static EarlyReturnTarg objectValue = new EarlyReturnTarg();
  public String ivar = stringValue;

  /*
   * These are the values that will be used by methods
   * returning early.  These are != the normal values
   * defined above.
   */
  static URL[] eurls = new URL[1];
  public static byte ebyteValue = 42;
  public static char echarValue = 'a';
  public static double edoubleValue = 6.6;
  public static float efloatValue = 9.9f;
  public static int eintValue = 7;
  public static long elongValue = Long.MIN_VALUE;
  public static short eshortValue = 3;
  public static boolean ebooleanValue = true;

  public static Class eclassValue = String.class;
  public static ClassLoader eclassLoaderValue;

  {
    try {
      urls[0] = new URL("been there, done that");
    } catch (java.net.MalformedURLException ee) {
    }
    classLoaderValue = new URLClassLoader(urls);
  }

  public static Thread ethreadValue;
  public static ThreadGroup ethreadGroupValue;
  public static String estringValue = "wxyz";
  public static int[] eintArrayValue = new int[] {10, 11, 12};

  public static java.util.Date eobjectValue = new java.util.Date();

  // Used to check the return values seen on the debugee side
  public static boolean chk(byte v) {
    return v == (debuggerWatching ? ebyteValue : byteValue);
  }

  public static boolean chk(char v) {
    return v == (debuggerWatching ? echarValue : charValue);
  }

  public static boolean chk(double v) {
    return v == (debuggerWatching ? edoubleValue : doubleValue);
  }

  public static boolean chk(float v) {
    return v == (debuggerWatching ? efloatValue : floatValue);
  }

  public static boolean chk(int v) {
    return v == (debuggerWatching ? eintValue : intValue);
  }

  public static boolean chk(long v) {
    return v == (debuggerWatching ? elongValue : longValue);
  }

  public static boolean chk(short v) {
    return v == (debuggerWatching ? eshortValue : shortValue);
  }

  public static boolean chk(boolean v) {
    return v == (debuggerWatching ? ebooleanValue : booleanValue);
  }

  public static boolean chk(String v) {
    return v.equals(debuggerWatching ? estringValue : stringValue);
  }

  public static boolean chk(Object v) {
    return v.equals(debuggerWatching ? eobjectValue : objectValue);
  }

  // Used to show which set of tests follows
  public static String s_show(String p1) {
    return p1;
  }

  // These are the static methods
  public static byte s_bytef(int p1) {
    return byteValue;
  }

  public static char s_charf() {
    return charValue;
  }

  public static double s_doublef() {
    return doubleValue;
  }

  public static float s_floatf() {
    return floatValue;
  }

  public static int s_intf() {
    return intValue;
  }

  public static long s_longf() {
    return longValue;
  }

  public static short s_shortf() {
    return shortValue;
  }

  public static boolean s_booleanf() {
    return booleanValue;
  }

  public static String s_stringf() {
    return stringValue;
  }

  public static Class s_classf() {
    return classValue;
  }

  public static ClassLoader s_classLoaderf() {
    return classLoaderValue;
  }

  public static Thread s_threadf() {
    return threadValue;
  }

  public static ThreadGroup s_threadGroupf() {
    return threadGroupValue;
  }

  public static int[] s_intArrayf() {
    return intArrayValue;
  }

  public static Object s_nullObjectf() {
    return null;
  }

  public static Object s_objectf() {
    return objectValue;
  }

  public static void s_voidf() {
    System.err.println("debugee in s_voidf");
  }

  // These are the instance methods
  public byte i_bytef(int p1) {
    return byteValue;
  }

  public char i_charf() {
    return charValue;
  }

  public double i_doublef() {
    return doubleValue;
  }

  public float i_floatf() {
    return floatValue;
  }

  public int i_intf() {
    return intValue;
  }

  public long i_longf() {
    return longValue;
  }

  public short i_shortf() {
    return shortValue;
  }

  public boolean i_booleanf() {
    return booleanValue;
  }

  public String i_stringf() {
    return stringValue;
  }

  public Class i_classf() {
    return classValue;
  }

  public ClassLoader i_classLoaderf() {
    return classLoaderValue;
  }

  public Thread i_threadf() {
    return threadValue;
  }

  public ThreadGroup i_threadGroupf() {
    return threadGroupValue;
  }

  public int[] i_intArrayf() {
    return intArrayValue;
  }

  public Object i_nullObjectf() {
    return null;
  }

  public Object i_objectf() {
    return objectValue;
  }

  public void i_voidf() {}

  static void doit(EarlyReturnTarg xx) throws Exception {
    System.err.print("debugee in doit ");
    if (debuggerWatching) {
      System.err.println("with a debugger watching.  Early returns expected.");
    } else {
      System.err.println("with no debugger watching.  Normal returns.");
    }

    s_show("==========  Testing static methods ================");
    if (!chk(s_bytef(88))) failureCount++;
    if (!chk(s_charf())) failureCount++;
    if (!chk(s_doublef())) failureCount++;
    if (!chk(s_floatf())) failureCount++;
    if (!chk(s_intf())) failureCount++;
    if (!chk(s_longf())) failureCount++;
    if (!chk(s_shortf())) failureCount++;
    if (!chk(s_booleanf())) failureCount++;

    if (!chk(s_stringf())) failureCount++;
    s_classf();
    s_classLoaderf();
    s_threadf();
    s_threadGroupf();
    s_intArrayf();
    s_nullObjectf();
    if (!chk(s_objectf())) failureCount++;
    s_voidf();

    s_show("==========  Testing instance methods ================");
    if (!chk(xx.i_bytef(89))) failureCount++;
    if (!chk(xx.i_charf())) failureCount++;
    if (!chk(xx.i_doublef())) failureCount++;
    if (!chk(xx.i_floatf())) failureCount++;
    if (!chk(xx.i_intf())) failureCount++;
    if (!chk(xx.i_longf())) failureCount++;
    if (!chk(xx.i_shortf())) failureCount++;
    if (!chk(xx.i_booleanf())) failureCount++;
    if (!chk(xx.i_stringf())) failureCount++;
    xx.i_intArrayf();
    xx.i_classf();
    xx.i_classLoaderf();
    xx.i_threadf();
    xx.i_threadGroupf();
    xx.i_nullObjectf();
    if (!chk(xx.i_objectf())) failureCount++;
    xx.i_voidf();
  }

  /** Hang so that test fails */
  static void hang() {
    try {
      // ten minute nap
      Thread.currentThread().sleep(10 * 60 * 1000);
    } catch (InterruptedException exc) {
      // shouldn't happen
    }
  }

  public static void main(String[] args) throws Exception {
    // The debugger will stop at the start of main,
    // set breakpoints and then do a resume.
    System.err.println("debugee in main");
    EarlyReturnTarg xx = new EarlyReturnTarg();

    doit(xx);
    if (debuggerWatching && failureCount > 0) {
      hang();
      throw new Exception("EarlyReturnTarg: failed");
    }
  }
}