54

Is there a way to find the name of the program that is running in Java? The class of the main method would be good enough.

jodonnell
  • 49,859
  • 10
  • 62
  • 67
ryantm
  • 8,217
  • 6
  • 45
  • 57

8 Answers8

45

Try this:

    StackTraceElement[] stack = Thread.currentThread ().getStackTrace ();
    StackTraceElement main = stack[stack.length - 1];
    String mainClass = main.getClassName ();

Of course, this only works if you're running from the main thread. Unfortunately I don't think there's a system property you can query to find this out.

Edit: Pulling in @John Meagher's comment, which is a great idea:

To expand on @jodonnell you can also get all stack traces in the system using Thread.getAllStackTraces(). From this you can search all the stack traces for the "main" Thread to determine what the main class is. This will work even if your class is not running in the main thread.

jodonnell
  • 49,859
  • 10
  • 62
  • 67
  • Good trick. In general, one would call this from main(), so there is only one thread at this point, but in case this is called from elsewhere, we better have this thread problem in mind... – PhiLho Jul 11 '12 at 06:14
  • 4
    There is no garantee main thead to be running when you'll try to find app name from other threads. Main thread could finish normally and some other background threads not yet finished. Don't think it is legitimate to do this trick other then from main thread. – Mike Sep 06 '12 at 06:59
18
System.getProperty("sun.java.command")
John Conde
  • 217,595
  • 99
  • 455
  • 496
Nadav Brandes
  • 191
  • 1
  • 5
  • 1
    i believe this only works on the HotSpot VM. see http://java.dzone.com/articles/programmatically-restart-java – ericsoco Jun 14 '13 at 23:15
15

To expand on @jodonnell you can also get all stack traces in the system using Thread.getAllStackTraces(). From this you can search all the stack traces for the main Thread to determine what the main class is. This will work even if your class is not running in the main thread.

Sid M
  • 4,354
  • 4
  • 30
  • 50
John Meagher
  • 22,808
  • 14
  • 54
  • 57
  • 7
    It is possible for the main thread to stop running but the application still continues (other non-daemon threads). This likely happens in many GUI/Swing applications since the common idiom is for the main thread to invoke on EDT to create the first frame and then terminate. – Kevin Brock Mar 11 '10 at 05:53
8

This is the code I came up with when using the combined responses of jodonnell and John Meagher. It stores the main class in a static variable to reduce overhead of repeated calls:

private static Class<?> mainClass;

public static Class<?> getMainClass() {
  if (mainClass != null)
    return mainClass;

  Collection<StackTraceElement[]> stacks = Thread.getAllStackTraces().values();
  for (StackTraceElement[] currStack : stacks) {
    if (currStack.length==0)
      continue;
    StackTraceElement lastElem = currStack[currStack.length - 1];
    if (lastElem.getMethodName().equals("main")) {
      try {
        String mainClassName = lastElem.getClassName();
        mainClass = Class.forName(mainClassName);
        return mainClass;
      } catch (ClassNotFoundException e) {
        // bad class name in line containing main?! 
        // shouldn't happen
        e.printStackTrace();
      }
    }
  }
  return null;
}
Andrew Taylor
  • 1,368
  • 1
  • 11
  • 8
4

Also from the command line you could run the jps tool. Sounds like a

jps -l 

will get you what you want.

polarbear
  • 12,425
  • 6
  • 29
  • 22
2

For access to the class objects when you are in a static context

public final class ClassUtils {
    public static final Class[] getClassContext() {
        return new SecurityManager() { 
            protected Class[] getClassContext(){return super.getClassContext();}
        }.getClassContext(); 
    };
    private ClassUtils() {};
    public static final Class getMyClass() { return getClassContext()[2];}
    public static final Class getCallingClass() { return getClassContext()[3];}
    public static final Class getMainClass() { 
        Class[] c = getClassContext();
        return c[c.length-1];
    }
    public static final void main(final String[] arg) {
        System.out.println(getMyClass());
        System.out.println(getCallingClass());
        System.out.println(getMainClass());
    }
}

Obviously here all 3 calls will return

class ClassUtils

but you get the picture;

classcontext[0] is the securitymanager
classcontext[1] is the anonymous securitymanager
classcontext[2] is the class with this funky getclasscontext method
classcontext[3] is the calling class
classcontext[last entry] is the root class of this thread.
tschodt
  • 164
  • 1
  • 5
-3

Try this :

Java classes have static instance of their own class (java.lang.Class type).

That means if we have a class named Main. Then we can get its class instance by Main.class

If you're interested in name only then,

String className = Main.class.getName();

color
  • 1
-5

Or you could just use getClass(). You can do something like:

public class Foo
{
    public static final String PROGNAME = new Foo().getClass().getName();
}

And then PROGNAME will be available anywhere inside Foo. If you're not in a static context, it gets easier as you could use this:

String myProgramName = this.getClass().getName();
Adam
  • 1
  • I don't think this solves the problem. The poster does not know which class contains the `main` method that was invoked when Java started up (perhaps it is part of a third party library). – Adam Paynter Mar 13 '11 at 11:41
  • 1
    This makes no sense at all. It only works if I knew that `Foo` was the main class. But then I wouldn't need to do this. – maaartinus Mar 13 '11 at 11:55