타 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 하는 방식을 사용하는 등 코어 로직에서 차이가 있었을 것이라 추정한다.