Roy has posted 1 posts at DZone. View Full User Profile

Reviewing the Early Draft: Servlet 3.0

05.30.2008
| 6654 views |
  • submit to reddit

First of all: Yes! There is a new Servlet spec coming! I had already seen some examples on this years JavaOne, but you can now download the complete early draft here. But after I browsed through it, I came to the conclusion that I don't like the new spec. There are currently some strange decisions and unclarities in it. Please allow me to give some examples:

@Servlet(urlMappings={"/foo", "/bar"})
public class SampleUsingAnnotationAttributes {
     @GET
     public void handleGet(HttpServletRequest req, HttpServletResponse res) {
          //Handle the GET
     }
}

This piece of code is a new servlet. A lot of features are now based on annotations. And there is some good things in this, look at the @Servlet annotation. This annotation contains the locations where this servlet is going to be mapped. So there is no more need to put all this in the web.xml.

But then there is the @GET annotation. And I really don't see what this annotation improves over having a HttpServlet interface with a doGet method. The only thing that would be useful is when you can put @GET and @POST on one method. But as far as I know now this is currently not supported. A couple of problems/unclarities with this:

You don't have code completion (an interface would have this)
Its a lot more error-prone (an interface forces the right parameters)
Its unclear/unspecified what happens when a Servlet has duplicate HttpMethod annotations; (2x @GET in one Servlet)

The same kind of problems arise in other places using annotations, for example in the ServletFilter:

@ServletFilter
@FilterMapping(“/foo”)
public class MyFilter {
     public void doFilter(HttpServletRequest req, HttpServletResponse res) {
          ...
     }
}

In this example we see that you can define a ServletFilter using the ServletFilter annotation. The first oddity is the @FilterMapping annotation.. why does the @ServletFilter need a seperate filtermapping annotation while the @Servlet just places this in its properties. Not very consistant. :(

Also, we now have a POJO being a ServletFilter, but its specified nowhere that your filter must contain this doFilter method. Just like the methods in the @Servlet its easy to make a typo and it wouldn't be noticed until runtime probably.
Why not use an interface for this?

This same problem also arises in the @ServletContextListener:

@ServletContextListener
public class MyListener {

     public void contextInitialized(ServletContextEvent sce) {
          ServletContext sc = sce.getServletContext();
          
          sc.addServlet("myServlet", "Sample servlet", "foo.bar.MyServlet", null, -1);

          sc.addServletMapping("myServlet", new String[] { 
               "/urlpattern/*" 
          });
     }
}

What forces the signature "public void contextInitialized(ServletContextEvent sce)"?
Nothing does, easy to make mistakes.

For some reason it seems like the JSR-315 group is very eager to put annotations everywhere. But I'm having serious doubt if this is the correct way to do this. Something like mapping a Servlet to a URL, this is cool. You are adding meta-data (mapping information) to a class. But specifying that a method is a GET method, this says something about the role of the method. People, why not just leave this hardcoded... using interfaces and parent classes. This isn't meta-data right? This shouldn't be configured with annotations...

But its not all bad, there are some cool new features in the spec. I really like the "Suspending Requests" idea. If you have a long running backend process (JDBC call, webservice, JMS) you don't want the Servlet to lock and wait for it. With the new feature you can suspend a Servlet and resume it once the backend is done.

Also new is 'Pluggability', the Servlet auto-discovery mode. During startup a scanner will (try to) find all the Servlets from the classpath and instantiate them. Then there is no more need to define all the Servlets in the web.xml! Although this would be nice during debugging or making a small project, I wouldn't trust it in an Enterprise environment. But luckely there is a way to shutdown the auto-discovery with one little line of XML (metadata-complete=true).

In conclusion, there are some good ideas in the Servlet 3 spec, but also some things I really don't like.

So what would be my suggestion? Something like this probably:

@ServletMapping(“/foo”, "/bar") //Only meta-data in annotations, with the naming consistant with @FilterMapping
public class MyServlet extends HttpServlet {

     @Override //keep strong typing!
     public void doGet(HttpServletRequest req, HttpServletResponse res) {
          ...
     }
}

From http://www.redcode.nl/blog16.html
 

Published at DZone with permission of its author, Roy van.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Leonid Maslov replied on Fri, 2008/05/30 - 11:00am

I Would agree with You about strong typing.Refactoring and ode verification is the main things Java is proud for. 

 

I would await @SecurityPermissions and/or @Authorization(type=basic) or smth if not already. As far I can see - the specs doesn't provide such as functionality.

 Comment:

In some cases I assume POJO servlets without any extends or implements - would be appreciated (in some kind of unit testing probably). Anyway - with or without annotation goodies people will extend those from HTTPServlet atc just to make strong typing work for them.

Brian Sayatovic replied on Fri, 2008/05/30 - 11:15am

I don't even like the servlet mapping annocations.  I presume you can still use web.xml if you want, but use the annotations for simple cases.  But if I'm using a third-party framework (e.g. Apache Axis) that includes a servlet in it slibrary that I would like to deploy at a custom mapping, I will do so via the web.xml.

So, at best, when I need to find a mapping for a servlet I have to look two places (annotated classes, web.xml) instead of just one.

Roy van replied on Fri, 2008/05/30 - 12:15pm in response to: Brian Sayatovic

That is a good point. But the main focus is to provide easier ways to do this stuff. They don't remove anything from the web.xml, it can still be used as is. But most of the annotations don't help make things easier at all, instead you just loose things the IDE can help you with. And they also didn't add the annotation for the 'advanced' heavy users either...

Raveman Ravemanus replied on Fri, 2008/05/30 - 12:52pm

hehehe, funny stuff. Is this certification driven design?

Mark Thornton replied on Fri, 2008/05/30 - 2:53pm

Code completion seem to work OK with annotations in my IDE (IntelliJ IDEA).

Casper Bang replied on Fri, 2008/05/30 - 3:34pm

I completely agree. It's sad that the lack of expression and growth in Java the language amounts to annotations being so massively misused. Beans binding, JPAQL. The upcoming JSR-308 is only going to reenforce this tragic trend.

Vic Cekvenich replied on Fri, 2008/05/30 - 3:57pm

Crap spec. It's not even secure to use jars anymore.

 

Comet is good, but why not leave all rest out. 

Leonid Maslov replied on Fri, 2008/05/30 - 4:09pm in response to: Vic Cekvenich

Completely agree. Cometd/Jetty Continuations/Tomcat 6 Suspend ... are great. I personally have experience only with Jetty continuations. IMHO Cometd like functionality is MUST HAVE for Web2.0. The rest could rest in peace :)

Roy van replied on Fri, 2008/05/30 - 8:28pm in response to: Mark Thornton

[quote=mt79448]Code completion seem to work OK with annotations in my IDE (IntelliJ IDEA).[/quote]

But if people make new annotations, they have to provide some kind of method information to the IDE. So basicly what the IDE needs for an annotation is a precise describtion of the method signatures it requires....but wait, isn't that just what an java Interface is? So why are we doing this (double) again?

I think IntelliJ is a great IDE, and having support for this is a nice gift to the developers, but you are kind of avoiding the real issue. You provide (framework-) developers with an excuse to do it 'wrong' IMHO, because the IDE can 'fix' this for you.

Jonhnny Weslley replied on Fri, 2008/05/30 - 9:25pm

Moreover the new spec:

  • no code completion, no interface contracts
  • breaks compatibility with the old versions
  • annotated methods requires reflection to be invoked, that is, the performance is affected

 

 Annotations are cool, but they must to be used with moderation. Servlet 3.0 API is using annotations like as a golden hammer!

Great post!!!

Silvio Bierman replied on Sat, 2008/05/31 - 3:36am

Annotations are an abomination. It is sad that the servlet spec is getting polluted with them as well.

Jan-kees Van Andel replied on Sat, 2008/05/31 - 4:22am in response to: Silvio Bierman

[quote=sbierman@jambo-software.com]Annotations are an abomination. It is sad that the servlet spec is getting polluted with them as well. [/quote]

I personally wouldn't go as far as to call annotations an abomination. Annotations certainly have their uses. A framework like Hibernate Validator is in my opinion an example of decent annotation use.

But this spec is a very bad (or at least strange) way to use annotations.

I think the EG has some work to do. Fix this crazy thing or explain to the community what their motivations are for using annotations.

ramon wang replied on Sat, 2008/05/31 - 8:18am

I think anotation will be a great supplement for web.xml, they will make your job easy, if applied properly; and lots of things can not be done just by anotation in servlet, it's something like the anotation in EJB3, it gives you excellent support to ejb-jar.xml, right?

Silvio Bierman replied on Sat, 2008/05/31 - 4:09pm in response to: Jan-kees Van Andel

The Hibernate example is exactly where my problem with annotations lie. They are not a language feature but a unstructured language extension facility that is primarily targeted at framework and tool providers who useit to glue the tool to the code. It encourages framework/tool-design that does not use proper language primitives but self-crafted extensions, mostly to save code lines.

Since new versions of said tools may force one to use annotations it is not even a language feature that we can choose to ignore. If and when the language is properly fixed to make annotations superfluous we will be stuck with heaps of polluted code bases.

Java has been my primary programming environment for eight years now ever since I switched from C++. I still love the platform but where generics merely made me frown the introduction and spread of annotations is causing me to seriously look at other languages for the platform.

Paul Keeble replied on Sat, 2008/05/31 - 10:57pm

My is that some lovely looking code, but alas I see the pain all too clearly. All that type safety (love it or hate it is what java is all about) is just gone. Its hard enough remembering what the types are for a gizillion methods across all the APIs and frameworks without having all of it erased using Annotations. The shortcut for mapping to an url is not so terrible. What we really need is an interface to implement rather than extend from a heavy class such as HttpServlet or this monster of annotations.

Still its not like J2EE has ever been a good way to do things, why expect any real change now after all this time for the better?! J2EE lost the bettle for the web already and we need a change.

Steven Baker replied on Sun, 2008/06/01 - 11:50pm

needless to say, this draft will hopefully be reviewed and changed alot.

i do like the idea of taking away the needs for web.xml updating, but the lack of type control makes me a sad panda.

i hate all this blackmagic typeless coding, this will only make it harder to follow, debug and control

Jan-kees Van Andel replied on Mon, 2008/06/02 - 3:04pm in response to: Steven Baker

[quote=zynasis]

needless to say, this draft will hopefully be reviewed and changed alot.

i do like the idea of taking away the needs for web.xml updating, but the lack of type control makes me a sad panda.

i hate all this blackmagic typeless coding, this will only make it harder to follow, debug and control

[/quote]

In some way the type control doesn't change. Yeah, a modern IDE can validate class names in web.xml, but validating annotations on classes is also possible. In fact, you don't even need that much validations, since most things are self-validating, like the fact that an annotation is always placed on a class/method. The method/class thus always exists. The only thing that has to be validated in this example is the method signature, accepting some kinds of parameters. You can even make the validations as smart as to accept sub classes of parameters, like HttpServletRequest/Response in a doFilter method, which in the current spec requires a cast in most cases, because the interface defines doFilter(ServletRequest, ServletResponse) instead of the Http*** sub classes.

The only two things that scare me are:

  1. One, everyone is getting on the annotation-train, while often there is no real reason for it. First try to find out what the problem is, then try to find some solutions, then check if the solutions work, then the rest of the marketing stuff.
  2. Two, I don't like the classpath search thing. For an EJB I can understand it, especially since ejb-jar.xmls are annoying. But in a web context, where every hacker in the world can access your servlet, I would prefer a more explicit way of publishing Servlets. Something Like web.xml, which has other advantages, like providing an overview of all public Servlets.

    In my opinion, DWR is based on the right principles regarding security (http://getahead.org/dwr/security) and the Servlet 3.0 guys should consider something like the DWR approach. Ease of development is okay, but security holes are not.

    Luckily, the expert group has recognized this fear and provided a <metadata-complete /> tag. I think I will use it by default. ;)

Silvio Bierman replied on Tue, 2008/06/03 - 3:14am in response to: Steven Baker

I do not see how not having to update web.xml but having to update the servlet source instead is anything but a disadvantage.

Besides, I use servlets primarily via embedded Jetty instances so we already have this stuff in a plain and simple piece of Java code.

If the hooking up of the servlet in the container must be done via the servlet code (probably useless for anything other then trivial sample code) what is wrong with allowing a servlet to implement an interface that exposes information about contexts and servlet paths?

Silvio Bierman

 

Leonid Maslov replied on Tue, 2008/06/03 - 3:55am

Some stupid notes - Clamour and stir around Servlet 3.0 Draf about this great article.

I really liked the article and people contribution in this: It kinda say - we care. We want our env to be clean, fency and shiny.

Steven Baker replied on Tue, 2008/06/03 - 6:40pm in response to: Leonid Maslov

i would much rather this be in the code, rather than the web.xml (atleast if the code doesnt get trashed too much in this process) as it feels like the code is more strongly connected to the application container rather than through xml configs.... *shudder* i hate xml configs

Silvio Bierman replied on Wed, 2008/06/04 - 4:28am in response to: Steven Baker

I agree and dislike XML configs as well. However, since I prefer to separate servlet logic from how it is mapped in the container I want to put the mapping logic outside the servlet source. Embedding a servlet container (Jetty in my case) allows exactly that.

It would be great if a web application had a standardized way of talking to the container telling it how to map the servlets. Something like an interface exposed by the container to some intialization mechanism in the web application. That way I could code my mapping logic without actually embedding a container.

Now if they would put something like that in the new spec!

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.