본문 바로가기

SW 개발 이야기

System.exit() 무효화 하기 (Code Analyst 코드 이야기 #2)

외부 오픈소스SW 라이브러리를 사용하다 보면, 가끔 정상적이든 비정상적이든 System.exit()로 끝나는 경우가 있다. 주로 커맨드 라인(Command Line) 방식에서 그렇게 사용된다. Code Analyst에서도 CheckStyle을 사용할 때 오류가 발생하면 강제 종료가 되는데, 이를 간단하게 무효화 할 수 있다.

2020/10/28 - [SW 개발 이야기] - Code Analyst(코드분석) 오픈소스SW 개발 이야기

package com.samsungsds.analyst.code.util;

import java.security.Permission;

public class SystemExitDisabler {
    public static class ExitTrappedException extends SecurityException {
        // no override
    }

    public static void forbidSystemExitCall() {
        final SecurityManager securityManager = new SecurityManager() {
            public void checkPermission(Permission permission) {
                if (permission.getName().startsWith("exitVM.")) {
                    throw new ExitTrappedException();
                }
            }
        };
        System.setSecurityManager(securityManager);
    }

    public static void enableSystemExitCall() {
        System.setSecurityManager(null);
    }
}

특정 Permission 허용 여부를 결정하는 SecurityManager를 생성하여 시스템에 등록하면 간단하게 무효화할 수 있고, 호출도 단순히 특정 라이브러리 호출 전후에 정의된 static 메소드를 호출하기만 하면 된다.

    // ...
    LOGGER.debug("Forbid System Exit Call");
    SystemExitDisabler.forbidSystemExitCall();
    try {
        Main.main(arguments.toArray(new String[0]));
    } catch (IOException ex) {
        throw new RuntimeException(ex);
    } catch (SystemExitDisabler.ExitTrappedException ex) {
        LOGGER.info("System Exit Called... (forbid that call)");
        throw new RuntimeException("System Exit Called when CheckStyle running");
    } finally {
        LOGGER.debug("Enable System Exit Call");
        SystemExitDisabler.enableSystemExitCall();
    }
    // ...

Written with by Vincent Han