开发者

Java web application in a Servlet container vs. standalone

What are the advantages of building a small Java web app to run in a Servlet container (like Tomcat) vs. building a standalone Java app with a built-in web server and running it behind a reverse proxy?

I've been playing with Java for about a year. I've noticed that to launch Tomcat takes time, and it's not always possible to do a hot-redeploy due to class loader issues. The Servlet API seems somewhat convoluted to me, especially from the perspective of configuration and of RESTful design (which it doesn't really fully support).

On the other hand, I've noticed that my IDE can compile and run a standalone app at lightning speed. Configuring Apache for reverse-proxying is a piece of cake, and embedded Jetty seems to handle whatever I can throw at it. I don't need Servlets when I can use Restlet, Wicket, etc. Being able to know better how my app works (because it's not integrated with a huge app server) feels empowering. The stack traces are shorter. Download size is smaller. End-user configuration is easier. I'm guessing performance i开发者_如何学JAVAs likely to be better because there are fewer software layers involved.

However, I am reminded of the saying that what sounds too good to be true usually is. So my question is, why would I not want to make my web apps standalone? What does a Servlet container give me and/or my end users that we really need but don't know about?


There are 2 separate questions in here:

  1. Should I be using an embedded server, or deploy into a container?

    I don't think you should be seeing a big difference one way or the other. There's slightly more code to startup a Jetty server programmatically, and configuration is easier to do programmatically. Even though IDE support for web app configuration and deployment is getting better, it's still worse than for standalone applications (this is kinda by definitions, since there's a superset of things to support).

    On the other hand, app servers give you some nice benefits like built-in management, built-in ability to run as a service, etc.

    You could even use a hybrid approach: use an embedded server to develop locally, then deploy into a container in production. But that's a bit weird: if you go through the trouble of making a proper WAR file, IDEs should really be able to handle deployment into a container adequately.

    BTW, it's weird that you have issues with hot-redeploy; Tomcat shouldn't be having issues with it unless you're running into some strange corner case...

  2. Should I be using Servlet API?

    This is orthogonal from #1. You could very well embed Jetty and implement Servlets. You could also use Restlet API inside Tomcat through a ServerServlet http://www.restlet.org/documentation/1.0/faq#02.

    I personally find the Servlet API to be pretty straight-forward.You get nice things like concurrency and state management. I don't quite know what that means that RESTful design is not supported, but if Restlets address your requirements better, then use that...


Embedded Jetty can be a good choice if you don't need the full Servlet stack. Unlike Tomcat, Jetty makes it easy to get rid of the parts you're not using (JSP, JNDI, whatever).

Writing your own HTTP server, on the other hand, is a terrible idea. Sure, it's easy to write something that handles basic requests. But soon you'll find that some clients are having trouble with it because it doesn't support the full protocol specs; or that it crashes when there's more than a few hundred users; or that there's a vulnerability that allows some kid in Malaysia to blow up your printer. So don't re-invent the wheel.

As for your complaint that the Servlet API doesn't support RESTful design - you're missing the point, it was never intended to do that. But there are plenty of REST libraries that run on top of the Servlet API.


An embedded Jetty is also a servlet container. I assume your application includes a web.xml where you define a wicket filter / servlet, the RESTlet servlet and their mappings (at least). So you cannot get rid of the Servlet API (or of a servlet container, even if you embed it), but you can hide it as well as possible underneath your frameworks and into some main() method of your own. RESTlet (or Jersey or any JAX-RS implementation) as well as Spring MVC are all based on servlets, so the Servlet API does support REST pretty well, i'd say.

P.S. The two approaches do not exclude each other. You can very well work with Jetty during development and then deploy your war into some (non-embeded) container for QA / production. Or... stick with Jetty for production, if that really suits your needs.


Servlet containers often provide a bunch of useful stuff like automatic session management, hot-deploying, frameworks for failover and clustering and so on. It depends on the container, of course, but sometimes these are very useful tools. Sometimes they are not.

EDIT: Just noticed your comment about hot-redeploy. Yes, sometimes the containers are buggy and a pain to work with, and they all tend to have their own quirks. Nevertheless, sometimes they do provide some really good stuff.


The in-process Servlet containers are the containers which work inside the JVM of Web server, these provides good performance but poor in scalibility.

The out-of-process containers are the containers which work in the JVM outside the web server. poor in performance but better in scalibility In the case of out-of-process containers, web server and container talks with each other by using the some standard mechanism like IPC.

In addition to these types of containers, there is 3rd type which is stand-alone servlet containers. These are an integral part of the web server.


if you are having issues with your hot deploy, most likely you aren't cleaning up your external connections or other resources. To handle this, usually you want to implement a listener that will let you know when something is started or stopped.

you should probably in your wars implement something like this (tomcat 6):

public class MyTomcatInitCleanupListener implements ServletContextListener
{
    @Override
    public void contextInitialized(ServletContextEvent arg0)
    {
        super.contextInitialized(arg0);
    }

    @Override
    public void contextDestroyed(ServletContextEvent arg0)
    {
        super.contextDestroyed(arg0);
    }
}

for tomcat 7+, you can google "tomcat lifecycle listener"

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜