이클립스 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 해제”는 올바른 해결책이 아닐까요?
1) JSP 컴파일 라이프사이클의 이해
JSP(JavaServer Pages)는 텍스트 파일처럼 보이지만, 서블릿 컨테이너(Apache Tomcat, Jetty, WildFly 등) 내부에서 브라우저 요청 시점에 자바 클래스로 변환(_jsp.java)된 뒤 바이트코드(.class)로 컴파일됩니다.
이 변환 과정에서 모든 JSP는 서블릿 규격에 따라 javax.servlet.http.HttpServlet(또는 최신 Tomcat 10+의 경우 jakarta.servlet.http.HttpServlet)을 상속받는 클래스로 생성됩니다.
[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 뷰에 톰캣 런타임 환경 등록 확인
- Eclipse 상단 메뉴
Window➔Preferences이동. - 좌측 트리에서
Server➔Runtime Environments선택. - 로컬 PC에 설치된 톰캣(Apache Tomcat v9.0, v10.1 등)이 목록에 등록되어 있는지 확인합니다.
- 목록이 비어 있다면
Add...클릭 ➔ 해당 버전의 Tomcat 선택 ➔ 톰캣 설치 경로(Tomcat installation directory) 지정 후Finish.
Step 2. Targeted Runtimes 설정 (가장 추천하는 정석)
개별 라이브러리를 하나씩 추가하는 것보다 프로젝트 패싯(Facet)에 톰캣을 연결하는 것이 훨씬 안전합니다.
Project Explorer에서 프로젝트 우클릭 ➔Properties(단축키:Alt + Enter).- 좌측 메뉴에서
Targeted Runtimes선택. - 목록에서 사용 중인 서버 런타임(예:
Apache Tomcat v9.0또는Apache Tomcat v10.1) 앞의 체크박스를 활성화. Apply and Close클릭.
lib 폴더 내에 있는 servlet-api.jar, jsp-api.jar, el-api.jar를 프로젝트 라이브러리로 자동 마운트합니다.
Step 3. Java Build Path에 Server Runtime 직접 추가 (2019년 원문 방식)
만약 Targeted Runtimes 탭이 보이지 않거나 체크 후에도 잡히지 않는다면 원문에서 소개한 클래스패스 직접 등록을 진행합니다:
- 프로젝트 우클릭 ➔
Properties➔Java Build Path선택. - 상단 탭 중
Libraries탭 클릭.
(Java 9+ 모듈 시스템 사용 시Classpath항목을 먼저 클릭한 뒤 활성화) - 우측 버튼 중
Add Library...클릭. - 라이브러리 목록 창에서
Server Runtime선택 후Next >. - 등록된 서버 목록에서
Apache Tomcat v9.0(또는 해당 버전) 선택 후Finish. 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)
<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>
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.* 그룹으로 변경해야 합니다.
<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>
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: 프로젝트 선택 ➔
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 에러를 발생시킵니다.
5. 여전히 빨간불이 남았을 때 5단계 응급 체크리스트
모든 설정을 완료했는데도 이클립스 에디터에 여전히 빨간 X 표시가 남아있다면 이클립스 내부 캐시 및 메타데이터 꼬임 현상입니다. 다음 순서대로 5단계 조치를 취합니다.
[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
- Tomcat 9:
- 우측
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 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 빌드 시스템에서는 빈번한 빌드 장애를 유발하는 주원인이었습니다.
오늘 정리한 내용을 바탕으로:
- Dynamic Web Project라면 반드시
Targeted Runtimes를 통해 톰캣 라이브러리를 동기화하고, - 신규 프로젝트라면 Maven/Gradle의
provided/compileOnly표준 스코프를 사용하여 환경 종속성을 제거하며, - Tomcat 10 이상 환경에서는
jakarta.servlet과jakarta.tags.core규격을 철저히 준수하여 불필요한 트러블슈팅 시간을 획기적으로 줄여보시기 바랍니다.