[TIPS] 이클립스 JSP 빨간줄 에러 완벽 해결 가이드 (Server Runtime 등록부터 Maven/Gradle 의존성 & Tomcat 10 Jakarta 전환까지)

이클립스 JSP 빨간줄 에러 완벽 해결 가이드
TIPS & TROUBLESHOOTING

이클립스 JSP 빨간줄 에러 완벽 해결 가이드

Server Runtime 등록부터 Maven/Gradle 의존성 & Tomcat 10 Jakarta 전환까지

💡 핵심 요약: 이클립스(Eclipse)에서 JSP 파일 최상단이나 스크립틀릿 태그에 발생하는 빨간색 엑스표(The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path) 에러는 단순 문법 오류가 아니라, JSP를 서블릿 자바 코드로 컴파일할 서블릿 컨테이너(Servlet/JSP API) 바이너리가 프로젝트 클래스패스에 없기 때문입니다. Validation을 체크 해제하는 임시방편 대신, 전통적 Dynamic Web Project의 Server Runtime 등록부터 현대 표준인 Maven/Gradle 의존성 선언(provided / compileOnly), 그리고 Tomcat 10+ 환경의 javax ➔ jakarta 패키지 전환 및 5단계 응급 체크리스트까지 완벽하게 정리합니다.

1. 2019년 팁의 배경과 에러의 근본 원인

2019년 당시 웹 검색이나 블로그 팁을 보면 다음과 같은 조언이 자주 등장했습니다:

“Validation을 해제해도 빨간불이 안 없어지면 다음처럼 해보자: Project Explorer -> Properties -> Java Build Path -> Libraries -> Add Library -> Server Runtime -> Apache Tomcat 선택”

이 조언이 왜 나왔고, 왜 “Validation 해제”는 올바른 해결책이 아닐까요?

1) JSP 컴파일 라이프사이클의 이해

JSP(JavaServer Pages)는 텍스트 파일처럼 보이지만, 서블릿 컨테이너(Apache Tomcat, Jetty, WildFly 등) 내부에서 브라우저 요청 시점에 자바 클래스로 변환(_jsp.java)된 뒤 바이트코드(.class)로 컴파일됩니다.

이 변환 과정에서 모든 JSP는 서블릿 규격에 따라 javax.servlet.http.HttpServlet(또는 최신 Tomcat 10+의 경우 jakarta.servlet.http.HttpServlet)을 상속받는 클래스로 생성됩니다.

DIAGRAM: JSP COMPILE LIFECYCLE
[Browser Request]
       │
       ▼
[ index.jsp ]
       │
       ▼ (JSP Engine: Jasper)
[ index_jsp.java ]  ── extends HttpServlet
       │
       ▼ (Java Compiler)
[ index_jsp.class ]

2) 왜 Validation 해제는 근본적인 해결책이 아닌가?

이클립스의 Preferences -> Validation에서 JSP Validator를 끄면 일시적으로 편집기 상의 빨간 밑줄은 사라질 수 있습니다. 하지만:

  • 문법 오류, 태그 누락, 스크립틀릿 변수 타입 불일치 등 실제 자바/JSP 문법 오류까지 검증하지 않게 됨
  • 클래스패스 상에 서블릿 API(servlet-api.jar, jsp-api.jar)가 여전히 없으므로, 프로젝트를 WAR로 묶어 로컬 서버에서 실행하거나 빌드할 때 컴파일 에러(ClassNotFoundException / NoClassDefFoundError)가 런타임에 폭발하게 됨
  • 즉, 질병을 치료하지 않고 온도계의 눈금을 지워버리는 위험한 임시방편입니다.

따라서 해결의 핵심은 프로젝트의 빌드 패스(Build Path)에 Servlet/JSP API 클래스를 정확히 제공해 주는 것입니다.

2. [전통적 방식] Dynamic Web Project - Server Runtime & Targeted Runtimes 정석 등록법

이클립스 고유의 Dynamic Web Project(동적 웹 프로젝트) 형태로 생성된 레거시 웹 애플리케이션에서는 이클립스가 관리하는 Tomcat 서버 런타임을 빌드 패스에 연결해 주어야 합니다.

Step 1. Eclipse Servers 뷰에 톰캣 런타임 환경 등록 확인

  1. Eclipse 상단 메뉴 Window ➔ Preferences 이동.
  2. 좌측 트리에서 Server ➔ Runtime Environments 선택.
  3. 로컬 PC에 설치된 톰캣(Apache Tomcat v9.0, v10.1 등)이 목록에 등록되어 있는지 확인합니다.
  4. 목록이 비어 있다면 Add... 클릭 ➔ 해당 버전의 Tomcat 선택 ➔ 톰캣 설치 경로(Tomcat installation directory) 지정 후 Finish.

Step 2. Targeted Runtimes 설정 (가장 추천하는 정석)

개별 라이브러리를 하나씩 추가하는 것보다 프로젝트 패싯(Facet)에 톰캣을 연결하는 것이 훨씬 안전합니다.

  1. Project Explorer에서 프로젝트 우클릭 ➔ Properties (단축키: Alt + Enter).
  2. 좌측 메뉴에서 Targeted Runtimes 선택.
  3. 목록에서 사용 중인 서버 런타임(예: Apache Tomcat v9.0 또는 Apache Tomcat v10.1) 앞의 체크박스를 활성화.
  4. Apply and Close 클릭.
✅ 동작 원리: 이 설정을 적용하면 이클립스가 자동으로 해당 톰캣의 lib 폴더 내에 있는 servlet-api.jar, jsp-api.jar, el-api.jar를 프로젝트 라이브러리로 자동 마운트합니다.

Step 3. Java Build Path에 Server Runtime 직접 추가 (2019년 원문 방식)

만약 Targeted Runtimes 탭이 보이지 않거나 체크 후에도 잡히지 않는다면 원문에서 소개한 클래스패스 직접 등록을 진행합니다:

  1. 프로젝트 우클릭 ➔ Properties ➔ Java Build Path 선택.
  2. 상단 탭 중 Libraries 탭 클릭.
    (Java 9+ 모듈 시스템 사용 시 Classpath 항목을 먼저 클릭한 뒤 활성화)
  3. 우측 버튼 중 Add Library... 클릭.
  4. 라이브러리 목록 창에서 Server Runtime 선택 후 Next >.
  5. 등록된 서버 목록에서 Apache Tomcat v9.0 (또는 해당 버전) 선택 후 Finish.
  6. Apply and Close를 눌러 저장.

3. [현대적 표준] 빌드 도구 기반 해결 (Maven & Gradle)

현대 웹 애플리케이션은 이클립스 전용 프로젝트 설정에 의존하지 않고, Maven이나 Gradle 같은 표준 빌드 도구를 사용하여 CI/CD 파이프라인과 로컬 IDE 모두에서 동일하게 빌드되도록 구성합니다.

핵심은 서블릿 컨테이너(Tomcat)가 런타임에 이미 API를 제공하므로, 패키징되는 WAR/JAR 파일에는 라이브러리가 포함되지 않도록 범위를 지정하는 것입니다.

  • Maven: <scope>provided</scope>
  • Gradle: compileOnly (및 테스트용 testCompileOnly)

1) Apache Tomcat 9 이하 (Java EE - javax.servlet)

MAVEN (pom.xml)
<dependencies>
    <!-- Servlet API (Tomcat 9 이하) -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>

    <!-- JSP API (Tomcat 9 이하) -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.3</version>
        <scope>provided</scope>
    </dependency>

    <!-- JSTL 1.2 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
</dependencies>
GRADLE (build.gradle)
dependencies {
    // 서블릿 및 JSP API: 컴파일 시에만 사용하고 WAR 패키징에는 제외
    compileOnly 'javax.servlet:javax.servlet-api:4.0.1'
    compileOnly 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.3'

    // JSTL은 런타임에도 필요하므로 implementation 지정
    implementation 'javax.servlet:jstl:1.2'
}

2) Apache Tomcat 10 / 11 이상 (Jakarta EE - jakarta.servlet)

Tomcat 10부터는 패키지 네임스페이스가 완전히 변경되었으므로 Maven/Gradle 좌표 역시 jakarta.* 그룹으로 변경해야 합니다.

MAVEN (pom.xml)
<dependencies>
    <!-- Servlet API 5.0/6.0 (Tomcat 10 / 11) -->
    <dependency>
        <groupId>jakarta.servlet</groupId>
        <artifactId>jakarta.servlet-api</artifactId>
        <version>6.0.0</version>
        <scope>provided</scope>
    </dependency>

    <!-- JSP API 3.1 -->
    <dependency>
        <groupId>jakarta.servlet.jsp</groupId>
        <artifactId>jakarta.servlet.jsp-api</artifactId>
        <version>3.1.1</version>
        <scope>provided</scope>
    </dependency>

    <!-- Jakarta JSTL (API + GlassFish 구현체) -->
    <dependency>
        <groupId>jakarta.servlet.jsp.jstl</groupId>
        <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
        <version>3.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.web</groupId>
        <artifactId>jakarta.servlet.jsp.jstl</artifactId>
        <version>3.0.1</version>
    </dependency>
</dependencies>
GRADLE (build.gradle)
dependencies {
    // Jakarta Servlet & JSP API
    compileOnly 'jakarta.servlet:jakarta.servlet-api:6.0.0'
    compileOnly 'jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.1.1'

    // Jakarta JSTL
    implementation 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.0'
    runtimeOnly 'org.glassfish.web:jakarta.servlet.jsp.jstl:3.0.1'
}
📌 중요: Maven/Gradle 프로젝트 갱신

의존성을 수정한 후 이클립스가 클래스패스를 다시 계산하도록 반드시 동기화 단축키를 눌러야 합니다:

  • Maven: 프로젝트 선택 ➔ Alt + F5 (또는 우클릭 ➔ Maven ➔ Update Project...) ➔ Force Update of Snapshots/Releases 체크 후 OK.
  • Gradle: 프로젝트 우클릭 ➔ Gradle ➔ Refresh Gradle Project.

4. [최신 환경 필수] Tomcat 10+ (Jakarta EE) 네임스페이스 전환 이슈

최신 Java 17, Java 21 LTS 버전에 맞춰 Apache Tomcat 10.1 또는 11.0을 도입하는 과정에서 JSP 에러가 빈번하게 재발합니다. 이는 단순 빌드 패스 누락이 아닌 네임스페이스 파편화 문제입니다.

1) Java EE ➔ Jakarta EE 패키지 전환 매핑

오라클에서 이클립스 재단으로 Java EE 상표권이 이관되면서 javax.* 상표명을 사용할 수 없게 되어 패키지가 일제히 변경되었습니다:

구분 Tomcat 9 이하 (Java EE 8 이하) Tomcat 10 / 11 (Jakarta EE 9 / 10 / 11)
Servlet 인터페이스 javax.servlet.Servlet jakarta.servlet.Servlet
HttpServlet 상속 javax.servlet.http.HttpServlet jakarta.servlet.http.HttpServlet
Filter 인터페이스 javax.servlet.Filter jakarta.servlet.Filter
JSP 태그 라이브러리 URI http://java.sun.com/jsp/jstl/core jakarta.tags.core

2) JSP 페이지 지시자 및 JSTL 태그 선언 트러블슈팅

Tomcat 10+ 환경에서 기존의 Sun/Oracle JSTL URI를 그대로 사용하면 JSP 파서가 태그를 인식하지 못하고 빨간줄을 띄우거나 Unable to find taglib for uri 에러를 발생시킵니다.

❌ Tomcat 10+에서 오류를 발생시키는 구형 선언
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- 구형 JSTL URI: Tomcat 10+에서는 500 에러 및 구문 분석 오류 발생 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
✅ Tomcat 10+ (Jakarta EE) 올바른 선언
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- 최신 Jakarta JSTL 3.0+ 정식 규격 URI -->
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<%@ taglib prefix="fmt" uri="jakarta.tags.fmt" %>
<%@ taglib prefix="fn" uri="jakarta.tags.functions" %>

5. 여전히 빨간불이 남았을 때 5단계 응급 체크리스트

모든 설정을 완료했는데도 이클립스 에디터에 여전히 빨간 X 표시가 남아있다면 이클립스 내부 캐시 및 메타데이터 꼬임 현상입니다. 다음 순서대로 5단계 조치를 취합니다.

DIAGRAM: 5-STEP EMERGENCY TROUBLESHOOTING FLOW
[Step 1] Project Clean
       │ (해결 안 됨)
       ▼
[Step 2] Project Facets 자바/동적 모듈 버전 일치 검증
       │ (해결 안 됨)
       ▼
[Step 3] .settings / org.eclipse.wst.common.project.facet.core.xml 직접 확인
       │ (해결 안 됨)
       ▼
[Step 4] eclipse -clean 파라미터로 캐시 강제 초기화 재시작
       │ (해결 안 됨)
       ▼
[Step 5] .metadata 폴더 재생성 또는 현대적 IDE (IntelliJ IDEA) 전환

1단계: Project Clean

이클립스는 컴파일된 마커(Error Marker)를 내부 인덱스에 캐싱합니다.

  • 상단 메뉴 Project ➔ Clean... 클릭.
  • Clean all projects 또는 문제가 발생한 프로젝트를 선택한 후 Clean 실행.
  • 백그라운드 컴파일(Building Workspace)이 100% 완료될 때까지 대기합니다.

2단계: Project Facets 버전 일치 점검

프로젝트의 Java 컴파일러 버전과 Dynamic Web Module 버전이 톰캣 버전과 호환되지 않으면 라이브러리가 존재해도 인식에 실패합니다.

  • 프로젝트 우클릭 ➔ Properties ➔ Project Facets.
  • Java: 설치된 JDK 버전과 맞는지 확인 (예: 17 또는 21).
  • Dynamic Web Module:
    • Tomcat 9: 4.0
    • Tomcat 10.0: 5.0
    • Tomcat 10.1: 6.0
  • 우측 Runtimes 탭에서 대상 톰캣이 체크되어 있는지 재확인.

3단계: .settings 설정 XML 직접 점검

간혹 UI 상에서 버전 변경 시 충돌(Cannot change version of project facet Dynamic Web Module to ...)이 나며 적용되지 않을 때가 있습니다.

  • 프로젝트 폴더 내 .settings/org.eclipse.wst.common.project.facet.core.xml 파일을 텍스트 에디터로 엽니다.
  • 다음과 같이 버전과 런타임 이름을 직접 일치시킵니다:
XML (.settings/org.eclipse.wst.common.project.facet.core.xml)
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
  <runtime name="Apache Tomcat v10.1"/>
  <secondary-runtime name="Apache Tomcat v10.1"/>
  <installed facet="java" version="17"/>
  <installed facet="jst.web" version="6.0"/>
</faceted-project>

4단계: eclipse -clean 파라미터로 재시작

이클립스의 OSGi 플러그인 캐시나 클래스로더가 이전 바이너리를 물고 있는 경우입니다.

  • 이클립스를 종료합니다.
  • 윈도우 터미널(cmd 또는 PowerShell)을 열고 이클립스 설치 경로로 이동합니다.
  • 다음 명령어로 실행합니다:
eclipse.exe -clean

*(또는 eclipse.ini 파일 최상단에 -clean 옵션을 추가한 뒤 1회 실행 후 지워주셔도 됩니다.)*

5단계: 최신 개발 환경으로의 점진적 전환

2026년 현재 상용 엔터프라이즈 환경에서는 이클립스의 .metadata 손상 빈도와 수동 설정 오버헤드를 줄이기 위해 다음 표준 환경으로 전환하는 추세입니다:

  • IntelliJ IDEA Ultimate: pom.xml이나 build.gradle의 provided/compileOnly 스코프를 인식하여 별도의 Server Runtime 설정 없이 완벽한 스마트 자동완성과 실시간 인덱싱을 지원합니다.
  • VS Code + Extension Pack for Java: 가벼운 환경에서 작업할 경우 Red Hat의 Language Support for Java와 톰캣 확장으로 안정적인 개발이 가능합니다.

6. 개발 환경별 설정 매트릭스 비교

프로젝트 유형 톰캣 버전 서블릿 규격 의존성 관리 방식 핵심 설정 파일 및 경로
Dynamic Web Project (전통) Tomcat 8.5 / 9.0 Java EE (javax.*) Eclipse Server Runtime Properties ➔ Targeted Runtimes ➔ 톰캣 선택
Dynamic Web Project (최신) Tomcat 10.1 / 11 Jakarta EE (jakarta.*) Eclipse Server Runtime (Facet 6.0) Targeted Runtimes + JSTL jakarta.tags.core
Maven WebApp (안정) Tomcat 9.0 Java EE (javax.*) pom.xml (provided) javax.servlet:javax.servlet-api:4.0.1
Maven WebApp (표준) Tomcat 10.1 / 11 Jakarta EE (jakarta.*) pom.xml (provided) jakarta.servlet:jakarta.servlet-api:6.0.0
Gradle Web (모던) Tomcat 10.1 / 11 Jakarta EE (jakarta.*) build.gradle (compileOnly) jakarta.servlet:jakarta.servlet-api:6.0.0

마치며: 유지보수 가능한 설정을 향해

2019년의 “Validation 해제”나 “수동 Add Library”는 당장 개발자의 눈앞에 보이는 빨간 에러를 지우는 데는 유용했지만, 팀 협업 환경과 CI/CD 빌드 시스템에서는 빈번한 빌드 장애를 유발하는 주원인이었습니다.

오늘 정리한 내용을 바탕으로:

  1. Dynamic Web Project라면 반드시 Targeted Runtimes를 통해 톰캣 라이브러리를 동기화하고,
  2. 신규 프로젝트라면 Maven/Gradle의 provided / compileOnly 표준 스코프를 사용하여 환경 종속성을 제거하며,
  3. Tomcat 10 이상 환경에서는 jakarta.servlet과 jakarta.tags.core 규격을 철저히 준수하여 불필요한 트러블슈팅 시간을 획기적으로 줄여보시기 바랍니다.

댓글 쓰기

다음 이전