Java Lambda 함수의 "ClassNotFoundException" 오류를 해결하려면 어떻게 해야 합니까?

최종 업데이트 날짜: 2021년 1월 7일

Java로 작성된 AWS Lambda 함수를 실행하면 "ClassNotFoundException" 또는 "NoSuchMethodError" 오류가 발생합니다. 이러한 문제를 해결하려면 어떻게 해야 합니까?

간략한 설명

Java 런타임에서 정규화된 이름을 기준으로 클래스를 로드할 때 클래스를 찾지 못하고 “ClassNotFoundException” 오류가 발생합니다.

참고: 클래스의 정규화된 이름에는 해당 배포 패키지 및 클래스 이름이 포함됩니다.

참조된 종속성 버전이 패키지 버전과 다를 경우 런타임에서 "NoSuchMethodError" 오류가 발생합니다.

Java 함수 배포 패키지 구조에 대한 자세한 내용은 Java 함수에 대한 ZIP 배포 패키지 생성을 참조하세요.

해결 방법

참고: AWS CLI(AWS 명령줄 인터페이스) 명령을 실행할 때 오류가 발생할 경우 AWS CLI의 최신 버전을 사용하고 있는지 확인하세요.

Java Lambda 함수 배포 패키지의 구조 및 내용을 검토하여 오류의 원인을 확인합니다. zipinfo를 사용하여 빌드 시스템의 출력 Java 파일을 보는 것이 좋습니다. 또는 다음 중 하나를 수행하여 패키지를 다운로드할 수 있습니다.

  • AWS CLI에서 Lambda get-function 명령을 실행합니다. 명령 출력에는 파일을 다운로드하는 데 사용할 수 있는 미리 서명된 URL이 표시됩니다. 자세한 내용은 Lambda 함수 검색을 참조하세요.
    참고: 이 옵션을 사용하는 경우 출력에서 함수 핸들러의 값에 대한 구성도 확인하세요. 다음 단계에 이 값이 필요합니다.
  • Lambda 콘솔의 함수(Functions) 페이지에서 함수를 선택하고 다음을 수행합니다.
    작업(Actions)을 선택합니다.
    함수 내보내기(Export function)를 선택합니다.
    함수 내보내기(Export your function) 대화 상자에서 배포 패키지 다운로드(Download deployment package)를 선택합니다.

다음 문제 중 하나를 찾습니다. 문제를 식별하고 해결한 후에는 Lambda 함수를 수동으로 번들링하고 업로드합니다. 그런 다음 여전히 오류가 발생하는지 확인합니다.

함수 핸들러 메서드 이름 확인

다음 중 하나를 수행하여 Lambda 함수 핸들러의 이름을 확인합니다.

자세한 내용은 Java의 AWS Lambda 함수 핸들러를 참조하세요.

배포 패키지 구조 보기

다음 명령을 실행하여 Lambda 함수 배포 패키지의 파일 구조를 확인합니다.

참고: 다음 명령은 Linux/Unix/macOS 시스템에 대해서만 유효합니다. my-deployment-package.zip은 배포 패키지의 파일 이름으로 바꿉니다.

$ zipinfo my-deployment-package.zip

CI/CD 파이프라인 사용 시 문제 확인

지속적 통합 및 지속적 전달(CI/CD) 파이프라인을 사용하여 함수를 패키징하고 배포하는 경우 다음을 확인합니다.

  • 함수를 패키징할 때 필요한 모든 종속성이 번들링되었습니다.
  • 참조된 모든 종속성 버전이 정확합니다.
  • 모든 필수 Amazon S3(Amazon Simple Storage Service) 버킷 URL이 존재하며 파일의 최신 버전을 가리킵니다.
    참고: Amazon S3 버킷 소스를 사용하고 버킷 버전 관리가 활성화된 경우에만 Amazon S3 버킷 URL이 필요합니다.
  • 코드 변경 사항은 핸들러 구성 변경을 배포하기 전에 배포되었습니다.
    참고: Lambda에는 하나의 원자성 변경으로 코드 및 구성을 업데이트하는 메커니즘이 없습니다.

클래스 파일 문제 확인

"ClassNotFoundException" 오류에 이름이 명시된 클래스에 대해 다음을 확인합니다.

  • 배포 패키지에 포함되어 있습니다. 클래스를 찾을 수 없는 경우 배포 패키지를 생성할 때 번들링되지 않았을 수 있습니다.
  • 번들 클래스 이름은 함수의 핸들러 값과 동일합니다. 예를 들어 함수 핸들러 값이 "com.amazonaws.lambda.demo.LambdaFunctionHandler"인 경우 Lambda는 함수 디렉터리 "/com/amazonaws/demo/"에 "LambdaFunctionHandler.class"라는 클래스 이름을 기대합니다. 자세한 내용은 Java의 AWS Lambda 함수 핸들러를 참조하세요.
  • 이는 /lib 또는 루트 디렉터리에 있습니다.
  • 위치는 Java CLASSPATH 환경 변수에 지정됩니다.
  • Lambda 계층으로 참조되는 경우 해당 콘텐츠가 java/lib 이외의 디렉터리로 추출되지 않았습니다.
  • 함수와 함께 패키징된 클래스와 동일한 버전입니다. 그렇지 않은 경우 로컬 시스템에 패키징된 버전과 다른 버전이 있는지 확인합니다.

Java 함수 패키징에 대한 자세한 내용은 Java의 AWS Lambda 배포 패키지를 참조하세요.

JAR 파일 문제 확인

함수가 로컬 시스템에서 또는 AWS SAM(AWS Serverless Application Model) 애플리케이션에서 예상대로 실행되는지 확인합니다. 함수가 Lambda에서 호출할 때만 실패할 경우 참조된 종속성(JAR 파일)에 문제가 있을 수 있습니다.

팁: Eclipse IDE(통합 개발 환경)를 사용하여 Java Lambda 함수를 빌드하는 것이 좋습니다. Eclipse에서 사용할 수 있는 플러그인을 활용하여 프로젝트를 생성하면 적절한 빌드에 맞게 프로젝트가 자동으로 구성됩니다. 자세한 내용은 AWS Toolkit for Eclipse로 Lambda 사용을 참조하십시오.

로컬 디렉터리에 있고 Java CLASSPATH 환경 변수에 지정된 JAR 파일에 대해 다음을 확인합니다.

  • 파일은 함수의 배포 패키지에 포함되어 있습니다. 참조된 JAR 파일을 찾을 수 없는 경우 배포 패키지를 생성할 때 번들링되지 않았을 수 있습니다.
  • 파일 버전은 배포 패키지의 파일과 동일합니다.

파일이 없거나 버전이 잘못된 경우 모든 종속성(JAR 파일)을 /lib 또는 루트 디렉터리에 복사합니다. 올바른 버전을 참조하는지 확인하세요. 그런 다음 압축된 콘텐츠를 업로드합니다.

참고: Apache Maven 또는 Gradle과 같은 빌드 도구를 사용하는 경우 배포 아티팩트를 빌드할 때 필요한 플러그인(예: Apache Maven Shade Plugin)을 사용해야 합니다.

Java 함수 패키징에 대한 자세한 내용은 Java의 AWS Lambda 배포 패키지를 참조하세요.

권한 문제 확인

Lambda는 zip 패키지 파일에 전역 읽기 권한이 있어야 합니다. 자세한 내용은 배포 패키지를 업로드할 때 Lambda "permission denied" 또는 "unable to import module" 오류를 해결하려면 어떻게 해야 합니까?를 참조하세요.