Java:System.exit () and security policy

Source: Internet
Author: User

Description

System.exit()The essence is to notify the JVM to shut down.

Generally speaking. There are two ways System.exit() to disable this:

    • Security Manager
    • Security Policy

The essence is the local implementation provided by the JRE, which performs permission inference prior to execution.

Because System.exit() it is a very violent means. It doesn't matter if you write a small program yourself in Client mode, but there are a lot of problems with multiple programs or multiple threads on the Server.

Underlying source code

1. First look at System.exit() the source code of the static method:

// System.exit()public static void exit(int status) {    Runtime.getRuntime().exit(status);}

It should be said to be very easy, simply invoke the exit method at execution time.

2. Then we look at the instance method at execution time exit :

// Runtime.exit()public void exit(int status) {    SecurityManager security = System.getSecurityManager();    if (security != null) {        security.checkExit(status);    }    Shutdown.exit(status);}

If you have a security manager, let the security Manager perform an checkExit exit permission check.

If the check does not pass, the security manager throws an exception (this is the Convention!).

)。

The current thread then throws an exception, assuming it is not captured, and the thread exits.

Assuming that no other foreground thread is executing, the JVM will then exit.

3. Shutdown is one of the following classes in the Java.lang package.

The access permission is default, so we cannot invoke it in the API.

Shutdown.exit () static void exit (int status) {Boolean runmorefinalizers = false;        Synchronized (lock) {if (status! = 0) Runfinalizersonexit = false;            Switch (state) {case RUNNING:/* Initiate shutdown */state = HOOKS;        Break        Case HOOKS:/* Stall and halt */break; Case Finalizers:if (Status! = 0) {/* Halt immediately on nonzero status */Halt            (status);                 } else {/* Compatibility with old behavior: * Run more finalizers and then halt            */runmorefinalizers = Runfinalizersonexit;        } break;        }} if (Runmorefinalizers) {runallfinalizers ();    Halt (status); } synchronized (Shutdown.class) {/* Synchronize on the class object, causing any other thread * so at       Tempts to initiate shutdown to stall indefinitely * * Sequence ();    Halt (status); }}

There are some synchronization methods to lock.

The exit logic is called by the halt method.

// Shutdown.halt()static void halt(int status) {    synchronized (haltLock) {        halt0(status);    }}static native void halt0(int status);

Then it is called the native halt0() method to let the JVM " suicide ".

Demo sample

The implementation code that uses the security manager is seen in the following example:

1. Define the exception class and inherit fromSecurityException

Exitexception.java

package com.cncounter.security;public class ExitException extends SecurityException {    private static final long serialVersionUID = 1L;    public final int status;    public ExitException(int status) {        super("忽略 Exit方法调用!");        this.status = status;    }}

2. Define the security manager class, inherit fromSecurityManager

Noexitsecuritymanager.java

package com.cncounter.security;import java.security.Permission;public class NoExitSecurityManager extends SecurityManager {    @Override    public void checkPermission(Permission perm) {        // allow anything.    }    @Override    public void checkPermission(Permission perm, Object context) {        // allow anything.    }    @Override    public void checkExit(int status) {        super.checkExit(status);        throw new ExitException(status);    }}

The system directly refuses to exit.

3. Add an auxiliary and test class, you can control the actual use of your own.

Noexithelper.java

package com.cncounter.security;public class NoExitHelper {    /**     * 设置不同意调用 System.exit(status)     *      * @throws Exception     */    public static void setNoExit() throws Exception {        System.setSecurityManager(new NoExitSecurityManager());    }    public static void main(String[] args) throws Exception {        setNoExit();        testNoExit();        testExit();        testNoExit();    }    public static void testNoExit() throws Exception {        System.out.println("Printing works");    }    public static void testExit() throws Exception {        try {            System.exit(42);        } catch (ExitException e) {            //            System.out.println("退出的状态码为: " + e.status);        }    }}

In the middle. A Main method is used to make a simple test. Console output results such as the following:

Printing works退出的状态码为: 42Printing works
Original problem

The original questions such as the following:

I ' ve got a few methods that should call System.exit () on certain inputs. Unfortunately, testing these cases causes JUnit to terminate! Putting the method calls in a new Thread doesn ' t seem to help, since System.exit () terminates the JVM, not just the Curren T thread. Is there any common patterns for dealing and this? For example, can I subsitute a stubs for System.exit ()?

The effect is:

There are some methods that need to be tested, but they are called at certain inputs System.exit() . This is the cup, and then the JUnit test also withdrew! It is useless to call such a method with a new thread, as it System.exit() will stop the JVM and not exit the current thread.

Is there a common pattern to deal with such situations?

For example, can I replace the System.exit() method?

Suggestions such as the following:

Instead of terminating with System.exit (Whatevervalue), why isn't throw an unchecked exception?

In normal use it'll drift all the the-the-last-ditch-the-the-JVM ' s catcher and shut your script down (unless you decide t O catch it somewhere along the, which might be useful someday).

In the JUnit scenario it is caught by the junit framework, which would report that Such-and-such test failed and move Smoothly along to the next.

Translate for example the following:

Calling in a program System.exit(whateverValue) is a very bad programming habit, so why not throw an unchecked exception (unchecked exception)? Assuming the program does not capture (catch), the thrown exception drifts all the way to the JVM, and then exits the program ( Only the main thread).

In JUnit's test scenario, the exception is caught by the JUnit framework, which then reports that a test execution failed and then continues the next unit test.

The solution, of course, is the previous piece of code. You can also read the following articles to find other solutions.

Articles:
    • Java: How does the unit test a method that calls System.exit ()?

    • How to disable API call System.exit () in Java

    • How to configure the security manager for Tomcat

Date: August 25, 2015

Personnel: Anchor Http://blog.csdn.net/renfufei

Java:System.exit () and security policy

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.