모눈종이에 사각사각

JSP 페이지의 실행 순서와 컴파일 과정 이해하기 : JSP 오류 해결 본문

활동기록

JSP 페이지의 실행 순서와 컴파일 과정 이해하기 : JSP 오류 해결

모눈종이씨 2024. 12. 22. 12:32

갑자기 JSP 페이지를 다뤄야 하는 상황..!

평소 JSP를 사용하지 않기 때문에 거의 모른다고 봐도 무방합니다. 그렇기 때문에 오류가 발생했을 때 해결하기 힘들더군요.

마주한 오류는 대략 다음과 같았습니다.

UT005023: Exception handling request to {경로}.jsp:java.lang.NullPointerException at 
~~ {jsp이름}_jsp.java


스택 트레이스에서 내뱉은 라인을 봐도 해당 코드가 아니고, 도대체 왜 오류가 나는가...

이를 JSP의 컴파일 순서와 함께 다뤄본다면 좋을 것 같아 글로 남겨보기로 했습니다.

JSP란 무엇일까요?

다들 아시겠지만, 일단 정의부터 한 번 보시죠.

JSP(JavaServer Pages)는 Java 기반의 웹 기술로, 정적 HTML과 동적 Java 코드를 결합하여 동적으로 웹 콘텐츠를 생성할 수 있는 서버 측 스크립팅 언어입니다. JSP는 서블릿(Servlet) 기술을 확장한 형태로, HTML 코드에 Java 코드를 삽입하여 동적인 웹 페이지를 쉽게 개발할 수 있도록 설계되었습니다.

JSP 페이지의 Life Cycle

JSP 페이지는 다음과 같은 라이프 사이클을 가지고 있습니다.

 

1. JSP 페이지 번역 & 컴파일 단계
2. 로딩 및 초기화 단계
3. 요청 처리 단계
4. 소멸 단계


이번 글에서는 JSP 페이지의 라이프 사이클을 따라서 어떻게 번역되고 실행되는지를 알아보려고 합니다.

JSP 컴파일 & 로딩 및 초기화

1. 클라이언트(브라우저)가 JSP 페이지를 요청한다.
2. 웹서버는 JSP 파일을 Java 서블릿 코드로 변환한다.
   - JSP의 HTML은 서블릿의 출력 메서드(`out.println`)를 통해 HTML 응답으로 변환된다.
   - JSP의 Java코드(`<% %>`, `<%= %>`)는 서블릿의 service 메서드에 포함된다.
3. 서블릿 컴파일
   - 변환된 Java 서블릿은 `.class` 파일로 컴파일된다.
   - 이후 `.class` 파일은 JVM에서 실행가능한 바이트코드로 변환된다.
   - 참고로 JSP에서 Javascript 코드는 서버에서 처리되지 않으며, 클라이언트로 전달된 후 브라우저가 해석하고 실행한다.
4. 서블릿 로드
   - 컴파일된 서블릿은 서버 메모리에 로드되고 초기화된다.
   - 이 과정은 서블릿의 `init()` 메서드에 의해 수행된다.

여기서 정리 한 번 해보면
- JSP 변환 : JSP ➡️ 서블릿 ➡️ 바이트코드 ➡️ 실행
이 순서로 된다는 것을 알 수 있습니다.

컴파일된 jsp의 java파일, class 파일 위치

여기서 의문의 드는 점 한가지, 컴파일 된 class 파일은 어디에 위치하게 될까요?
jsp 파일이 서블릿으로 변환될 때 변환된 java 파일과 컴파일된 클래스 파일은 서버의 work 디렉토리 또는 서버 설정에 따라 지정된 임시 디렉토리에 저장됩니다. 이 경로는 웹 서버 (Tomcat 등)의 설정에 따라 달라질 수 있습니다.
그리고 파일의 이름은 보통 abc.jsp -> abc_jsp.java -> abc_jsp.class 이렇게 지어집니다. (그래서 에러 스택 트레이스에 ~~_jsp.class 이런 문구들이 보였던 것입니다.)

JSP 실행 순서

JSP가 서블릿으로 변환되고 컴파일된 후, 클라이언트 요청이 들어올 때 다음의 단계를 거칩니다.

1. 클라이언트 요청 
   - 클라이언트(브라우저)가 URL을 통해 HTTP 요청(GET/POST)을 보낸다.
2. 요청 전달 및 매핑
   - 웹 서버(Tomcat 등)가 요청된 URL을 확인하고 해당 JSP 파일에 매핑된 서블릿을 호출한다.
3. 서블릿 실행
   - 서블릿 컨테이너는 서블릿의 service 메서드를 호출한다.
   - 요청 메서드(GET, POST)에 따라 `doGet` 또는 `doPost`메서드가 실행된다.
4. 동적 HTML 생성
   - 서블릿은 요청 처리 후 동적 HTML을 생성한다.
5. 응답 반환
   - 생성된 HTML이 HTTP 응답으로 클라이언트(브라우저)에 반환한다.
   - 이때, JSP 파일에 포함된 Javascript도 클라이언트로 전송한다.
   - 브라우저는 HTML을 렌더링하여 사용자 화면에 표시한다.
   - 렌더링하면서 Javascript 코드를 실행한다.


JSP 파일을 수정하면 재기동이 필요할까?

java 소스를 고치면 재기동을 해야 변경사항이 적용됩니다.
그렇다면 JSP 파일을 수정할 경우에는 어떠할까요?
정답은 재기동 하지 않아도 된다 입니다.

그 이유는 다음과 같습니다.

컴파일은 최초 요청 시에만 발생합니다. 그리고 JSP가 수정되면 서버가 변경 사항을 감지하여 서블릿을 다시 생성하기 때문에 재기동하지 않아도 됩니다. JSP 파일을 수정하면 서버는 해당 JSP 파일의 변환된 서블릿과 컴파일된 클래스 파일을 자동으로 삭제 및 재생성합니다. 이때 서버는 JSP 파일의 최종 수정 시간을 감지하여 필요할경우 재컴파일합니다.

그러나,, 언제나 이대로 작동하지는 않죠?!

재기동 하지 않아도 되지만 서버 설정 및 캐싱 문제로 변경사항이 적용되지 않는 경우가 종종 있습니다.
따라서 JSP 페이지를 변경했는데 계속 적용이 되지 않는다면 바로 재기동 해보시길 바랍니다.

오류 발생 원인 파악하기

그렇다면 다시 처음으로 돌아가서 오류 로그를 파악해 봅시다.

UT005023: Exception handling request to {경로}.jsp:java.lang.NullPointerException at 
~~ {jsp이름}_jsp.java

 

 

위에서 서술한 JSP 페이지의 컴파일 및 실행 과정으로부터 추측해 보았을 때 
JSP 파일이 서블릿으로 변환된 후 컴파일 된 Java 클래스 파일에서 발생한 예외입니다.

 

에러 스택 트레이스에서 나온 라인 번호의 JSP 페이지에 가도 해당 부분에서 발생한 에러가 아니었던 이유는, 컴파일 된 파일에서 내뱉은 에러이기 때문입니다. JSP 코드가 서블릿으로 변환된 후의 라인 번호를 출력하므로, 실제 JSP 파일의 라인을 찾아 보아도 소용이 없을 것입니다.

따라서 위의 NullPointerException 에러는 Java 코드 부분에 객체가 초기화 되지 않았거나, null 인 상태에서 메서드 호출 또는 필드 접근을 시도했을 가능성이 있다는 뜻입니다.
실제로 컨트롤러에서 JSP로 전달된 데이터가 null인 상태로 전달되었고, 해당 필드를 접근하니 발생한 에러였습니다.

 

한 단계 더 나아가 생각해봤을 때 JSP 페이지가 실행은 되지만, 화면에서 에러가 발생한다?

F12 개발자도구로 봤을 때 뭔가 이상하다?

그러면 Javascript나 HTML 소스에서 문제가 발생하고 있을 가능성이 높습니다.

 

 

참고
[JSP Life Cycle | Learn JSP Basics - Life Cycle of JSP]

Comments