3

My custom security manager currently blocks graceful closing due to SIGTERMs. The follow message is displayed:

Java HotSpot(TM) 64-Bit Server VM warning: Exception java.lang.SecurityException occurred dispatching signal SIGTERM to handler- the VM may need to be forcibly terminated

What should I do to enable shutting down due to SIGTERMS but nothing more?

Aaron Yodaiken
  • 19,163
  • 32
  • 103
  • 184
  • Do you know which check method your SecurityManager is causing that exception? As far as I can tell, the relevant one is: checkPermission(java.lang.RuntimePermission shutdownHooks) – Jon Lin Jun 01 '12 at 05:40
  • Sorry, 2 others: checkAccess() with the "system" thread group, and checkAccess() with the SIGTERM handler thread within the "system" threadgroup. Is your SecurityManager preventing these accesses? – Jon Lin Jun 01 '12 at 06:00
  • It has everything disabled at the moment. – Aaron Yodaiken Jun 01 '12 at 13:49
  • You've probably look at this but just in case. http://stackoverflow.com/questions/191215/how-to-stop-java-process-gracefully – Rob Kielty Jun 01 '12 at 15:35
  • Then you need to allow checkPermission() for the name "shutdownHooks", allow checkAccess() for the *system* thread group and the *SIGTERM handler* thread. – Jon Lin Jun 01 '12 at 17:44

1 Answers1

1

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.

Yves Martin
  • 10,217
  • 2
  • 38
  • 77