의존성에 대하여
다른 사람들이 열심히 만들어놓은 기능들을 -> 라이브러리화 해서 배포해주면 -> 저희는 maven/gradle로 implements 혹은 <dependency> 태그로 한 줄만 추가하면 해당 기능을 라이브러리처럼 간편하게 imports 하여 이용할 수 있게됩니다.
pom.xml 에 일반적인 방법으로 추가한 의존성은 빌드시 인터넷에 연결되어 외부에서 라이브러리 소스를 참조해옵니다(어떻게보면 다운로드 받아온다고 하는게 맞겠네요). 이게 기본적으로 의존성을 이용하는 이유이기도 하죠.
이런 의존성 참조 기능이 없었다면, 우리는 남들이 만들어놓은 좋은기능을 직접 .jar 패키지 파일로 다운받아와서, 직접 프로젝트 내부에 설치해놓고, classpath로 연결해서 하나하나 읽어와야 한답니다.
구현 목적
네.. 그 번거로운 작업을 하게 되었습니다.
의존성 라이브러리 파일들을 직접 하나하나 .jar로 받아서 연결하는 방식이요...
- 본 프로젝트는 거래처 외부 보안 클라우드망에서 운영될 예정이며, 해당 망은 인터넷이 차단된 폐쇄망(air-gapped) 환경임.
- Maven Central Repository 또는 외부 저장소에 접근할 수 없기 때문에, pom.xml에 선언된 모든 의존성을 로컬 .jar 파일로 직접 관리해야 함.
- mvn clean package를 수행하여 실행 가능한 fat JAR (Spring Boot Executable Jar) 를 생성할 수 있어야 정상 배포 및 실행이 가능함.
수행 작업 및 구조 변경
1. 라이브러리 내장화
pom.xml에 선언된 모든 라이브러리와 해당 전이(dependency tree) 의존성을 /lib 디렉토리에 .jar 파일로 직접 다운로드 및 포함해야 합니다.
이 때, 기존 pom.xml에 추가한 의존성 라이브러리만 추가하는것이 아니고, 추가한 라이브러리.jar를 압축해제 하여 내부의 pom.xml에 적혀져있는 하위 라이브러리까지 전부 .jar로 받아 등록해야 오류가 발생하지 않습니다.
- 로컬 개발 환경에서 다음 명령어를 통해 .jar 파일 일괄 추출 : mvn dependency:copy-dependencies DoutputDirectory=./lib
[IntelliJ] pom.xml의 라이브러리 목록 압축하기 | maven으로 라이브러리 다운로드받기
외부사에 소스점검을 진행하기 위해,maven 설정파일인 pom.xml에서 사용하고있는 설정파일 목록의라이브러리 목록들을 실제 로컬 폴더에 다운로드 및 압축받아 메일로 전송하게 되었습니다. 그런
esclife.tistory.com
➡️위의 명령어로 다운로드 받아지지 않은 누락 라이브러리 & 하위 라이브러리 다운로드 방법
1) 의존 라이브러리를 전부 파일로 추가하여 연결했는데도 import문에 오류 발생 -> 하위라이브러리 부족
: import 오류가 나는 라이브러리를 검색하여, 라이브러리 명을 찾고 해당 라이브러리 .jar 파일을 압축해제하세요. 그 안에 META-INFO 폴더안에 들어가면 pom.xml로 의존성 설정파일이 있습니다. 거기적힌 하위 의존성도 모두 .jar 파일로 받아서 추가하고 scope, systempath로 연결해주시면 됩니다. 다 연결되면 import에 에러가 발생하지 않을거에요 !
2) 버전이 안맞을 수 있습니다
: 의존성 내부화를 할 때는 무조건 version 태그에 직접 버전을 설정해줘야 하는데요. 이 때 꿀팁은 최대한 최신 버전으로 올려서 맞춰보는거에요. 이전 버전끼리 충돌하는 경우가 많으니 가장 최신버전부터 하나씩 내려보며 맞춰보세요. 저는 보통 인텔리제이에서 자동으로 version 태그에 추천버전이 뜨더라구요. 작성해놓고 해당버전 .jar 파일을 받아서 /lib 경로에 넣어주는 순서로 연결했어요.
*maven 의존성 라이브러리 .jar 다운받기*
추출된 라이브러리를 pom.xml에서 아래 형식으로 수동 등록:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.5.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/spring-boot-starter-3.5.0.jar</systemPath>
</dependency>
- 정상 등록되었다면 intelliJ 좌측 메뉴 패널의 'Extenal Libraries'에 외부의존성이아닌 내부의존성으로 추가된 라이브러리 항목이 다르게 표시됩니다.
- scope, systemPath 태그를 추가하는 순간부터 에러가 많이 발생하니.. 소스코드 수정시에는 주석해놓고 기존의 외부 의존성 추가방식으로 작성해놓고 수정해주세요.
2. 빌드 플러그인 설정
라이브러리 .jar 파일 추가와, systemPath 연결이 모두 완료되었다면.
Maven 빌드 시 lib/ 폴더의 system scope JAR 파일을 포함한 실행 가능한 fat JAR 가 생성될 수 있도록 'spring-boot-maven-plugin' 플러그인 설정을 추가해야 합니다. :: includeSystemScope, mainClass 설정태그를 추가했습니다.
네트워크가 차단된 외부 망에서 별도의 dependency resolving 없이 애플리케이션 실행 가능해야 하기때문에. 해당 설정까지 추가한 후 mvn clean package 하여 외부망 서버에올려 테스트해봐야 합니다.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<includeSystemScope>true</includeSystemScope> <!-- system scope jar 포함 -->
<mainClass>net.herit.fcmgateway.Application</mainClass>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
아래는 위의 플러그인 설정에 includeSystemScope, mainClass 설정태그를 추가하지 않은 상태에서
패키징한 .jar 파일을 실행했을 때 나타나는 에러 로그입니다. 참고하세요 !
root@mig-dev-pushauth-92tn:/svc/app/fcm-gateway/bin#./run.sh start
learne
pcount=0
START fcm-gateway pid:2666307
root 2666307 2666300 99 09:20 pts/19 00:00:00/usr/lib/jvm/jdk-17.0.14/bin/java-classpath:/svc/app/fcm-gateway/config-Dlogging.config=file:/svc/app/fcm-gateway/config/logback-spring-dev.xml-Xms4096M -Xmx4096M -XX:+UseG1GC-
XX:ParallelGCThreads=1-XX:+DisableExplicitGC -Dsun.rmi.dgc.client.gclnterval=18000000-Dsun.rmi.dgc.server.gc/nterval=18000000 -
Xlog:gc*:file=/logs/gcLog/fcm-gateway/gc.log:time,level,tags:filecount=9,filesize=20m-XX:-HeapDumpOnOutOfMemoryError-
XX:HeapDumpPath=/logs/gcLog/fcm-gateway/java_pid2666300.hprof-DAppName=fcm-gateway -
Dspring.config.location=/svc/app/fcm-gateway/config/-Dspring.profiles.active=dev -Duser.timezone=Asia/Seoul-DAppName=fcm-
mo gateway -jar fcm-gateway.jar
root@mig-dev-pushauth-92tn/svc/app/fcm-gateway/bin#Exception in thread "main® java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorlmpl.invoke0(NativeMethod)
my
90
at java.base/jdk.internal.reflect.NativeMethodAccessorlmpl.invoke(NativeMethodAccessorlmpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorlmpl.invoke(DelegatingMethodAccessorlmpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:102)
6
at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:64)
감
at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:40)
Caused by:java.lang.NoClassDefFoundError:org/springframework/boot/SpringApplication
at net.herit.fcmgateway.Application.main(Application.java:14)
... 7 more
00
Caused by: java.lang.ClassNotFoundException: org springframework.boot.SpringApplication
wh
at java.base/java.netURLClassLoader.findClass(URLClassLoader.java:445)
>
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:592)
at org.springframework.boot.loader.net.protocol.jar.JarUrlClassLoader.loadClass(JarUrlClassLoader.java:107)
at org.springframework.bootloader.launch.LaunchedClassLoader.loadClass(LaunchedClassLoader.java:91)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
결과
보안망 환경에서는 외부 저장소 접근이 차단되므로, Maven 의존성을 모두 수동 .jar로 관리하는 방식이 필수적입니다.
scope=system + systemPath 설정과 함께 spring-boot-maven-plugin의 includeSystemScope 옵션을 활성화함으로써 빌드 및 실행의 완전한 독립성 확보가 가능해졌습니다.
해당 구성은 보안망 내 시스템 구축 시 재사용 가능한 템플릿으로 활용 가능하며, 차후 버전 변경이나 패치 적용 시에도 버전 관리와 추적이 용이할 수 있도록 패키징 과정을 문서로 공유해 보았습니다.
'IT > Backend | All' 카테고리의 다른 글
| LGU+ 홈IoT | FCM 게이트웨이 개발 프로젝트 (0) | 2025.09.24 |
|---|---|
| FeignClient에서 커넥션을 닫지 않으면 생기는 일 | netstat로 확인하는 법 (1) | 2025.07.30 |
| [IntelliJ] pom.xml의 라이브러리 목록 압축하기 | maven으로 라이브러리 다운로드받기 (0) | 2025.07.12 |
| 443, 8080, 9443? 관행적으로 쓰는 포트번호💡 | 개발자가 알아야 할 주요 포트번호 정리표 (0) | 2025.06.30 |
| GCP와 FCM | GCP 서비스계정 권한 부여로 Firebase 접근 승인하기 (2) | 2025.06.24 |