There are three different types of TransportListener implementations (and TransportInDescription instances) that are used during the lifecycle of AxisServlet:
1) The default axis2.xml that we ship with the Web app has a transportReceiver entry for org.apache.axis2.transport.http.SimpleHTTPServer. This is of course wrong because we want to use AxisServlet, not the standalone HTTP server. Since AxisServlet replaces this TransportInDescription anyway (see point 2), the SimpleHTTPServer is never started (fortunately!), but it is still necessary to have the dependencies of SimpleHTTPServer in the classpath (see AXIS2-4464). Note that simply removing the transportReceiver entry from axis2.xml doesn't work, because this leads to the issue described in
2) AxisServlet#init creates a fresh TransportInDescription (with AxisServlet as TransportListener) and registers it in the ListenerManager/AxisConfiguration. This replaces the TransportInDescription from point 1. AxisServlet, in conjunction with ListingAgent#extractHostAndPort also implements some sort of autodetection mechanisms for the port number (using the RUNNING_PORT configuration context property). Note that all this is only done for HTTP, not HTTPS.
3) ListingAgent can also create and register TransportInDescription instances on the fly if it detects requests using a protocol for which no TransportInDescription has been registered, i.e. HTTPS. See the addTransportListener method. This TransportInDescription instance will have yet another type of TransportListener associated with it, namely org.apache.axis2.transport.http.CustomListener.
This approach has several problems:
- It is a complete mess.
- Nobody will ever be able to document this properly or explain to a user how this works.
- It causes lots of issues. See the JIRAs linked to this report.
- It doesn't take into account that fundamentally, no port autodetection scheme will ever work reliably (i.e. in such a way that it produces the correct WSDL from the start) if the servlet is used with both HTTP and HTTPS. The reason is that autodetection can only rely on information from incoming requests. This means that the WSDL can only be complete if the servlet has received at least on HTTP request and at least one HTTPS request.
Here is a simple proposal to solve these problems once and for all:
- Use a single TransportListener implementation with AxisServlet. This cannot be the AxisServlet itself because there can be two TransportListener instances for the same AxisServlet instance. It would basically be CustomListener, but with a better name, e.g. AxisServletListener.
- Require the user to declare a transportReceiver (with AxisServletListener) in axis2.xml for every protocol (http and/or https) he wants to use.
- If a single transportReceiver is configured, the user is not required to specify the port and AxisServlet will autodetect it based on incoming requests.
- If a transportReceiver is configured for both http and https, the user is required to provide information about the port numbers. This makes sure that the correct WSDL can always be generated.
- For consistency, if AxisServlet receives a request with a protocol for which no transportReceiver is configured, the request is rejected.
- Update the default axis2.xml for the WAR distribution so that it contains: <transportReceiver name="http" class="org.apache.axis2.transport.http.AxisServletListener"/>
The only cases where this approach may fail to give consistent results is when
- port autodetection takes places and the WSDL is retrieved through a non HTTP protocol (very unlikely, unless something like MEX over SOAP/JMS is used...);
- port autodetection takes places and the servlet container accepts connections for the same protocol on different ports.
In both cases it is sufficient to specify the port number in the transportReceiver element to avoid the issue.