반응형

출처 : https://www.tecmint.com/rsync-local-remote-file-synchronization-commands/

Rsync (원격 동기화): 리눅스에서 Rsync 명령의 10가지 실용적인 예시

Rsync (원격 동기화)리눅스/유닉스 시스템에서 로컬 뿐만이 아니라 원격으로 파일과 디렉터리를 복사하고 동기화하는데 가장 보편적으로 사용되는 명령입니다. rsync 명령의 도움으로 당신은 당신의 데이터를 로컬과 원격으로 디렉터리, 디스크, 네트워크 상에서 복사하고 동기화할 수 있고 두 리눅스 머신 간에 백업과 미러링을 할 수 있습니다.

이 글은 파일을 리눅스 기반의 머신에서 로컬과 원격으로 파일을 전송하는 rsync 명령의 10개의 기본적이고 고급 사용법을 설명합니다. rsync 명령을 실행하는 데 root 사용자일 필요는 없습니다.

Rsync 명령의 장점과 특징

  • 원격 시스템부터 또는 원격으로 파일을 효율적으로 복사하고 동기화 합니다.
  • 링크, 장치, 소유자, 그룹, 권한 복사를 지원합니다.
  • rsync는 파일의 두 집합 사이에 차이점만 전송하는 원격 갱신 프로토콜을 사용하기 때문에 scp (Secure Copy) 보다 빠릅니다. 처음에는 파일 또는 디렉토리의 전체 내용을 소스에서 대상으로 복사하지만 다음부터는 변경된 블록과 바이트만 대상으로 복사합니다.
  • Rsync는 압축 및 압축 해제 방식을 사용하여 데이터를 송수신하면서 대역폭을 덜 소모합니다.

rsync 명령의 기본 문법

# rsync 옵션 원본 대상
# rsync options source destination

명령에서 사용되는 몇 가지 공통 옵션

  • -v : 자세한 설명 출력
  • -r : 데이터를 재귀적으로 복사합니다(그러나 데이터를 전송하는 동안 타임스탬프와 권한을 유지하지 않습니다.)
  • -a : 아카이브 모드, 아카이브 모드는 파일을 재귀적으로 복사할 수 있으며 심볼릭 링크, 파일 권한, 사용자 및 그룹 소유권 및 타임스탬프도 보존합니다.
  • -z : 파일 데이터 압축
  • -h : 사람이 읽을 수 있는 형식의 출력 숫자

추천 읽기: 비표준 SSH 포트와 함께 Rsync를 사용하여 파일/디렉토리를 동기화하는 방법

리눅스 머신에서 rsync 설치하기

다음 명령으로 rsync 패키지를 설치할 수 있습니다.

# yum install rsync (Red Hat 기반 시스템에서)
# apt-get install rsync (On Debian 기반 시스템에서)

1. 로컬에서 파일과 디렉터리 복사/동기화 하기

로컬 컴퓨터에서 파일 복사/동기화 하기

다음 명령어는 로컬에서 한 위치에서 다른 위치로 하나의 파일을 동기화할 것입니다. 여기 이 예시에서 파일 이름 backup.tar/tmp/backups 폴더로 복사되거나 동기화될 것입니다.

[root@tecmint]# rsync -zvh backup.tar /tmp/backups/

created directory /tmp/backups

backup.tar

위 예시에서 목적지(/tmp/backups)가 아직 없다면 rsync는 자동으로 목적지에 디렉터리를 만들 것입니다.

로컬 컴퓨터에서 디렉터리 복사/동기화 하기

다음 명령어는 같은 머신에서 한 디렉터리에서 다른 디렉터리로 모든 파일을 동기화하거나 전송할 것입니다. 여기 이 예시에서 /root/rpmpkgs는 몇 개의 rpm 패키지 파일을 포함하며 /tmp/backups 폴더로 복사될 것입니다.

[root@tecmint]# rsync -avzh /root/rpmpkgs /tmp/backups/

sending incremental file list

rpmpkgs/

rpmpkgs/httpd-2.2.3-82.el5.centos.i386.rpm

rpmpkgs/mod_ssl-2.2.3-82.el5.centos.i386.rpm

rpmpkgs/nagios-3.5.0.tar.gz

rpmpkgs/nagios-plugins-1.4.16.tar.gz

sent 4.99M bytes  received 92 bytes  3.33M bytes/sec

total size is 4.99M  speedup is 1.00

2. 서버에서 또는 서버로 파일과 디렉터리 복사/동기화 하기

로컬 서버에서 원격 서버로 디렉터리 복사하기

이 명령은 로컬 머신에서 원격 머신으로 디렉터리를 동기화 합니다. 예시: 로컬 컴퓨터에 몇개의 RPM 패키지를 포함하는 "rpmpkg" 폴더가 있습니다. 로컬 디렉터리의 내용을 원격서버로 보내고 싶으시면, 다음 명령을 사용할 수 있습니다.

[root@tecmint]$ rsync -avz rpmpkgs/ root@192.168.0.101:/home/

root@192.168.0.101's password:

sending incremental file list

./

httpd-2.2.3-82.el5.centos.i386.rpm

mod_ssl-2.2.3-82.el5.centos.i386.rpm

nagios-3.5.0.tar.gz

nagios-plugins-1.4.16.tar.gz

sent 4993369 bytes  received 91 bytes  399476.80 bytes/sec

로컬 서버에서 원격 서버로 디렉터리의 특정 파일만 복사하기(역자추가)

여기 예시로 로컬 컴퓨터에 몇개의 RPM 패키지를 포함하는 "rpmpkg" 폴더가 있습니다. 로컬 디렉터리의 확장자가 rpm인 파일만을 원격서버로 보내고 싶으시면, 다음 명령을 사용할 수 있습니다.

[root@tecmint]$ rsync -avz rpmpkgs/*.rpm root@192.168.0.101:/home/

root@192.168.0.101's password:

sending incremental file list

./

httpd-2.2.3-82.el5.centos.i386.rpm

mod_ssl-2.2.3-82.el5.centos.i386.rpm

sent ? bytes  received ? bytes  ? bytes/sec

원격 디렉터리를 로컬 머신으로 복사/동기화 하기

이 명령은 당신이 원격 디렉터리를 로컬 디렉터리로 동기화 하도록 도움을 줄 것입니다. 여기 예시로 원격서버에 있는 디렉터리 /home/tarunika/rmpkgs는 당신의 로컬 컴퓨터의 /tmp/myrpms로 복사될 것입니다.

[root@tecmint]# rsync -avzh root@192.168.0.100:/home/tarunika/rpmpkgs /tmp/myrpms

root@192.168.0.100's password:

receiving incremental file list

created directory /tmp/myrpms

rpmpkgs/

rpmpkgs/httpd-2.2.3-82.el5.centos.i386.rpm

rpmpkgs/mod_ssl-2.2.3-82.el5.centos.i386.rpm

rpmpkgs/nagios-3.5.0.tar.gz

rpmpkgs/nagios-plugins-1.4.16.tar.gz

sent 91 bytes  received 4.99M bytes  322.16K bytes/sec

total size is 4.99M  speedup is 1.00

3. SSH를 통한 RSync

rsync로 우리는 데이터 전송을 위해 SSH (Secure Shell) 을 사용할 수 있습니다. SSH 프로토콜을 사용하면 데이터가 전송되는 동안 아무도 읽을 수 없도록 암호화된 보안 연결로 데이터가 인터넷의 유선을 통해 전송되고 있음을 확인할 수 있습니다.

또한 우리가 rsync를 사용할 때 특정한 작업을 성공하기 위해 user/root 비밀번호를 제공할 필요가 있습니다. SSH 옵션을 사용하여 암호화된 방법으로 로그인하여 전송할 수 있고 당신의 비밀번호는 안전할 것입니다.

SSH로 원격 서버에서 로컬 서버로 파일 복사하기

rsync로 프로토콜을 지정하기 위해 "-e" 옵션을 당신이 사용하기 원하는 프로토콜 이름을 함께 제공할 필요가 있습니다. 여기 예시에서 "-e" 옵션으로 "ssh" 를 사용하여 데이터 전송을 수행할 것입니다.

[root@tecmint]# rsync -avzhe ssh root@192.168.0.100:/root/install.log /tmp/

root@192.168.0.100's password:

receiving incremental file list

install.log

sent 30 bytes  received 8.12K bytes  1.48K bytes/sec

total size is 30.74K  speedup is 3.77

SSH로 로컬 서버에서 원격 서버로 파일 복사하기

[root@tecmint]# rsync -avzhe ssh backup.tar root@192.168.0.100:/backups/

root@192.168.0.100's password:

sending incremental file list

backup.tar

sent 14.71M bytes  received 31 bytes  1.28M bytes/sec

total size is 16.18M  speedup is 1.10

추천 읽기: 리눅스에서 새로운 또는 변경/수정된 파일을 동기화하기 위해 Rsync 사용하기

4. rsync로 데이터 전송하는 동안 진행상태 보기

하나의 머신에서 다른 머신으로 데이터가 전송되는 동안 진행상태를 보기 위해 우리는 '--progress' 옵션을 사용할 수 있습니다. 이것은 파일과 전송을 완료하는 데 남은 시간을 표시합니다.

[root@tecmint]# rsync -avzhe ssh --progress /home/rpmpkgs root@192.168.0.100:/root/rpmpkgs

root@192.168.0.100's password:

sending incremental file list

created directory /root/rpmpkgs

rpmpkgs/

rpmpkgs/httpd-2.2.3-82.el5.centos.i386.rpm

           1.02M 100%        2.72MB/s        0:00:00 (xfer#1, to-check=3/5)

rpmpkgs/mod_ssl-2.2.3-82.el5.centos.i386.rpm

          99.04K 100%  241.19kB/s        0:00:00 (xfer#2, to-check=2/5)

rpmpkgs/nagios-3.5.0.tar.gz

           1.79M 100%        1.56MB/s        0:00:01 (xfer#3, to-check=1/5)

rpmpkgs/nagios-plugins-1.4.16.tar.gz

           2.09M 100%        1.47MB/s        0:00:01 (xfer#4, to-check=0/5)

sent 4.99M bytes  received 92 bytes  475.56K bytes/sec

total size is 4.99M  speedup is 1.00

5. --include 와 --exclude 옵션 사용하기

이 두 가지 옵션을 사용하면 매개변수를 지정하여 파일을 포함제외할 수 있습니다. 이 옵션은 동기화에 포함할 파일 또는 디렉터리를 지정하고 전송을 원하지 않는 파일 및 폴더를 제외하는 데 도움이 됩니다.

여기 예시로 rsync 명령은 'R' 로 시작하는 파일이나 디렉터리를 포함하며 모든 다른 파일과 디렉터리는 제외될 것입니다.

[root@tecmint]# rsync -avze ssh --include 'R*' --exclude '*' root@192.168.0.101:/var/lib/rpm/ /root/rpm

root@192.168.0.101's password:

receiving incremental file list

created directory /root/rpm

./

Requirename

Requireversion

sent 67 bytes  received 167289 bytes  7438.04 bytes/sec

total size is 434176  speedup is 2.59

6. --delete 옵션 사용하기

파일 또는 디렉토리가 원본에 없지만 대상에는 이미 존재하는 경우 동기화하는 동안 대상에서 기존 파일/디렉토리를 삭제할 수 있습니다.

'-delete' 옵션을 사용하여 원본 디렉토리에 없는 파일을 삭제할 수 있습니다.

원본와 대상은 동기화 됩니다. 이제 대상에서 새 파일 test.txt가 만들어 집니다.

[root@tecmint]# touch test.txt
[root@tecmint]# rsync -avz --delete root@192.168.0.100:/var/lib/rpm/ .
Password:
receiving file list ... done
deleting test.txt
./
sent 26 bytes  received 390 bytes  48.94 bytes/sec
total size is 45305958  speedup is 108908.55

대상에는 test.txt((라는 새 파일이 있으며 **'–delete' 옵션으로 소스와 동기화하면 test.txt 파일이 제거됩니다.

7. 전송될 파일의 최대 크기 설정

전송되거나 동기화될 파일의 (최대) 크기를 지정할 수 있습니다. "--max-size" 옵션과 함께 최대 크기를 지정할 수 있습니다. 여기 예시로 최대 파일 크기는 200k 이며, 이 명령은 200k 보다 같거나 작은 파일만 전송할 것입니다.

[root@tecmint]# rsync -avzhe ssh --max-size='200k' /var/lib/rpm/ root@192.168.0.100:/root/tmprpm

root@192.168.0.100's password:

sending incremental file list

created directory /root/tmprpm

./

Conflictname

Group

Installtid

Name

Provideversion

Pubkeys

Requireversion

Sha1header

Sigmd5

Triggername

__db.001

sent 189.79K bytes  received 224 bytes  13.10K bytes/sec

total size is 38.08M  speedup is 200.43

8. 성공적인 전송 후에 원본 파일 자동으로 지우기

메인 웹 서버와 데이터 백업 서버가 있다고 가정하면, 매일 백업을 생성하고 당신의 백업서버로 동기화 하면 이제 당신의 웹 서버에 있는 백업의 로컬 복제본은 유지하고 싶지 않을 것입니다.

그럼, 파일 전송 완료될 때까지 기다렸다가 수동으로 이 로컬 백업을 삭제해야 할까요? 당연히 아닙니다. 이 자동 삭제는 '--remove-source-files' 옵션을 사용하여 할 수 있습니다.

[root@tecmint]# rsync --remove-source-files -zvh backup.tar /tmp/backups/

backup.tar

sent 14.71M bytes  received 31 bytes  4.20M bytes/sec

total size is 16.18M  speedup is 1.10

[root@tecmint]# ll backup.tar

ls: backup.tar: No such file or directory

9. rsync로 모의테스트 하기

당신이 초보자이고 rsync를 사용하고 있고 당신의 명령이 정확히 무엇을 하는지 모르는 경우 Rsync는 대상 폴더의 항목을 실제로 엉망으로 만들 수 있으며 실행 취소를 수행하는 것은 지루한 작업이 될 수 있습니다.

추천 읽기: Rsync 사용하여 두 웹 서버/웹 사이트를 동기화 하는 방법

이 옵션을 사용하면 아무 것도 변경되지 않고 명령의 테스트 실행만 수행하고 명령의 출력이 표시됩니다. 출력이 원하는 것과 정확히 일치하면 명령에서 '-dry-run' 옵션을 제거하고 명령의 출력을 표시할 수 있습니다. 터미널에서 실행합니다.

root@tecmint]# rsync --dry-run --remove-source-files -zvh backup.tar /tmp/backups/

backup.tar

sent 35 bytes  received 15 bytes  100.00 bytes/sec

total size is 16.18M  speedup is 323584.00 (DRY RUN)

10. 대역폭 제한을 설정하고 파일 전송하기

당신은 '–bwlimit' 옵션의 도움으로 한 머신에서 다른 머신으로 데이터를 전송하는 동안 대역폭을 설정할 수 있습니다. 이 옵션은 입출력(I/O) 대역폭을 제한하도록 우리에게 도움을 줍니다.

[root@tecmint]# rsync --bwlimit=100 -avzhe ssh  /var/lib/rpm/  root@192.168.0.100:/root/tmprpm/
root@192.168.0.100's password:
sending incremental file list
sent 324 bytes  received 12 bytes  61.09 bytes/sec
total size is 38.08M  speedup is 113347.05

또한 기본적으로 rsync는 변경된 블록과 바이트만 동기화합니다. 명시적으로 전체 파일을 동기화하려면 '-W' 옵션을 사용합니다.

[root@tecmint]# rsync -zvhW backup.tar /tmp/backups/backup.tar
backup.tar
sent 14.71M bytes  received 31 bytes  3.27M bytes/sec
total size is 16.18M  speedup is 1.10

이제 rsync에 알아 보았고 더 많은 옵션에 대한 매뉴얼 페이지에서 볼 수 있습니다. 앞으로 더 흥미롭고 흥미로운 튜토리얼을 위해 Tecmint와 계속 연결하십시오. 귀하의 의견과 제안을 남겨주세요.

반응형
반응형

출처

https://dzone.com/articles/java-8-how-to-create-executable-fatjar-without-ide

명령줄로 실행 가능한 Fat JAR 생성하기

명령줄 만으로 실행 가능한 fat JAR 파일을 만들고 실행하고 싶으십니까? 필요한 기초 작업과 수행 방법을 확인하십시오.

이 글은 추가 플러그인, IDE 또는 다른 도구를 사용하지 않고 순수한 명령 줄과 Java에서 Fat JAR (Java 아카이브 파일)을 만들 수 있는 가능성을 검토하는 내 블로그 게시물을 통합한 내용입니다.

빌드 도구 (Ant, Maven 또는 Gradle)의 세계에서는 명령줄에 대해 생각하는 것이 유용하지 않을 수도 있습니다. 가장 유명한 IDE (IntelliJ, Eclipse 또는 NetBeans)는 빌드 도구와 구현을 즉시 제공합니다. 그러나 명령줄 만 있고 인터넷에 액세스 할 수 없다고 가정해 보겠습니다.

그러면 어떻게 하시겠습니까?

파트 1: ExecutableOne.jar 컴파일 (GitHub)

이 첫 번째 부분의 목표는 실행 가능한 JAR 파일을 만드는 것입니다. ExecutableOne.jar 이라고 부르겠습니다. 명령줄을 열어서 간단한 프로젝트 폴더를 생성해 보겠습니다. 예제 프로젝트 구조는 Maven 표준 디렉토리 레이아웃 구조를 따릅니다.

./libs
./out
./README.md
./src
./src/main
./src/main/java
./src/main/java/com
./src/main/java/com/exec
./src/main/java/com/exec/one
./src/main/resources

우리의 의도는 실행 가능한 JAR 파일을 만드는 것이므로 기본 클래스를 만들어야 합니다. com.exec.one 패키지에서 해봅시다. 패키지는 샘플 프로젝트 구조의 SRC/MAIN/JAVA 폴더에서 찾을 수 있습니다.

package com.exec.one;

public class Main {
    public static void main(String[] args){                                                                                 
        System.out.println("Main Class Start");                     
    }                                                      
}

SRC/MAIN/RESOURCES 폴더 안에 META-INF 폴더를 만든 다음 그 안에 MANIFEST.MF 파일을 배치합니다. 새로 생성된 MANIFEST.MF 파일을 열고 기본 설명을 입력해 보겠습니다.

Manifest-Version: 1.0   
Class-Path: .                                                                                                                                                                          
Main-Class: com.exec.one.Main

참고 : JAR 파일 당 하나의 MANIFEST.MF 파일만 있습니다.

MANIFEST.FM 파일에는 JAR 파일이 사용되는 방법에 대한 세부 사항이 포함되어 있습니다. 자세한 내용은 다루지 않습니다. 정의한 옵션에 집중하겠습니다.

  1. Manifest-Version : manifest 파일 버전입니다.
  2. 클래스 경로 : 애플리케이션 또는 확장 클래스 로더는 이 속성 값을 사용하여 내부 검색 경로를 구성합니다. 원래 클래스 로더는 검색 경로에서 각 요소를 다운로드하고 엽니다. 이러한 목적을 위해 간단한 선형 검색 알고리즘이 사용되었습니다.
  3. Main-Class : 시작시에 런처가 로드할 클래스의 이름이 있습니다.

이제 *.jar 라이브러리없이 JAR 파일을 생성합니다. 프로젝트 구조의 LIBS 폴더는 여전히 비어 있습니다. 이렇게 하려면 먼저 javac를 사용하여 프로젝트를 컴파일해야합니다. 한편 출력은 OUT 폴더에 저장합니다. 명령 줄로 돌아가서 프로젝트 루트 안에 다음을 입력해 보겠습니다.

$javac -cp ./src/main/java ./src/main/java/com/exec/one/*.java -d ./out/

프로젝트가 OUT 디렉터리로 컴파일되었습니다. ls 명령을 사용하여 확인할 수 있습니다.

두 번째 단계는 OUT 디렉터리에 있는 리소스에서 실행 가능한 JAR 파일을 만드는 것입니다. 명령줄로 돌아가서 다음 명령을 실행합니다.

$jar cvfm ExecutableOne.jar ./src/main/resources/META-INF/MANIFEST.MF -C ./out/ .

우리가 사용한 JAR 도구 옵션을 간단히 검토 및 설명해 보겠습니다.

  • c : 새 JAR 파일을 만들려고 함을 나타냅니다.
  • v : 표준 출력에 대한 자세한 출력을 생성합니다.
  • f : 생성 할 jar 파일을 지정합니다.
  • m : 우리가 사용하는 매니페스트 파일을 나타냅니다. 매니페스트 파일에는 이름-값 쌍이 포함됩니다.
  • -C : 디렉토리에 대한 임시 변경을 나타냅니다. 이 디렉토리에서 JAR 파일로 클래스가 추가됩니다. 점은 모든 클래스 (파일)를 나타냅니다.

최종 출력을 위해 명령줄을 열고 다음을 입력합니다.

$java -jar ./ExecutableOne.jar

standard output: 
Main Class Start

잘 했습니다! 파트 2로 이동하겠습니다.

파트 2: 추가적인 패키지와 함께 ExecutableOne.jar 컴파일

이 섹션의 주요 목표는 추가적인 패키지를 포함하여 실행 가능한 JAR 파일을 컴파일 아는 방법을 보여드리겠습니다. 이러한 목적을 위해, 우리는 MagicService를 만들 것입니다. 이 서비스는 우리에게 getMessage() 메소드를 우리에게 제공하며 표준 출력으로 메세지를 출력합니다.

명령줄을 열어 새로운 폴더 _SERVICE_와 파일 MagicService.java를 만듭니다.

$mkdir src/main/java/com/exec/one/service
$vi src/main/java/com/exec/one/service/MagicService.java

새롭게 만들어진 MagicService는 다음 예제에서 사용될 수 있습니다.

package com.exec.one.service;                                                                                                                                                          
public class MagicService {                                                                                                                                                            
  private final String message;                                       
    public MagicService(){ 
        this.message = "Magic Message";
    }                    

    public String getMessage(){                                                      
         return message;                              
    }
}

MagicService는 Main 클래스보다 패키싲 구조에서 다른 위치에 있습니다. 이제 우리는 Main 클래스로 돌아가서 새롭게 만든 MagicService를 import 합니다. import하고 서비스 인스턴스를 만든 뒤에 Main 클래스는 getMessage() 메소드로 접근을 할 것입니다. Main 클래스는 다음 방법으로 변경될 것입니다.

package com.exec.one;                                                                                                                                                                  
import com.exec.one.service.MagicService;                                                                                                                                              
public class Main {                                                                                                         
    public static void main(String[] args){
        System.out.println("Main Class Start");            
        MagicService service = new MagicService();          
        System.out.println("MESSAGE : " + service.getMessage());
     }
} 

이제 코드를 컴파일 할 준비가 된 지점에 도달했습니다. 명령줄로 돌아가 Executable-One 프로젝트의 루트 폴더로 이동하겠습니다. 첫 번째 단계는 Executable-One 프로젝트를 OUT 폴더로 컴파일 / 재컴파일하는 것입니다. 이를 위해 새로 생성된 MagicService.java 클래스의 위치를 추가해야 합니다.

javac -cp ./src/main/java ./src/main/java/com/exec/one/*.java ./src/main/java/com/exec/one/**/*.java -d ./out/

두 번째 단계는 컴파일된 클래스에서 실행 가능한 JAR 파일을 만드는 것입니다. JAR 파일 논리를 변경하지 않았으므로 명령을 변경할 필요가 없습니다. 이는 MANIFEST.FM 파일이 변경없이 그대로 유지됨을 의미합니다.

Manifest-Version: 1.0
Class-Path: .                                                           
Main-Class: com.exec.one.Main

이제 샘플 프로젝트의 루트 디렉토리에서 Part 1과 유사한 명령을 다시 실행할 수 있습니다.

jar cvfm ExecutableOne.jar ./src/main/resources/META-INF/MANIFEST.MF -C ./out/ .

생성된 JAR 파일을 실행하여 표준 출력에 인쇄된 메시지를 얻습니다.

$java -jar ExecutableOne.jar 
output: 
Main Class Start
MESSAGE : Magic Message

축하합니다. 다시 잘 하셨습니다!

파트 3: 실행 가능한 Fat JAR 생성하기 (GitHub)

이 파트의 목표는 개발된 프로그램에서 모든 필요한 의존성을 포함하는 fat JAR(Java Archive)를 생성하는 것입니다. 외부 라이브러리로 우리는 파트 2에서 생성된 JAR 파일을 사용할 필요가 있습니다. 파트 3에서 우리는 (위의 링크에서 다운로드 받을 수 있는) "Executable-Two"라고 불리는 샘플 프로젝트를 생성합니다.

executable-two 프로젝트는 다음과 같은 폴더 구조를 가집니다.

./libs
./libs/ExecutableOne.jar
./out
./README.md
./src
./src/main
./src/main/java
./src/main/java/com
./src/main/java/com/exec
./src/main/java/com/exec/two
./src/main/java/com/exec/two/Main.java
./src/main/resources
./src/main/resources/META-INF
./src/main/resources/META-INF/MANIFEST.MF

LIBS 폴더는 전에 생성된 "ExecutableOne.jar"를 포함합니다. "ExecutableOne.jar"는 우리가 ExecutableTwo 안에서 사용될 MagicService 클래스를 포함합니다. 우리는 클래스 MagicService를 인스턴스화 하여 public 메소드 getMessage()를 실행할 것입니다. 프로젝트 "ExecutableTwo"의 메인 클래스 안에서 이 모든 것이 발생할 것입니다.

프로젝트 패키지 com.exec.two 에서 다음 메인 클래스를 생성합시다.

package com.exec.two;                                                                                                                                                                  
import com.exec.one.service.MagicService;                                                                                                                                              
public class Main {
    public static void main(String[] args){
        System.out.println("Executable-Two Main");
        MagicService service = new MagicService();                                                                                 System.out.println("MagicService from Executable-ONE");                                                                     System.out.println("MESSAGE: " + service.getMessage());
     }
}

이제 우리는 JAR 파일 생성의 모든 것이 준비 되었습니다. 이전에 생성한 getMessage() 메소드를 실행한 JAR 라이브러리에서 MagicService를 가져 왔습니다. 다음 몇 단계에서는 Java JDK에서 제공하는 javac 및 JAR 도구를 사용합니다. 명령 줄로 돌아가서 프로젝트를 컴파일해 보겠습니다. 명령에서 클래스 경로를 사용된 라이브러리로 확장해야 함을 컴파일러에 알려야합니다.

$javac -cp ./src/main/java 
./src/main/java/com/exec/two/*.java -d ./out/ 
-classpath ./libs/ExecutableOne.jar

"Executable-Two" 프로젝트가 OUT 디렉토리로 성공적으로 컴파일 되었습니다.

이제 fat JAR 생성을 위해 OUT 디렉토리를 적절하게 준비할 때입니다. OUT 디렉토리 안에는 "Executable-Two"를 위해 만든 컴파일 된 클래스가 있습니다. 한편, JAR 도구는 파일 시스템에 물리적으로 위치한 파일만 읽습니다. 압축된 JAR 파일은 읽지 않습니다. 물론 이는 JAR 도구가 OUT 디렉토리에있는 * .jar 파일의 압축을 풀거나 읽지 않음을 의미합니다.

그 결과 ExecutableOne.jar을 OUT 디렉토리에 복사하더라도 JAR 도구는 ExecutableOne.jar 파일의 압축을 풀지 않고 라이브러리가 결과에 추가됩니다 (압축된 형태로). 물론 압축 되었기 때문에 무시됩니다.

문제는 $java -jar 도구가 내부 패키지 *.jar 아카이브 파일을 읽지 않는다는 것입니다!

이는 이전에 생성된 Java 아카이브 (JAR) "Executable-One.jar"을 "Executable-Two" 프로젝트의 OUT 디렉토리에 압축 해제해야 함을 의미합니다. 명령 줄을 열고 다음을 입력합니다.

$cp libs/ExecutableOne.jar ./out/
$cd ./out
$jar xf ExecutableOne.jar
$rm ExecutableOne.jar

이제 "Executable-Two" 프로젝트 출력 디렉토리를 새 JAR 파일의 소스 폴더로 사용할 준비가 되었습니다.

참고: 모든 실행 가능한 JAR 파일에는 하나의 MANIFEST.FM 파일만 사용할 수 있습니다.

"Executable-Two"프로젝트를 JAR 아카이브 파일에 묶기 위해 ./src/main/resources/META-INF/ 폴더에 새로 생성된 매니페스트 파일을 사용합니다.

Manifest-Version: 1.0                              
Class-Path: .                                      
Main-Class: com.exec.two.Main

다음처럼 타이핑하여 이 모두를 묶을 수 있습니다..

$jar cvfm ExecutableTwo.jar ./src/main/resources/META-INF/MANIFEST.FM -C./out/ .

새로 생성된 fat JAR 파일인 "ExecutableTwo.jar"을 실행하면 다음과 같은 출력이 나타납니다.

$java -jar ./ExecutableTwo.jar
output:
Executable-Two Main
MagicService from Executable-ONE
MESSAGE: Magic Message

축하합니다! 당신은 fat JAR 파일을 실행했습니다!

반응형

+ Recent posts