text/Java

jar 인자 전달을 쉽게! jCommander

hoonzii 2024. 4. 6. 19:37
반응형

이번 프로젝트를 하면서 jar 파일을 만드는 경우가 생겼는데,

해당 jar는 일정 시간마다 한 번씩 실행되는 걸 염두에 두고 구성되었다.

 

실행하면 DB1 → 데이터 가공 → DB2 순으로 데이터를 밀어 넣는 방식인데

문제는 해당 jar 파일이 실패했을때를 대비해 jar의 실행 설정을 변경하여, 다시 실행시킬 수 있어야 한다는 점이었다.

 

우리가 흔히 보는 java의 main 함수는 jar로 만들어 실행 시 파라미터를 args로 받을 수 있다.

// $java -jar test.jar date time flag


public static void main(String[] args){
	// args 로 실행 파라미터를 입력받을 수 있다!
	String date = args[0];
	String time = args[1];
	String flag = args[2];
}

 

 

이게 왜 문제냐…

  1. 실행시 조건을 넣을 수도 안 넣을 수도 있고, (위 예시에서 date는 안 넣고, time는 넣고 싶을 경우)
  2. 파라미터별로 형식이 다르기 때문이다 (date는 yyyyMMdd 형식으로 고정되어 있는 경우)

위 예시를 보면 String 배열이기에 date, time, flag 차례대로 들어있다.

그렇다면 time 만 넣고 싶다면? 게다가 time 은 특정 형식이 정해져 있는 경우라면?

 

들어오는 args의 길이를 체크할 필요가 있고,

체크한 다음엔 해당 값이 특정 값이 맞는지, 맞다면 형식에 어긋나진 않는지 체크하는 로직등

main 함수가 존재하는 클래스 내 조건으로 들어오는 파라미터를 체크하는 로직 (if로 점철된…)을 추가할 필요가 생긴다.

 

순서도 중요하고, 파라미터별 형식도 중요하지만 둘 다 jar를 실행할 때 안내가 없기에 코드를 까봐야 알 수 있다는 단점도 역시 존재한다.

위와 같은 상황을 조금 더 편하게 해주는 jCommander 라이브러리를 소개한다.

 

https://mvnrepository.com/artifact/com.beust/jcommander/1.82

 

maven 프로젝트라면 pom 파일에, java 프로젝트라면 나처럼 jar를 다운로드 받아 추가해 준다.

args를 받을 클래스를 하나 만들어 준다.

//jarArgs.java

import com.beust.jcommander.Parameter;

public class JarArgs {
    public static final String HELP = "--help";
    @Parameter(names=HELP, description = "jar args description", help = true)
    private boolean help;
    public boolean getHelp(){
        return this.help;
    }

    public static final String DATE = "--date";
    @Parameter(names=DATE, description = "date args format=yyyyMMdd", required = false)
    private String date;
    public String getDate(){
        return this.date;
    }


    public static final String TIME = "--time";
    @Parameter(names=TIME, description = "time args format=hhMMss", required = false)
    private String time;
    public String getTime() {
        return this.time;
    }

    public static final String FLAG = "--flag";
    @Parameter(names=FLAG, description = "on/off args", required = false)
    private String flag;
    public String getFlag() {
        return this.flag;
    }
}

 

 

그리고 main 클래스의 args 처리를 다르게 바꿔준다.

import com.beust.jcommander.JCommander;

public class Main {

    public static void main(String[] args) {
        JarArgs jarArgs = new JarArgs();
        JCommander commander = new JCommander(jarArgs);
        commander.parse(args);

        if(jarArgs.getHelp()){
            commander.usage();
            return;
        }

        String date = jarArgs.getDate();
        String time = jarArgs.getTime();
        String flag = jarArgs.getFlag();

        System.out.println("Hello world!");
        System.out.println(date+"/"+time+"/"+flag);
    }
}

 

 

변경 후, jar로 만들어주고... jar를 실행시켜보자.

 

—help 파라미터를 적어 어떤 파라미터가 어떤 형식으로 필요한지 알 수 있게 됐다.

또한, 앞서 본 예제에선 args 순서가 중요했지만 —{parameter이름}으로 특정 파라미터만 받을 수 있게 됐다.

 

 

간단하게 jar 파라미터를 제어할 수 있게 됐다.

반응형