Programming

GraalVM Native 이미지로 빌드 에러 발생 원인

ipxy 2025. 3. 24. 14:25
728x90

Spring Boot 애플리케이션을 GraalVM Native 이미지로 빌드한 후 실행할 때, 파일 생성(file creation) 시 에러가 발생하는 것은 꽤 일반적인 문제입니다. Native 이미지 환경에서는 리플렉션, 파일 시스템 접근, 동적 프록시, 리소스 처리 등이 제한되거나 명시적으로 등록되어야 합니다.

💥 에러 발생 원인

GraalVM Native 이미지 빌드는 애플리케이션의 전체 동작을 컴파일 타임에 분석해서 최적화된 바이너리를 만듭니다. 이 과정에서 동적으로 생성되거나 접근되는 파일/리소스가 제대로 등록되지 않으면 런타임에서 오류가 발생합니다.


✅ 주요 원인과 해결 방법

1. ❌ 파일 시스템 쓰기 경로 제한

Native 이미지 실행 환경에서는 파일 시스템 쓰기에 제약이 있을 수 있습니다.

🔧 해결:

  • 실제 파일 쓰기 위치를 확인하세요. /tmp, /home, ./ (현재 디렉토리) 외의 경로는 쓰기가 막혀있을 수 있습니다.
  • 예시:
// 안전한 경로로 저장
File file = new File("/tmp/my-output.txt");

2. ❌ 리소스 등록 누락 (Resource Configuration)

파일을 만들기 전에 리소스를 읽거나 특정 파일 존재 여부를 체크하는 로직이 있다면, 그 리소스가 native 이미지에 포함되지 않아서 에러가 날 수 있습니다.

🔧 해결:

  • resource-config.json에 리소스를 등록하거나, @ResourceHint 사용
{
  "resources": [
    {
      "pattern": "config/.*\\.txt"
    }
  ]
}
@NativeHint(resources = @ResourceHint(patterns = "config/.*\\.txt"))

3. ❌ 리플렉션 사용

파일 이름을 기반으로 클래스 로딩이나 동적 처리를 할 때, 리플렉션이 개입되면 별도로 등록해야 합니다.

🔧 해결:

  • reflect-config.json 사용 또는 @ReflectionHint 사용

4. ❌ GraalVM 보안/퍼미션 문제

파일 쓰기를 시도하는데 OS나 런타임에서 해당 경로에 대한 권한이 없을 수 있습니다.

🔧 해결:

  • 실행 권한 확인:
chmod +x myapp
./myapp
  • Docker 환경이라면 --volume, --tmpfs 등을 통해 쓰기 권한 부여

5. ❌ GraalVM 파일 관련 예외 예시

java.io.IOException: Operation not permitted
java.nio.file.AccessDeniedException: /path/to/file
java.lang.UnsupportedOperationException: No such file system provider

이런 에러가 보이면 파일 시스템 접근 자체가 막힌 경우입니다.


🛠️ 빌드 시 팁

Spring Native (또는 Spring Boot 3+ with AOT)에서 Native 이미지로 빌드할 때는 다음 플래그들을 추가해보세요:

./gradlew nativeCompile \
  -PnativeBuildArgs=--trace-class-initialization=YourClass \
  -Dspring.aot.enabled=true

또는 Docker 기반 빌드:

./gradlew bootBuildImage --imageName=my-native-app \
  -PBP_NATIVE_IMAGE=true

 

728x90