I am writing a SecurityManager
that should only allow System.exit()
calls from a single class. The problem is that this class is also the one containing the main()
method which is running the app, so using SecurityManager.inClass()
won't work - we're always in that class. I need to know if that class is the one that explicitly is trying to exit or not. Is this possible at all?
3 Answers
You can look at the StackTrace.
StackTraceElemment[] stes = Thread.currentThread().getStackTrace();
// find the first non system package
int i = 0;
for(; i < stes.length-1;i++)
if (!stes.getClassName().startsWith("java.lang."))
break;
// is that package/class ok?
if (stes[i].getClassName().startsWith("my.ok.package."))
There is more efficient ways of doing this with internal APIs, but they are not standard, even between version of Java of HotSpot.
Note: this will give you the method name and possibly the file name and line number if debugging information has been included. What it won't give you is the actual class. With multiple class loaders, you can have multiple classes with the same name and there is no way of knowing which one it is. All you get is the package and class name, not the class loader.

- 525,659
- 79
- 751
- 1,130
-
1And we know that the relevant element is always at index 3 because...? Perhaps it would be best to walk up the stack trace looking for a class that also has a `main` method and then if appropriate do further checks. – Ted Hopp Jun 25 '14 at 21:11
-
@TedHopp You are right, it might not be true for all JVMs. – Peter Lawrey Jun 25 '14 at 21:18
Putting it all together:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
String className = stacktraceElements[stackTraceElements.length-1].getClassName();
if (className.contains("MainClassName")){
}
Alternatively, you can loop over the stackTraceElements to see if any of them are your main class (or make sure the "correct" one is).
Here is how I found out all this:
See this question on how to get the stack trace: Get current stack trace in Java
Once you have the array of StackTraceElements, you can get the last one, and then get the class from that one. (the last StackTraceElement is the most recent one)
See this question to get a class from the stack trace: How do I find the caller of a method using stacktrace or reflection?
Actually, by the looks of it, you can more easily get the class name, which you can easily use to do a String.equals() check:
if(className.equals("MainClassName")){
}
As it turns out, the class name has package info in it too, according to http://docs.oracle.com/javase/7/docs/api/java/lang/StackTraceElement.html. So use String.contains() instead.

- 1
- 1

- 1,507
- 17
- 22
-
-
You should edit out the `instanceof`. Then explain how to get the stack trace. They would possibly have to clean it up. How would they do that? – Sotirios Delimanolis Jun 25 '14 at 21:06
You can probably make a security policy that only grants exitVM
permission to your particular main class
the policy file has to have a line like this
permission java.lang.RuntimePermission ${yourMainClass} exitVM
More information on this Blog I found http://www.informit.com/articles/article.aspx?p=1187967&seqNum=3

- 31,188
- 3
- 63
- 67