How to determine main class at runtime in threaded java application?

后端 未结 10 975
野的像风
野的像风 2021-01-01 13:37

I want to determine the class name where my application started, the one with the main() method, at runtime, but I\'m in another thread and my stacktrace doesn\'t go all the

10条回答
  •  [愿得一人]
    2021-01-01 14:30

    Here's what I'm using, for situations where you don't control the main:

    public static Class getMainClass() {
      // find the class that called us, and use their "target/classes"
      final Map traces = Thread.getAllStackTraces();
      for (Entry trace : traces.entrySet()) {
        if ("main".equals(trace.getKey().getName())) {
          // Using a thread named main is best...
          final StackTraceElement[] els = trace.getValue();
          int i = els.length - 1;
          StackTraceElement best = els[--i];
          String cls = best.getClassName();
          while (i > 0 && isSystemClass(cls)) {
            // if the main class is likely an ide,
            // then we should look higher...
            while (i-- > 0) {
              if ("main".equals(els[i].getMethodName())) {
                best = els[i];
                cls = best.getClassName();
                break;
              }
            }
          }
          if (isSystemClass(cls)) {
            i = els.length - 1;
            best = els[i];
            while (isSystemClass(cls) && i --> 0) {
              best = els[i];
              cls = best.getClassName();
            }
          }
          try {
            Class mainClass = Class.forName(best.getClassName());
            return mainClass;
          } catch (ClassNotFoundException e) {
            throw X_Util.rethrow(e);
          }
        }
      }
      return null;
    }
    
    private static boolean isSystemClass(String cls) {
      return cls.startsWith("java.") ||
          cls.startsWith("sun.") ||
          cls.startsWith("org.apache.maven.") ||
          cls.contains(".intellij.") ||
          cls.startsWith("org.junit") ||
          cls.startsWith("junit.") ||
          cls.contains(".eclipse") ||
          cls.contains("netbeans");
    }
    

提交回复
热议问题