Bug 54387 - Having servlets with same url should at least cause warning
Having servlets with same url should at least cause warning
Status: RESOLVED FIXED
Product: Tomcat 7
Classification: Unclassified
Component: Catalina
7.0.47
All All
: P2 normal (vote)
: ---
Assigned To: Tomcat Developers Mailing List
:
Depends on:
Blocks:
  Show dependency tree
 
Reported: 2013-01-08 12:58 UTC by Edson Richter
Modified: 2014-02-17 13:40 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Edson Richter 2013-01-08 12:58:37 UTC
I've found this interesting "mal functioning" in a application where I just copied the mapping portion of web.xml for a new created servlet, but forgot to change de URI.

Tomcat deployed the application without any warning, but when running the application only the last referenced servlet was working (like if the mapping of the first has been overwritten by the last in the XML file).

I made additional tests using annotations in servlets, and the behavior of having more than one servlet with same mapping causes random access to one or another (I cannot determine a predictable way).

In order to prevent breaking existing applications, I would like to have just a "big warning" in the log at startup and/or deployment of the application that have more than one servlet mapped to same URL.

Examples of the problem:

Example 1: Web.xml
...
  <servlet>
    <servlet-name>PrintDacteServlet</servlet-name>
    <servlet-class>br.com.simfreteV1.web.PrintDacteServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>CotacaoReportServlet</servlet-name>
    <servlet-class>br.com.simfreteV1.web.CotacaoReportServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>PrintDacteServlet</servlet-name>
    <url-pattern>/secure/relatorios/Action</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>CotacaoReportServlet</servlet-name>
    <url-pattern>/secure/relatorios/Action</url-pattern>
  </servlet-mapping>
...


Example 2: annotations in java servlet files

@WebServlet(name = "PdfReportPrint", urlPatterns = {"/secure/relatorios/doReport"})
public class PdfReportPrint extends AbstractBaseServlet {
...


@WebServlet(name = "PrintBoletoServlet", urlPatterns = {"/secure/relatorios/doReport"})
public class PrintBoletoServlet extends HttpServlet {
...
Comment 1 Mark Thomas 2013-01-08 21:49:54 UTC
Hmm.

Before we do anything on this I'd like to get some feedback from the Servlet EG as to what the expected behaviour is here. My personal view is that it should not be allowed and the web application should fail to start.

http://java.net/jira/browse/SERVLET_SPEC-53
Comment 2 Mark Thomas 2013-01-10 08:13:05 UTC
The EG has confirmed that deployment should fail.
Comment 3 Mark Thomas 2013-01-10 12:09:35 UTC
This has been fixed in trunk and 7.0.x and will be included in 7.0.35 onwards.
Comment 4 Loïc Albertin 2013-05-23 16:20:54 UTC
Hi Mark,

I totally agree with the fact that an URL should be mapped to only one Servlet.
But, I'd like to have your point of view and maybe the one of the Servlet EG about the following case.

Let's imagine that we have a Servlet annotated with @WebServlet("/an/url") and a web.xml descriptor that define the same Servlet class with a different logical name mapped to the same URL through a Servlet mapping.

From my point of view this is actually the "same" Servlet which is mapped to this URL and it doesn't contradict the updated paragraph in the Servlet specification [1].

With the current Tomcat implementation this case will lead to a deployment failure. My proposed solution is that when different Servlet names with the same Servlet class are mapped to a same URL the first one defined will be chosen. This will lead to prefer the one defined in the web descriptor over annotations.
So, what do you think?

Thanks & regards,
Loïc


[1] "If the effective web.xml (after merging information from fragments and annotations) contains any url-patterns that are mapped to multiple servlets then the deployment must fail."
Comment 5 Edson Richter 2013-05-23 16:54:01 UTC
My understanding is that

Scenario 1:

ServletA -> /my/path/to/servlet
ServletB -> /my/path/to/servlet

Rule: same path to different servlets = failure.


Scenario 2:

ServletA -> /my/path/to/servlet1
ServletA -> /my/path/to/servlet2

Rule: same servlet to different paths: success.



Regards,

Edson
Comment 6 Violeta Georgieva 2013-05-23 18:57:49 UTC
(In reply to comment #4)
> 
> Let's imagine that we have a Servlet annotated with @WebServlet("/an/url")
> and a web.xml descriptor that define the same Servlet class with a different
> logical name mapped to the same URL through a Servlet mapping.
> 


In Servlet Spec 3.0, 8.1.1 @WebServlet

There is an explicit statement that these are two different servlets.

"
If the same servlet class is declared in the deployment
descriptor under a different name, a new instance of the servlet MUST be
instantiated.
"

Regards
Violeta
Comment 7 Loïc Albertin 2013-06-04 07:47:45 UTC
Hi Violeta,

thank you for that clarification, I agree with you. 
I missed this statement in the specification.

Thanks again.
Regards,
Loïc
Comment 8 Abdul Aziz 2013-12-10 13:35:34 UTC
I want to understand more..

having following configuration in deployment descriptor

<servlet>
	<servlet-name>sn1</servlet-name>
	<servlet-class>com.servlets.urlpatterns.Servlet1</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>sn1</servlet-name>
	<url-pattern>/s</url-pattern>
</servlet-mapping>

<servlet>
	<servlet-name>sn2</servlet-name>
	<servlet-class>com.servlets.urlpatterns.Servlet1</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>sn2</servlet-name>
	<url-pattern>/s</url-pattern>
</servlet-mapping>

why should the server startup / app deployment fail? what makes the difference?

Any how both the servlets sn1 and sn2 are referring to same Servlet1
Comment 9 Violeta Georgieva 2013-12-10 13:44:32 UTC
(In reply to Abdul Aziz from comment #8)
> 
> Any how both the servlets sn1 and sn2 are referring to same Servlet1

Once you use 
<servlet-class>com.servlets.urlpatterns.Servlet1</servlet-class>
the servlets will point to one and the same class.

But you need to specify different url-patterns that's the case.
Comment 10 Abdul Aziz 2013-12-10 15:04:48 UTC
(In reply to Violeta Georgieva from comment #9)
> (In reply to Abdul Aziz from comment #8)
> > 
> > Any how both the servlets sn1 and sn2 are referring to same Servlet1
> 
> Once you use 
> <servlet-class>com.servlets.urlpatterns.Servlet1</servlet-class>
> the servlets will point to one and the same class.
> 
> But you need to specify different url-patterns that's the case.

Correct!! My Question is, Why should the server start-up fail?

What difference would it make if I try to access either of the servlet's with same url pattern?

I agree its foolish doing so.. But failure during server up doesn't make sense, Right?

Earlier versions of Tomcat used to support this (prior to 7.0.35)

However server start-up should fail, if same url pattern refers to different servlets say

<servlet>
	<servlet-name>sn1</servlet-name>
	<servlet-class>com.servlets.urlpatterns.Servlet1</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>sn1</servlet-name>
	<url-pattern>/s</url-pattern>
</servlet-mapping>

<servlet>
	<servlet-name>sn2</servlet-name>
	<servlet-class>com.servlets.urlpatterns.Servlet2</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>sn2</servlet-name>
	<url-pattern>/s</url-pattern>
</servlet-mapping>