타 WAS 에서 잘 사용하던 소스를 Tomcat 에 올렸는데,
"java.lang.IllegalArgumentException: The servlets named [name1] and [name2] are both mapped to the url-pattern [/pattern] which is not permitted" 와 같은 Exception 이 발생하면서 반영이 안되었다.
(여기서 name1, name2, pattern 은 실제 내용을 수정한 것임을 밝힌다)
web.xml 을 살펴보았다.
<servlet-mapping> <servlet-name>name1</servlet-name> <url-pattern>/pattern</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>name2</servlet-name> <url-pattern>pattern</url-pattern> </servlet-mapping>
더 이상의 자세한 설명은 생략한다.
대신 Tomcat 소스를 확인해보자.
org.apache.catalina.deploy 패키지 내에 WebXml.java 가 해답을 가지고 있다.
우선 아래를 보자.
for (Entry<String, String> entry : servletMappings.entrySet()) { context.addServletMapping(entry.getKey(), entry.getValue()); }
addServletMapping 은 여기에 있다.
// servlet-mapping private Map<String,String> servletMappings = new HashMap<String,String>(); private Set servletMappingNames = new HashSet(); public void addServletMapping(String urlPattern, String servletName) { String oldServletName = servletMappings.put(urlPattern, servletName); if (oldServletName != null) { // Duplicate mapping. As per clarification from the Servlet EG, // deployment should fail. throw new IllegalArgumentException(sm.getString( "webXml.duplicateServletMapping", oldServletName, servletName, urlPattern)); } servletMappingNames.add(servletName); } public Map<String,String> getServletMappings() { return servletMappings; }
위 코드에서 servletMappings 에 mapping 건을 계속 담게(put) 되고 그 결과 값을 oldServletName 로 받게 되는데, oldServeltName 이 null 이 아닌 상황에서 예외상황을 발생시키고 있으며, null 이 아닌 상황이라는 것은 key 가 이미 존재한다는 것, 그리고 그 key 는 urlPattern (url-pattern) 이라는 것을 알 수 있다.
결론적으로 Tomcat 은 서로 다른 servlet-name 이 하나의 url-pattern 을 가질 수 없음을 알 수 있다.
그렇다면 다른 WAS 에서는 예외상황 없이 왜 잘 되었을까? 하면 자세히는 모르겠지만 아마 override 하는 방식을 사용하는 등 코어 로직에서 차이가 있었을 것이라 추정한다.