Your implementation has probably disabled the full debugging information from -Djava.security.debug=all
if you omit to call super.checkAccess
. If you write first in your SecurityManager
implementation
public void checkAccess(ThreadGroup g) {
System.out.println("Access for " + g);
super.checkAccess(g);
}
public void checkAccess(Thread t) {
System.out.println("Access for " + t);
super.checkAccess(t);
}
and run with -Djava.security.debug=all
, you get information about checkAccess
calls to allow and permissions to add to your policy file. I sum up:
Access for java.lang.ThreadGroup[name=system,maxpri=10]
Permission (java.lang.RuntimePermission modifyThreadGroup)
[...]
Access for Thread[SIGTERM handler,9,system]
Permission (java.lang.RuntimePermission modifyThread)
[...]
java.security.Permissions@133c5982 (
(java.lang.RuntimePermission exitVM)
(java.io.FilePermission /path/to/current/working/directory/- read)
)
As a result, you enable SIGTERM
signal handling the stricter way with the following code in your SecurityManager
:
public void checkAccess(ThreadGroup g) {
System.out.println("Access for " + g);
if ("system".equals(g.getName())) {
// will checkPermission java.lang.RuntimePermission "modifyThreadGroup"
super.checkAccess(g);
} else {
throw new SecurityException("Access denied to " + g);
}
}
public void checkAccess(Thread t) {
System.out.println("Access for " + t);
if ("SIGTERM handler".equals(t.getName())) {
// will checkPermission java.lang.RuntimePermission "modifyThread"
super.checkAccess(t);
} else {
throw new SecurityException("Access denied to " + t);
}
}
And also these permissions granting in your java.security.policy
file:
grant {
permission java.lang.RuntimePermission "modifyThreadGroup";
permission java.lang.RuntimePermission "modifyThread";
permission java.lang.RuntimePermission "exitVM";
};
The full information is available here but it is really not obvious to do it right, the try-and-fix method is still the fastest way.