Consider the following servlet snippet: URL main = context.getResource("/WEB-INF/wsdl/hello_literal.wsdl"); URL sub = new URL(main, "hello.xsd"); URL sub1 = context.getResource("/WEB-INF/wsdl/hello.xsd"); While sub.toString().equals(sub1.toString()) is TRUE, sub.equals(sub1) returns FALSE, where it should also return TRUE. I noticed the reason sub.equals.(sub1) is FALSE is because their getHost() values are different: sub.getHost() -> "" sub1.getHost() -> null Notice that in the case of URL sub = new URL(main, "hello.xsd"); java.net.URLStreamHandler.parseURL() will set host to "", while in the case of URL sub1 = context.getResource("/WEB-INF/wsdl/hello.xsd"); which is implemented by org.apache.catalina.core.ApplicationContext.getResource() as follows: return new URL ("jndi", null, 0, getJNDIUri(hostName, fullPath), new DirContextURLStreamHandler(resources)); the host component is set to "null". Changing return new URL ("jndi", null, 0, getJNDIUri(hostName, fullPath), new DirContextURLStreamHandler(resources)); to return new URL ("jndi", "", 0, getJNDIUri(hostName, fullPath), new DirContextURLStreamHandler(resources)); in ApplicationContext.getResource() fixes the problem. Unfortunately, I am having cvs problems, otherwise i would have committed the fix myself.
I will not be fixing that, as this changes the value of toString for the URL.
Good point about toString(). I have a solution for that as well. Just override org.apache.naming.resources.DirContextURLStreamHandler.toExternalForm() and have it ignore the "authority" part of the URL, as follows (this is copied from java.net.URLStreamHandler.toExternalForm(), with "authority" part ignored): /** * Converts a <code>URL</code> of a specific protocol to a * <code>String</code>. * * @param u the URL. * @return a string representation of the <code>URL</code> argument. */ protected String toExternalForm(URL u) { // pre-compute length of StringBuffer int len = u.getProtocol().length() + 1; if (u.getPath() != null) { len += u.getPath().length(); } if (u.getQuery() != null) { len += 1 + u.getQuery().length(); } if (u.getRef() != null) len += 1 + u.getRef().length(); StringBuffer result = new StringBuffer(len); result.append(u.getProtocol()); result.append(":"); if (u.getPath() != null) { result.append(u.getPath()); } if (u.getQuery() != null) { result.append('?'); result.append(u.getQuery()); } if (u.getRef() != null) { result.append("#"); result.append(u.getRef()); } return result.toString(); } It is important that URLs returned by ServletContext.getResource() that are equal have equals() return TRUE. This works for all other kinds of URLs.