안녕하세요, 개발자 여러분! 오늘은 Java 프로젝트에서 흔히 발생할 수 있지만 간과하기 쉬운 문제에 대해 이야기해보려고 합니다. 바로 내부 클래스를 제거한 후 배포할 때 발생할 수 있는 이슈입니다. 이 문제를 겪어본 분들은 얼마나 골치 아픈 상황인지 잘 아실 거예요. 그럼 이 문제가 왜 발생하는지, 어떻게 해결할 수 있는지 자세히 알아보겠습니다.
여러분이 이런 상황을 겪어보셨을 수도 있습니다. 기존 코드에 있던 내부 클래스를 제거하고 새 버전을 배포했는데, 갑자기 애플리케이션이 제대로 동작하지 않습니다. 클래스를 찾을 수 없다는 오류나 클래스 로딩 관련 예외가 발생하죠. "분명히 코드에서 제거했는데 왜 이러지?"라는 생각이 들 수 있습니다.
이 문제의 근본 원인은 Java의 내부 클래스 컴파일 메커니즘과 클래스 로딩 방식에 있습니다. 조금 자세히 들여다볼까요?
내부 클래스의 특별한 컴파일: Java 컴파일러는 내부 클래스를 별도의 .class
파일로 컴파일합니다. 예를 들어, OuterClass.java
안에 InnerClass
가 있다면, 컴파일 후에는 OuterClass.class
와 OuterClass$InnerClass.class
두 개의 파일이 생성됩니다.
클래스 로더의 동작: JVM은 이 두 파일을 별도로 로드합니다. OuterClass.class
에는 내부 클래스에 대한 참조 정보가 들어있어요.
덮어쓰기 배포의 함정: 새 버전에서 내부 클래스를 제거하고 단순히 덮어쓰기 배포를 하면, OuterClass.class
는 업데이트되지만 OuterClass$InnerClass.class
는 그대로 남아있게 됩니다.
결과적 오류: 클래스 로더는 여전히 존재하는 OuterClass$InnerClass.class
파일을 로드하려고 시도하지만, 이는 더 이상 OuterClass.class
와 호환되지 않습니다. 그 결과 ClassNotFoundException
, NoClassDefFoundError
, 또는 IncompatibleClassChangeError
등의 오류가 발생하게 되는 거죠.
이 문제를 해결하기 위한 핵심은 '깨끗이 비우고 새로 시작하는 것'입니다. 구체적인 단계를 살펴볼까요?
먼저, 프로젝트를 완전히 새로 빌드해야 합니다.
mvn clean install
gradle clean build
이렇게 하면 이전 빌드의 모든 결과물이 제거되고 새로운 클래스 파일만 생성됩니다.
애플리케이션 서버의 배포 디렉토리(예: 톰캣의 webapps
폴더)에서 해당 애플리케이션의 모든 파일을 삭제합니다. 특히 WEB-INF/classes
폴더 내의 모든 클래스 파일을 꼼꼼히 제거해주세요.
클린 빌드로 생성된 새로운 WAR 파일이나 클래스 파일들을 서버의 적절한 위치에 배포합니다.
애플리케이션 서버의 캐시 디렉토리(예: 톰캣의 work
폴더)를 비웁니다. 이전에 컴파일된 JSP 파일이나 캐시된 클래스 정보를 모두 제거하는 거죠.
마지막으로 애플리케이션 서버를 완전히 중지하고 다시 시작합니다. 이렇게 하면 모든 변경사항이 확실히 적용됩니다.
이런 문제를 미리 예방하려면 어떻게 해야 할까요? 몇 가지 좋은 방법이 있습니다:
빌드 스크립트 개선: 항상 클린 빌드를 수행하도록 빌드 스크립트를 수정하세요.
CI/CD 파이프라인 수정: 지속적 통합/배포(CI/CD) 파이프라인에 클린 빌드 단계를 필수적으로 포함시키고, 배포 전 이전 버전 파일을 완전히 제거하는 단계를 추가하세요.
배포 스크립트 개선: 배포 스크립트에 이전 버전 파일 제거 로직과 서버 캐시 정리 단계를 포함시키세요.
코드 리뷰 강화: 내부 클래스를 제거하거나 수정할 때 특별한 주의를 기울이도록 코드 리뷰 가이드라인을 수정하세요.
개발자 교육: 팀 내 개발자들에게 이런 이슈에 대해 교육하고, 클린 빌드와 완전한 배포의 중요성을 강조하세요.
Java의 내부 클래스 관련 배포 이슈는 처음 접하면 당황스러울 수 있지만, 이제 여러분은 이 문제를 이해하고 해결할 수 있는 지식을 갖추셨습니다. 클린 빌드, 완전한 이전 버전 제거, 그리고 서버 캐시 정리가 핵심임을 기억하세요. 이러한 방법을 일상적인 개발 및 배포 프로세스에 통합한다면, 유사한 문제의 재발을 방지하고 더욱 안정적인 애플리케이션 운영이 가능할 거예요.
여러분의 개발 생활에 이 글이 도움이 되었기를 바랍니다. 궁금한 점이나 추가적인 경험이 있다면 댓글로 공유해 주세요. 함께 성장하는 개발자 커뮤니티를 만들어 갑시다!
해피 코딩하세요! 😊👨💻👩💻