Apache Tomcat, Jetty and Sun Java System Web Server are only Java Web (Servlet) containers, meaning they can only execute Servlets/JSP - they don't provide the full Java EE API stack.
As such, they can only deploy .war
files, not .ear
(that would also include .jar
modules with EJBs), and do not support out of the box some Java EE APIs like JSF or CDI. or other functionalities/APIs. It is important to note that, since Java EE6, .war
files may contain EJBs. More info on differences about .war
and .ear
.
Every Java EE server has a Web Container + EJB Container.
(You can see here and here that Tomcat and Jetty do not claim to be JavaEE servers, just servlet (web) containers.)
JBoss Application Server uses JbossWeb (an Apache Tomcat fork) as its web container. Its EJB container is, well, JBoss (they don't have a separate name other than "JBoss EJB Container" for it).
The others (IBM WebSphere, Oracle/BEA WebLogic, TomEE, Glassfish) also have their web container + EJB container.
TomEE obviously uses Apache Tomcat as its web container. Glassfish also uses an Apache Tomcat fork. (Yes, Apache Tomcat seems to be very popular :)
In the discussion below, you can change Tomcat with "Web Container" and JBoss with "Fully capable Java EE Server" whenever they appear. (I used the product's names for clarity.)

Image: Java EE Server and containers - Source: The Java EE Tutorial.
What are the (dis)advantages of having Java Web Servers (such as Tomcat) handling the Servlet/JSP calls and forwarding more complex requests to Application Servers such as JBoss (or IBM WebSphere or BEA WebLogic)?
From a functionality stantdpoint, there is no effective gain
If you place a Tomcat before a JBoss, what you are actually doing is putting a Tomcat before a JBossWeb (web container, thus the entrance to every web application) that will always be before the JBoss' EJB container. If we are talking about functionality, that's just redundant, as we have the same service being delivered twice.
Switching implementors or Clustering capabilities
Placing a Tomcat before a JBoss can make sense if they are using JBoss for its EJB container only: the choice here, then, would be a simple switch in the web container implementor.
Also, if the Tomcat was at a different network node (or more than one Tomcat/node), clustering capabilities could be applied (that otherwise couldn't, as JBossWeb and JBoss usually are treated as one and thus go in the same machine).
Serving static content and Security issues
What is very common is placing a web server (such as Apache HTTPD or IIS) before the Java Web Container. There are two main motivations for this:
- Make the HTTPD serve the static content (such as images) and forward the rest to the Java web container. This is done because web servers are usually better optimized at the task of delivering static content.
- Security: Expose only the HTTPD in the DMZ. One can set up an Apache HTTPD at the DMZ, and make it simply forward everything to Web Containers (Tomcats, etc.) and JavaEE Servers (JBosses, etc.).
If one wants added security, there is no point in using a web container in the DMZ: If it is serving apps (that is, have .war
files deployed to it), the applications are still "vulnerable"; if it its only forwarding requests/responses, then an Apache HTTPD is a much better option!