1. 소개

이 짧은 기사에서는 프로그래밍 방식으로 jar 파일을 만드는 과정을 살펴보겠습니다. 소프트웨어를 작성할 때 결국 프로덕션 상태로 배포해야 합니다. 경우에 따라 별도의 파일이 있는 클래스 경로를 사용해도 됩니다. 일반적으로 단일 파일을 처리하는 것이 더 편리합니다. Java의 경우 이를 수행하는 표준 방법은 JAR, WAR 또는 EAR 파일을 사용하는 것입니다.

기본 프로세스는 매니페스트를 작성하고, 항아리를 열고, 내용을 추가하고, 마지막으로 항아리를 닫는 것입니다.

2. Jar 파일 분석

jar 파일은 매니페스트 파일이 포함된 ZIP 파일 형식의 확장입니다. 매니페스트 파일은 JAR 파일에 특정한 특수 파일이며 다양한 설정을 포함할 수 있습니다. 이들 중 일부는 기본 클래스, 선택적 데이터(예: 작성자, 버전 등) 및 코드 서명 정보입니다.

당사는 아카이브의 일부 또는 전체를 보고 추출하기 위해 WinRar 와 같은 zip 호환 도구를 사용할 수 있습니다 . 의존성 jar를 포함하기 위한 jars 또는 libs 하위 디렉터리를 포함할 수도 있습니다. jar는 zip 파일의 확장이므로 모든 파일이나 디렉토리를 포함할 수 있습니다.

3. JarTool 클래스 만들기

JAR 파일 생성 프로세스를 단순화하기 위해 작업을 캡슐화하는 단독 POJO(Plain Old Java Object) 클래스를 생성합니다. 매니페스트 파일에 항목 넣기, JAR 파일 만들기, 파일 또는 디렉터리 추가가 포함될 수 있습니다.

JAR에서 삭제를 수행하거나 기존 JAR에 항목을 추가하는 메서드를 생성할 수도 있지만 이러한 작업에는 JAR을 완전히 읽고 다시 써야 합니다.

3.1. JAR 매니페스트

JAR 파일을 생성하려면 먼저 매니페스트를 시작해야 합니다.

public class JarTool {    
    private Manifest manifest = new Manifest();

    public void startManifest() {
        manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
    }
}

jar 파일을 실행 가능하게 하려면 기본 클래스를 설정해야 합니다.

public void setMainClass(String mainFQCN) {
    if (mainFQCN != null && !mainFQCN.equals("")) {
        manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, mainFQCN);
    }
}

또한 추가 속성을 지정하려는 경우 매니페스트에 추가할 수 있습니다. 예를 들면 다음과 같습니다.

addToManifest("Can-Redefine-Classes", "true");

그 방법은 다음과 같습니다.

public void addToManifest(String key, String value) {
     manifest.getMainAttributes().put(new Attributes.Name(key), value);
}

3.2. 쓰기 위해 항아리 열기

매니페스트가 완료되면 이제 항목을 JAR 파일에 쓸 수 있습니다. 이렇게 하려면 먼저 항아리를 열어야 합니다.

public JarOutputStream openJar(String jarFile) throws IOException {        
    return new JarOutputStream(new FileOutputStream(jarFile), manifest);
}

3.3. Jar에 파일 추가

JAR에 파일을 추가할 때 Java는 슬래시를 구분 기호(/)로 사용하는 Solaris 스타일 파일 이름을 사용합니다. 다른 JAR 파일이나 빈 디렉터리를 포함하여 모든 유형의 파일을 추가할 수 있습니다 . 이것은 의존성을 포함하는 데 정말 편리합니다.

또한 JAR 파일은 클래스 경로의 형식이기 때문에 JAR 내에서 사용하려는 절대 경로 부분을 지정해야 합니다 . 우리의 목적을 위해 루트 경로는 프로젝트의 클래스 경로가 됩니다.

이를 이해하면 이제 이 방법으로 JarTool 클래스를 완료할 수 있습니다.

public void addFile(JarOutputStream target, String rootPath, String source) 
  throws FileNotFoundException, IOException {
    String remaining = "";
    if (rootPath.endsWith(File.separator)) {
        remaining = source.substring(rootPath.length());
    } else {
        remaining = source.substring(rootPath.length() + 1);
    }
    String name = remaining.replace("\\","/");
    JarEntry entry = new JarEntry(name);
    entry.setTime(new File(source).lastModified());
    target.putNextEntry(entry);
    
    BufferedInputStream in = new BufferedInputStream(new FileInputStream(source));
    byte[] buffer = new byte[1024];
    while (true) {
        int count = in.read(buffer);
        if (count == -1) {
            break;
        }
        target.write(buffer, 0, count);
    }
    target.closeEntry();
    in.close();
}

4. 실례

실행 가능한 jar에 대한 최소 요구 사항을 보여주기 위해 애플리케이션 클래스를 작성한 다음 작동 방식을 확인합니다.

public class Driver {
    public static void main(String[] args) throws IOException {
        JarTool tool = new JarTool();
        tool.startManifest();
        tool.addToManifest("Main-Class", "com.baeldung.createjar.HelloWorld");

        JarOutputStream target = tool.openJar("HelloWorld.jar");
        
        tool.addFile(target, System.getProperty("user.dir") + "\\src\\main\\java",
          System.getProperty("user.dir") + "\\src\\main\\java\\com\\baeldung\\createjar\\HelloWorld.class");
        target.close();
    }
}

HelloWorld 클래스는 텍스트를 출력하는 단일 main() 메서드가 있는 매우 간단한 클래스입니다.

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

그리고 그것이 작동하는지 보여주기 위해 다음 예제가 있습니다.

$ javac -cp src/main/java src/main/java/com/baeldung/createjar/HelloWorld.java
$ javac -cp src/main/java src/main/java/com/baeldung/createjar/JarTool.java
$ javac -cp src/main/java src/main/java/com/baeldung/createjar/Driver.java
$ java -cp src/main/java com/baeldung/createjar/Driver
$ java -jar HelloWorld.jar
Hello World!

여기서는 각 클래스를 컴파일한 다음 HelloWorld jar 를 생성할 Driver 클래스를 실행했습니다 . 마지막으로 jar 파일을 실행하여 "Hello World" 메시지를 인쇄했습니다.

위의 명령은 프로젝트 위치에서 실행해야 합니다.

5. 결론

이 사용방법(예제)에서는 프로그래밍 방식으로 jar 파일을 만들고 파일을 추가한 다음 마지막으로 실행하는 방법을 살펴보았습니다.

물론 코드는 GitHub에서 사용할 수 있습니다.

res – REST with Spring (eBook) (everywhere)