JSP 를 실행하는데 계속 아래와 같은 에러 메세지가 나타나서 6시간동안 삽질 후에 찾아낸 것과 알아낸 것을 공유 드립니다. (미래의 나에게 주는 힌트 ㅎ,.ㅎ) 여기서 핵심은 자신이 어떤 환경에서 개발중이며, 어떤 버젼을 사용하고 있는지 확실하게 파악하는 것입니다. 결과만 얘기하자면 아래와 같습니다.
- Jakarta EE 의 버젼과 Tomcat 버젼을 확인한다.
- jakarta servlet 을 사용할거면 glassfish 에서 제공하는 녀석을 추가한 후에 dependancy 에서 버젼만 바꿔주면 된다.
필자는 (24.05.13 기준)
Mac, IntelliJ IDEA Ultimate 2024.1.1 버젼을 사용하고 있으며, JSP 환경은 Jarkarta EE 9.1 를 사용중이며 배포는 Tomcat 9.0.88 을 사용하였습니다. 해당 버젼으로 Form tag 와 button submit 을 활용한 페이지 넘기기와, ajax 를 활용하여 간단한 기능이 담긴 페이지 구현에도 오류 없이 성공하였습니다. 하지만 JSTL 을 설정해주는 과정에서 오류가 발생하였습니다.
절대 uri인 [http://java.sun.com/jsp/jstl/core]을(를), web.xml 또는 이 애플리케이션과 함께 배치된 jar 파일 내에서 찾을 수 없습니다.
해당 오류는 아래의 코드를 선언 해 주었을 때 생겼습니다.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
해당 태그를 로드하지 못하는 주된 이유는 JSTL 라이브러리가 프로젝트에 제대로 포함되지 않았거나, 잘못된 버전의 라이브러리를 사용하고 있다는 것을 알고는 있었는데. 일단 먼저, (왜 이렇게 Maven 을 줬는지 모르겠지만 ;;) Maven 에 Jarkarta EE 와 Java EE 두 가지의 JSTL 관련 의존성이 포함되어 있다는 것을 발견하게 되었습니다. 즉, 어떤건 Javax 로 import 되어 있었고, 어떤건 Jarkarta 로 import 되어 있었습니다. 따라서 잠재적인 충돌의 원인이 되어 javax.servlet.jsp.jstl 을 제거해주었습니다.
이후에 JSTL 의 구현체를 포함하기 위해 다음 의존성을 추가해주었습니다.
앞서 추가해준 파일은 세가지인데 그 중 .jstl 과 .jstl-api 중 하나만 없어도 작동하지 않았습니다. 그 이유에 대해 검색한 결과 jstl-api 은 api 의 인터페이스와 보조클래스가 있지만 실행클래스가 없기 때문에 이것을 보완해주는 .jstl 이 필요합니다. 하지만 모든 종속성을 Maven 에 추가 해주어도 태그 사용은 불가능 하였고, Tomcat lib 에 직접 jstl-1.2.lib를 넣어줘도 작동을 안했고, IntelliJ 내부에 WEB_INF 에 lib 에 넣어줘도 작동을 안했습니다. 모든 종속성을 맞추어 줬음에도 불구하고 태그 사용은 불가능 하였는데 여기서 간과하였던게 바로 Tomcat 버젼이었습니다.
Tomcat 공식 홈페이지에 접속하게 되면 Jarkarta 버전에 따른 Tomcat 버젼을 아주 친절히 설명해주고 있습니다. 필자의 경우 Jakarta EE 의 Servlet 버젼을 5.0.0 을 사용하였고, 해당 버젼은 Tomcat 10.1.x 를 사용해야 했습니다 ... 따라서 톰켓 버젼을 10.1.23 으로 변경 해주니 아주 잘 작동하였습니다 .. 제가 추가해준 maven은 총 3개 입니다 !
Jakarta Servlet | https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api | V 5.0.0 |
Jakarta JSTL API | https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api | V 3.0.0 |
Jakarta Implementation | https://mvnrepository.com/artifact/org.glassfish.web/jakarta.servlet.jsp.jstl | V 3.0.0 |
하지만 설정을 다 해놓고 까보니 문득 Maven 을 한번 까봐야 겠다는 생각이 들어 직접 까봤는데...
jakarta.servlet.jsp.jstl-api:3.0.0 이 이미 Jakarata.servlet-api:6.0.0을 종속 받고 있지만 필자는 이미 위에서 5.0.0의 버젼을 종속 시켜주었기 때문에 omitted for conflict 되어진 것을 확인할 수 있었습니다. 따라서 jakarta.servlet-api:5.0.0 을 삭제 시켜 주었더니 !
omitted for conflict 되었던 6.0.0 이 자동으로 종속되는 것을 확인할 수 있었습니다 ! 근데 이렇게 보니 glassfish 에서 제공하는 jakarta.jstl 은 이미 jstl-api 3.0.0 을 종속받고 있는 것을 확인할 수 있었습니다. 따라서 jakarta.servlet.jsp.jstl-api: 3.0.0 을 제거하였더니
오류를 발생하며 이런 로그창을 띄워주었습니다. 해석해보니 ".jstl-api 에 3.0.0-RC1 을 찾을 수 없다. " 였습니다. 여기서 필자는 앞서 설정해주었던 .jstl-api 는 3.0.0 이었는데 glassfish 의 .jstil-api 는 3.0.0-RC1 인것을 볼 수 있었습니다. 따라서 저 녀석의 dependancy 설정을 들어가보니
3.0.0-RC1 인것울 확인할 수 있었고 이것을 3.0.0 으로 변경해주었더니 정상작동하는 것을 확인 할 수 있었습니다.
여기서 하나 더 알게 된 점은 glassfish 가 제공하는 .jsp.jstl:3.0.0 에는 필자가 앞서 주었던 .jstl-api:3.0.0 과 servlet-api:6.0.0 이 이미 dependancy 에 선언 되어있었습니다. 결과적으로는 org.glassfish.web 에서 제공하는 jarkarta.servelet.jsp.jstl:3.0.0 만 추가 해주면 알아서 자동으로 종속되어지는 것을 확인 할 수 있었습니다.
Error 를 고치면서 느낀점.
깔끔해진 나의 pom.xml 을 돌아보며 , maven 을 아주 간단하게 맛을 봤더니 이후에 있을 spring 과 spring boot 설정이 살짝 두려우면서도 그때는 maven 보다 graddle 을 많이 사용한다고 하니 또 설레기도 합니다. intellij 에서 javax.servlet 을 사용하였으면 이런 고생 없이 진즉에 servlet 을 사용할 수 있었겠지만 괜히 jarkarta servlet 을 써보겠다고 똥고집 부려 본 것 같습니다. 6시간이라고 적어는 놨지만 거의 10시간은 잡아먹은 것 같습니다. 아무쪼록 maven에 대해 아무것도 모르는 상태에서 이것저것 추가하면 된다라고 적힌 블로그만 보여지는게 너무 아쉬어 정리해보게 되었습니다. 저와 같은 문제가 있으신 분들에게 도움이 되셨으면 좋겠네요. 얕은 지식으로 눈앞에 보이는 문제만 해결한거와 다를바 없으니 틀린것이 있다면 알려주시면 감사하겠습니다.
'Error' 카테고리의 다른 글
RKE2 클러스터 연결 이슈 (CrashLoopBackOff) (0) | 2024.12.10 |
---|