Spring Boot 애플리케이션 보호
springboot는 Spring Boot 애플리케이션을 보호하며 BOOT-INF/classes, BOOT-INF/lib, Spring Boot Loader, 프레임워크 스캔을 처리합니다.
1. GUI에서 하는 방법
-
애플리케이션 유형 페이지에서 Spring Boot를 선택합니다.

-
보호할 Spring Boot 애플리케이션, 함께 넣을 Java 버전, 대상 플랫폼을 선택한 뒤 간단 모드와 고급 모드 중에서 고릅니다.

-
고급 모드에서는 출력 레이아웃, 보호할 의존성 JAR, JavaFX 설정, JVM 시작 옵션, 제외 규칙을 선택합니다. 간단 모드는 호환성 검사 결과에서 레이아웃과 제외 규칙을 정합니다. 각 옵션의 의미는 Protector4J 고급 모드 설정을 참고하세요.

-
출력 디렉터리를 선택하고 요약을 확인한 뒤 보호 실행을 클릭합니다.

2. CLI 예제
가장 짧은 형태:
p4j springboot app.jar dist
기본값은 p4jx-fat 레이아웃입니다. 다른 레이아웃을 직접 고르려면:
p4j springboot app.jar dist --layout fat
p4j springboot app.jar dist --layout separate
애플리케이션의 일부만 보호하는 경우:
p4j springboot app.jar dist \
--protect 'com.example.service.impl.**' \
--exclude 'com.example.dto.**,com.example.config.**'
3. 출력 구조와 레이아웃
p4jx-fat: 기본 레이아웃, 단일 보호 아카이브
dist/
├── app.p4jx # jar 아카이브 확장자를 쓰면 app.jar
├── vlxjre/
├── run.sh
├── run.command
└── run.bat
특징:
- 애플리케이션 전체가 하나의 P4JX 아카이브로 배포됩니다.
- 물리 파일은 기본적으로 ZIP이 아닙니다.
- Spring Boot 리소스, 중첩된 의존성, 메타데이터는 가상 JAR 뷰로 제공됩니다.
- 보호 범위가 가장 넓어, 서드파티 클래스패스 스캐너에 의존하지 않는 애플리케이션에 적합합니다.
fat: Spring Boot 호환 레이아웃
dist/
├── app.jar
├── app.p4jx # jar 확장자를 쓰면 app-protected.jar
├── vlxjre/
└── run.*
특징:
app.jar가 표준BOOT-INF물리 구조를 유지합니다.- 보호 대상 클래스의 실제 구현은 옆에 있는 P4JX 아카이브에 들어갑니다.
- ClassGraph나 Reflections를 쓰는 등 물리적인 Spring Boot JAR 구조를 스캔해야 하는 애플리케이션에 적합합니다.
- 두 파일은 서로 의존하므로 반드시 함께 갱신하고 함께 배포해야 합니다.
separate: 분리형 호환 레이아웃
dist/
├── plain-launcher.jar
├── app.p4jx
├── lib/
├── vlxjre/
└── run.*
특징:
- Spring Boot Loader, 보호되지 않은 클래스, 의존성을 따로 둡니다.
lib/*평면 클래스패스를 요구하는 오래된 연동 환경에 적합합니다.- 보호 대상 클래스는 생성된 실행기가 미리 로딩합니다.
- 새 프로젝트에서는
p4jx-fat, 또는 스캐너가 권장하는p4jx-fat/fat을 쓰세요.
레이아웃 고르는 법
| 상황 | 권장 레이아웃 |
|---|---|
| 표준적인 Spring Boot 서비스 | p4jx-fat |
| ClassGraph, Reflections 같은 스캐너를 실제로 사용 | fat |
| 외부 의존성을 평면 디렉터리에 두거나, 의존성 파일을 따로 암호화해야 함 | separate |
| 판단하기 어려움 | 먼저 --compat-scan 실행 |
ZIP 오버레이는 ZIP 중앙 디렉터리를 직접 읽는 도구에만 도움이 됩니다. ClassLoader와 클래스패스 스캐너가 필요로 하는 물리적 Spring Boot 구조를 대신하지는 못합니다.
4. 실행
./run.sh --spring.profiles.active=prod
Windows:
run.bat --spring.profiles.active=prod
출력 디렉터리의 vlxjre를 시스템 JRE로 바꾸지 마세요.
Windows용으로 패키징할 때는 네이티브 실행기도 만들 수 있습니다. 세 레이아웃 모두 지원하며 실행 스크립트와 함께 존재합니다. 자세한 내용은 Windows EXE 실행기 생성을 참고하세요.
JVM 시작 옵션
패키징할 때 옵션을 고정할 수 있습니다. GUI의 JVM 시작 옵션에 한 줄에 하나씩 입력하거나 명령줄에서 지정합니다.
p4j springboot app.jar dist \
--jvm-option -Xms1g \
--jvm-option -Xmx2g
배포된 패키지에 한 번만 옵션을 더하려면:
APP_JAVA_OPTS="-Duser.timezone=Asia/Seoul" ./run.sh
배포된 스크립트를 직접 편집할 수도 있습니다.
- macOS와 Linux:
run.sh에서 생성된JVM_OPTS=(...)와JVM_OPTS+=(...)뒤에JVM_OPTS+=("-Xms1g" "-Xmx2g")를 추가합니다. - Windows:
run.bat에서 생성된set "JVM_OPTS=..."뒤에set "JVM_OPTS=%JVM_OPTS% -Xms1g -Xmx2g"를 추가합니다.
패키저가 Spring Boot나 JavaFX를 위해 만든 --add-opens, 모듈 경로 같은 옵션은 지우지 마세요. 다시 패키징하면 직접 수정한 내용은 모두 덮어씌워집니다. 자세한 내용은 JVM 시작 옵션을 참고하세요.
5. 보호 범위
기본적으로 BOOT-INF/classes 아래의 애플리케이션 클래스를 보호합니다. 다음과 같은 Spring 관련 클래스는 보호하지 않는 편이 안전합니다.
@Controller,@RestController,@ControllerAdvice클래스@Configuration클래스, 자동 구성 클래스, AOT·CGLIB로 확장된 클래스- Jackson DTO, JPA 엔티티, 레코드, 검증 모델
- 애플리케이션 진입점과 프레임워크가 직접 생성하거나 프록시하는 클래스
- 실행 중 바이트코드 확장이 필요한 클래스
서비스 구현을 보호하고 공개된 파사드나 인터페이스를 통해 접근하세요. 규칙에는 정확한 클래스 이름과 pkg.*, pkg.**를 쓸 수 있습니다.
6. 의존성 JAR 보호
--protect-lib는 BOOT-INF/lib에서 조건에 맞는 의존성을 보호합니다. 세 레이아웃 모두에서 쓸 수 있습니다.
p4j springboot app.jar dist \
--protect-lib 'company-core-*.jar,pricing-*.jar'
자사의 비공개 의존성만 보호하세요. 「더 많이 보호하겠다」는 이유로 Spring, Tomcat, 로깅 라이브러리, 데이터베이스 드라이버 같은 서드파티 프레임워크를 암호화하지 마세요.
7. 호환성 검사
p4j springboot app.jar --compat-scan
p4j springboot app.jar dist --compat-apply
두 옵션은 함께 쓸 수 없습니다. 차이는 다음과 같습니다.
| 옵션 | 동작 | 사용 시점 |
|---|---|---|
--compat-scan | 입력 JAR를 검사해 위험 요소와 설정 권장을 출력하고 종료합니다. 인코딩하지 않고 dist도 만들지 않으므로 출력 디렉터리가 필요 없습니다. | 처음 보호할 때, Spring Boot나 다른 의존성을 올린 뒤, 보호 범위나 레이아웃을 바꾼 뒤, 호환성 문제를 조사할 때 먼저 보고서를 확인합니다. |
--compat-apply | 검사한 뒤 보수적인 권장 설정을 반영하고 그대로 인코딩해 결과물을 만듭니다. 따라서 출력 디렉터리가 필요합니다. | 검사 결과를 확인하고 권장 설정을 받아들인 뒤 패키징을 마무리할 때 사용합니다. 규칙이 검증된 반복 빌드나 CI에도 적합합니다. |
springboot에서 --compat-apply는 검사 결과에 따라 레이아웃을 고르고 제외 규칙을 추가하며 스캐너 ZIP 오버레이, JavaFX, 아카이브 확장자 등을 조정할 수 있습니다. 제외 규칙을 뺀 나머지는 명령줄에서 직접 지정한 값이 우선합니다. 권장되는 제외 규칙은 기본적으로 직접 지정한 --exclude와 합쳐집니다. 자동 추가를 원하지 않으면 --no-compat-excludes를 함께 전달하세요. 스캐너는 정적 휴리스틱 분석만 수행하므로 소스 수정이 필요한 문제는 --compat-apply로 해결되지 않으며, 패키징한 뒤에도 대상 플랫폼에서 회귀 테스트가 필요합니다.
그 밖의 CLI 명령, 전체 옵션, 환경 변수, 자동화 예제는 CLI 레퍼런스를 참고하세요.