Site Search :
Standard Enterprise XML Methodology Pattern Setting Tunning Other
Article Contributors
GuestBook
Javapattern Maven
XSourceGen Dev
JetSpeed Test
JLook Image
jLook Family Site


Shutdown hook클래스 작성방법 및 샘플
 
시스템의 비정상종료시에(Ctrl+C) 애플리케이션이 무언가 처리후 종료되어야 할 경우 그 방안에 대하여 작성할 수 있는 방법과 샘플코드를 보여주도록 한다. ( 2003/07/28 ) 244
Written by ienvyou - 최지웅
1 of 1
 

이번 아티클에서는 shutdown hook에 대한 글을 써보고자 한다. 우선 개요부터 말하자면
당신이 열나게 애플리케이션을 만들었다고 가정을 해보자.
사용자가 도스창에서 애플리케이션을 실행시키고 동작시키고 있는데, 이 사용자가
갑자기 이게 아니다 싶어서 애플리케이션을 죽이려고 한다. 
근데 분명 내가 메뉴에 종료라는 항목을 하나 추가해주었거늘..
Ctrl+C를 눌러버리고야 말았다.

문제는 무었인고? 나는 해당사용자의 내용에 대한 backward기능을 주고 싶어서 
그 사람이 하고 있는 행동에 대한 rollback가능한 로그를 쌓고 사용자가 애플리케이션을
종료시키면 그때 필요없는 데이터들을 모두 없애버리리라 마음을 먹고 있던 차였다.
그런데...

위의 같은 상황이 발생을 한다면 당신은 어떻게 할것인가? 
서블릿 컨테이너나 Applet의 경우도 실제 라이프사이클에 의하여 동작하여 해당 클래스가
메모리에서 unload되어지는 시점에 destroy메소드들을 호출하도록 하고 있는데,
위의 ctrl+c라는 행위는 아예 daemon thread까지 "너 죽어랏~!" 하면서 보내버리는 케이스니 말이다.

만약 저러한 애플리케이션을 스윙으로 만든다면 actionPerformed 이벤트를 걸어서 어떻게든
처리를 하겠는데 일반 text based application의 경우는 더더욱이 문제가 아닐듯 싶다.

▶ 자바에서의 shutdown event의 두가지

자바에서 virtual machine이 shutdown을 인식하는 방법으로는 두가지가 있는데 

1. 첫번째로는 애플리케이션이 System.exit()메소드를 통하여 정상적으로 종료하는 경우가 있고, 

2. 두번째로는 사용자가 직접 Ctrl+C를 키보드에 입력함으로서 현재 실행중인 애플리케이션을
closing하지 않고 virtual machine을 비정상적으로 강제종료시키는 경우이다.


간단하게 shutdown hook을 작성할 수 있는 방법은 다음과 같다.

1. java.lang.Thread를 상속받는 클래스를 하나 작성한다.
2. Thread의 run메소드를 구현할 때 당신이 shutdown시에 처리해야 할 일들에 대하여 기술한다.
3. 해당 shutdown hook클래스를 생성한다.
4. Runtime클래스의 addShutdownHook()메소드를 이용하여 등록한다.
    Runtime.getRuntime().addShutdownHook(shutdownHook);

▶ ShutdownHook Sample정의

여기서 우선 애플리케이션을 만들 경우를 가정하자. 
보통의 서블릿 컨테이너는 사용자에 대한 세션을 자신의 로컬파일로 저장하여 관리하고 있다.
레진같은 엔진을 보더라도 session이라는 디렉토리에 file serialize를 통하여 저장하고 엔진이
종료되거나 세션의 시간이 만료되게 되면 그 저장된 temporary파일들을 삭제하는 루틴을
가지고 있다.
그런데 만약에 그러한 엔진들이 비정상적인 종료에 해당 파일들을 삭제하지 못하고
쌓아두게 된다면, 또한 접속이 많은 그러한 서버였다면 파일시스템의 사이즈가 비대하게
불어나게 될 것은 불을 보듯 뻔한 일아닌가? 

놀새~의 샘플코드 가정을 비슷하다.
애플리케이션이 시작되면 사용자의 고유식별파일을 하나 만들어서 기록하고 있다가 
어떠한 방법으로라도 프로그램이 종료되게 되면 그 파일을 삭제하도록 할것이다.

자 그럼 위의 순서에 의하여 하나하나 작성을 해보도록 하자.

▶ ShutdownHookDemo.java


    import java.io.*;

    public class ShutdownHookDemo {
    private String dir = ".";
    private String filename = "session_tmp.txt";

    /**
    *  애플리케이션이 시작되면 shutdown을 생성한후 등록한다.
    */
    public void start() {
        System.out.println("Demo");
        ShutdownHook shutdownHook = new ShutdownHook();
        Runtime.getRuntime().addShutdownHook(shutdownHook);
    }

    /**
    *  1. 실행의 순서는 먼저 tempoary파일의 생성
    *  2. Runtime클래스에 shutdown hook을 등록
    *  3. 사용자의 입력을 기다림(무한루프)
    */
    public static void main(String[] args) {
        ShutdownHookDemo demo = new ShutdownHookDemo();
        demo.setup();
        demo.start();

        try {
            while(true){
                System.in.read();
            }
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
    /**
    *	ShutdownHook클래스를 inner클래스로 사용함으로서 ShutdownHookDemo클래스의
    *	멤버변수에 대한 참조를 가능하도록 만든다.
    */
    private class ShutdownHook extends Thread {
        public void run() {
            shutdown();
        }
    }

    /**
    *  Shutdown의 되는 시점에 생성되었던 temporary파일을 삭제한다.
    */
    private void shutdown() {
        System.out.println("start shutdown progress.. please wait");
        // delete the temp file
        File file = new File(dir, filename);

        if (file.exists()) {
            System.out.println("Deleting temporary file.");
            file.delete();
        }

    }
    /**
    *  프로그램최초 수행시에 임시파일을 생성해낸다.
    */
    private void setup(){
    // create a temp file
        File file = new File(dir, filename);

        try {
            System.out.println("Creating temporary file");
            file.createNewFile();
        }
        catch (IOException e) {
            System.out.println("Failed creating temporary file.");
        }
    }


    }

위에서 별반 다르게 볼건 없다. 프로그램이 시작되면 while(true){ System.in.read(); } 처럼 무한루프를 돌며 사용자의 키보드 입력을 기다리게 되는데, ctrl+c가 입력되기전에는 계속 입력만을 받게 된다. 실제 shutdown hook클래스는 아래와 같이 간단하게 만들수 있으며 private class ShutdownHook extends Thread { public void run() { shutdown(); } } 단순히 클래스가 Runtime.getRuntime().addShutdownHook(shutdownHook); 에 의하여 등록만 되어 있으면 자동으로 처리되게 된다. 실제로 테스트를 해볼경우 프로그램을 수행시키는 시점에 session_tmp.txt파일이 디렉토리에 생기게 된다. 계속 테스트하다가 실제 ctrl+C를 키보드에 입력했을 경우 shutdown progress라는 메시지와 함께 해당 임시파일은 없어지게 될것이다. 간단하게 테스트 해볼 수 있으며 위의 프로그램을 조금만 응용해도 당신은 아주 훌륭한 애플리케이션을 만들수 있을 것이다.
 
1
References
 
Copyright ⓒ 2003 www.javapattern.info & www.jlook.com, an jLOOK co.,LTD