Author: admin

  • Living la vita JSP.

    I have finally seen the JSP light! I think I actually like them and
    I will have to stop pouring scorn upon them (and all who use them)!
    So maybe 2004 is a bit late to be blogging about the wonders of JSPs, but
    the agent of my conversion has been the new JSP 2.0 combined with the latest
    2.4 servlet specification. Together with a bit of careful thought, the new
    features result in a capable MVC web framework directly on a raw servlet container without the need for heavy weight framework like struts.

    Living “la vita open source” as I do, I have recently moved to a telecommuting
    village on the Italian riviera: Colletta
    di Castelbianco
    . I undertook to redevelop the village’s
    website, which was a rushed job
    that needed an internationalised wiki wrapped around a booking engine.
    As there are too many web frameworks out there to evaluate, I decided to try to do
    without.

    My basic complaint against JSPs has always been that they do not really
    separate concerns very well. In fact JSPs originally munged concerns into
    a single file of unreadable HTML and java code together.
    The later addition of custom
    tags improved the principal of JSPs, but the practise was still a
    mess of descriptors, classes and way too much <% } %> going on.

    JSP2.0 and 2.4 Servlets have changed all that. They finally provide the features
    needed to develop parameterized HTML in modules that are well separated from
    the business and implementation logic. The key new features are:

      Filters: Added in 2.3 and refined in 2.4, Filters allow a form of
      aspect oriented programming to be used within a webapp. I have used
      separate filters to capture each of the major concerns of the Colletta
      site: Internationalisation, Authentication, Navigation, generic POST handling
      and specific business logic filters derived from the generic POST filter.
      Filters provide an easy way of adding logic to a webapp, without the need for
      a Controller servlet and additional configuration mappings. Why have yet
      another xml descriptor file mapping controllers to URLs when web.xml can now do
      that for you!
      Expressions: At first glance, JSP expressions look like a
      bit of a ${novelty + act}. But they provide a vital link between logic
      and presentation that avoids much boiler plate syntax. Expressions provide
      a search mechanism that looks up requests, parameters, sessions, context scopes and
      hides all the null checking, bean methods, reflection and map lookups that
      may otherwise end up in the JSP. Expressions finally provide an elegant
      way of parameterising both HTML fragments and calls to custom tags.
      Tag Files: Modularity, encapsulation and reuse can now be had in the
      presentation layer without the hassle of descriptors, helper classes and
      bizzare over complex APIs. No more is a tag developer forced to use java for
      generating reusable HTML. The simplicity of tag files encourages the
      creation of a tag almost a soon as a single line of HTML is repeated. Development
      of a set of custom form input widgets is now trivial and the JSP expressions
      allow excellent parameterisation of the tags.

    The Colletta site has been internationalised with a 167 line LocaleFilter. It’s initial
    job is to look at requests and to determine the locale for them, either from
    the session, cookies set previously or from HTTP accept headers. Once the locale
    is determined for the request, the input and output encodings are handled and
    the filter can forward the request to a localised resource. Thus a request for logo.gif
    may be forwarded to logo_it.gif or logo_en.gif. More importantly, because 2.4 filters can
    be applied to request dispatches, this filter is in the path of a
    <jsp:include page="text.jsp"/> and can include text_it.jsp instead.
    Thus layout JSPs can simply include localised content.

    But localisation cannot be done simply by bulk includes of content. Thus the PageFilter
    uses the locale and the requested resource to select a localised property file
    for the request (eg page_it.properties in the same directory as the requested
    resource). The resulting property files is combined with those from all ancestor
    directories, cached and set as the “prop” attribute on the request. The presentation
    JSPs can thus access localised properties via JSP expressions like
    ${prop.name}. This allows simple localisation of complex layouts and error
    messages without making the HTML unreadable.

    As a final example, I will show you the JSP code that renders the discount field
    in the booking form:

    <td ...>
    ${prop.discount}:
    </td><td ...>
    <tag:curInput
    name="discount"
    value="${reservation.discount}"
    readonly="${!user.managerOf[reservation.aptId]}"/>
    </td>
    

    This input field is preceded with a localised label and then calls the tag file
    for currency Input to render the actual HTML input field. It is passed the current
    value of the discount from the reservation option that the BookingFilter has
    put in the session. Also passed is the readonly flag that is true if the current
    user (placed in the request by the UserFilter) is not the manager of the
    apartment.
    The power here, is not in the tag file
    (whose details I leave to your imagination), but in the way that JSP expressions allow
    complex data derived in separate logic to be combined and passed to parameterise modules
    of HTML.

    Web frame works – who needs them!

  • WADI Web Application Distribution Infrastructure.

    The problem with the current breed of HTTP servlet session distribution mechanisms
    is that they do not scale well. I have just tried the first release of
    WADI ‘Web Application Distribution Infrastructure’, and it
    shows great promise as a next-generation session distribution mechanism that can be used for
    simple load balancing, as well as huge multi redundant clusters.

    Web applications are put into clusters with one or more of the following aims:

    Scalability: to use N nodes to increase throughput almost N times.

    Availability: to use N nodes to ensure that after N-1 failures,
    request will find at least 1 node running the application.

    Fault Tolerance: to use N nodes to ensure that after N-1 failures, the
    results of previous requests are correctly available to the application.

    Unfortunately, these aims are not always mutually compatible, nor completely understood
    by those who want to implement a cluster. Also, the components that are used to make a cluster
    (load balancers, session replicators, EJB replications, distributed databases) all have
    different focuses with respect to these aims. Thus it is important to remember why you
    want a cluster and not to make the aims of a single component dominate your own.

    The current crop of load balancers (eg.
    mod_jk,
    Pound and IP routers) are very good at scalability
    and quickly distribute the HTTP requests to a node in a cluster. But they are not so good
    at fault tolerance as once a failure occurs, the mechanisms for selecting the correct node for
    a request are replaced by a “pick a node, any node” approach.

    The currently available
    HTTP session distribution mechanisms
    have mostly been written with fault tolerance in mind. When a node
    receives some session data, it immediately attempts to replicate it somewhere else. Thus the session is
    broadcast on the network or persisted in a database, and significant extra load is generated. Because
    load balancers cannot be trusted to select the correct node, the session is often distributed to
    all nodes. Thus in an N node cluster, every node must store and broadcast it’s own sessions while
    receiving and storing the session from N-1 other nodes. This is great for
    fault tolerance but a disaster for scalability. Rarely is 1+1>1 or even 1+1+1+1>1 and throughput
    is inversely proportional to cluster size. Worse still, the complexity of the mechanism often
    results in more failures and less availability.

    It is difficult to achieve scalability and/or availability with a session distribution mechanism
    that has been designed for fault tolerance. Thus, many clusters do not use session distribution.
    Unfortunately this has its own problems, as load balancers are not perfect at sticking a session
    to a node in a cluster. For example, if IP stickiness is used and the client is on AOL, then their
    source IP can change mid session and the load balancers will route the requests to the wrong node.
    To handle the imperfections of load balancers, a subset of session distribution is needed – namely
    session migration.

    Session migration is the initial focus of WADI, so
    that it can provide scalability and availability to match the available load balancers.
    However, WADIs extensible architecture has also been designed for fault tolerance, so eventually
    it will be able to handle all the concerns of clustering Servlet sessions.

    WADI has been simply integrated with the
    Jetty and
    Tomcat Servlet containers. For normal operation, it adds very
    little overhead to session access. Only the cost of synchronizing
    requests to the session and of some AOP interceptors. Expensive mechanisms such as migration or
    persistence are only used when a node has been shutdown or a load balancer has directed the
    request to a different node.

    When a WADI node receives a request for which it has no session data, it can ask the cluster
    for the location of the session. This can either be on another node or in persistant storage (after
    a timeout or graceful node shutdown). The request can then be directed to the correct node or the session can
    be migrated to the current node.

    WADI is still alpha software, but is actively being developed by
    Julian Gosnell
    of Core Developers Network and should soon be included with
    Jetty 5 and Geronimo.

  • A Shared Jetty Server in a College Environment


    When I was systems administrator for the University of North Carolina at
    Charlotte department of Computer Science, I saw the need to establish an
    environment for our students to experiment with servlets.
    The goal was to provide a centralized system for our students to
    deploy their servlets / web-applications on without having to shoulder
    the additional burden of administrating their own web / servlet containers.
    At the time, the department of computer science was a partner in a heavily
    centralized workstation-based computing system modeled after MIT’s Project
    Athena, using AFS as an enterprise filesystem. Having such a filesystem
    solved the problem of getting the student’s code + web-application data
    to the servlet container — just save it in a readable portion of the
    student’s AFS home directory, and the servlet server can pick it up
    and go.

    I developed a workable solution with Jetty version 3. I found the internal
    architecture of Jetty to follow the ‘as simple as things should be, but
    no simpler’ rule, allowing me, a time-constrained sys admin with Java
    skills, to squeeze off the project in the time allowed so that courses could begin to utilize the service. Jetty’s native extensibility allowed me
    to easily extend its functionality, allowing the students to remote-deploy
    and administrate their own servlet / JSP code on the machine via webspace
    gestures.

    Implementation

    The core bits of this was a new HttpHandler implementation which acted as
    the main controller. In Jetty 3, HttpHandlers are stacked within
    HandlerContext objects, which are mapped to URI patterns within the
    Jetty server itself. The HandlerContext most closely matching the
    URI named in a HTTP request is asked to handle the request, which it
    does so through iterating over each its contained HttpHandlers.
    The HandlerContext containing this HttpHandler implementation was mapped to URI “/~*”, so that this handler would be considered to handle a request to “/~username/…”. The handler’s initial
    responsibilities were to:

    1. Dynamically build contexts for users on demand by first
      reference to their own webspace on the machine, such as the first
      hit to “/~username/*”. This handler would look up the user’s homedir
      in a UNIX passwd file containing only students (no system accounts),
      and then create a new HandlerContext to serve out static content and JSPs
      out of ~username/public_html in filespace, and dynamically
      mapped servlets from ~username/public_html/servlets in filespace. The
      ability to lazily deploy a user’s personal context was paramount, since
      possibly only 20 out of many thousands of possible students would use
      the server any given day. The newly-created HandlerContext would be
      preferred by Jetty to serve out requests to “/~username/*” over this
      handler’s context, since the match to “/~username/” was more specific.
    2. Reload any one of the already-deployed user contexts, so that
      Jetty would reload any class files that had been recompiled. This was
      done through merely stopping, removing, and destroying the user context
      in question (easy, since the HttpHandler implementation maintained a
      Map of username -> created context). After removal of the old context,
      we would lazily initialize a new context upon next request to a resource
      in that context via step 1. This action was done through a custom servlet
      in the same package which maintained a reference to the HttpHandler via the
      singleton design pattern. This servlet, when asked via a webspace gesture,
      would make a protected method call into the HttpHandler to perform this
      step to user foo’s context.

    As time went on, additional features were added:

    • Web applications. Students could deploy web-applications, either
      in expanded format or jar’d up into a subordinate webspace of their
      personal webspace of their own choosing (i.e /~username/mywebapp/*). They
      could then choose to undeploy, redeploy, or to view the logs generated
      by this web-application’s servlet / JSP code (hooks to personal log sinks
      per each webapplication). I chose to have the deployed web-applications
      be ‘sticky’, living through a server reset. This was accomplished by
      serializing the Map of loaded web-applications to disk whenever it changed,
      and to replay it as a log upon server startup. In hindsight, I should have
      deferred the full reload of a known web-application until a resource within
      the web-application was actually referenced, reducing the memory footprint
      of the server, as well as greatly reducing the server startup time (150
      webapps can contain quite a lot of XML to parse).
    • User authentication realms. Users could configure simple
      Jetty HashUserRealms via indicating where in their filespace to load in
      the data for the realm. Realms defined by students in this way were
      forced to be named relative to their own username, such as ‘joe:realm’.
      The student’s web-applications could then contain security constraints
      referencing user / role mappings of their own choosing.

    Security

    Security is an issue for any resource shared by students. The servlet
    allowing users to remote-control their own resources was ultimately
    made available through SSL, locked down via a HTTP basic security
    realm backed by interprocess communication to C code to perform the
    AFS/Kerberos authentication checks given a username / password, allowing
    the server to accurately trust gestures controlling a given user’s
    resources on the server. A java security policy was installed
    in the JVM running Jetty, limiting filespace access, as well as disallowing
    calls to System.exit() and other obvious baddies, as I quickly found out
    that their JDBC code’s SQLException handler often was System.exit().
    Unfortunately, the java SecurityManager model cannot protect against
    many types of ‘attacks’ brought on by untrusted student code, such as
    CPU-hogging broken loops, thread-bombs, and the like. A babysitting
    parent process was quickly written to restart the servlet server if it
    ever went down, as well as would bounce the server if it had
    consumed more CPU than it should have (probable student-code busy-loop).
    Daily restarting the server acted as ultimate garbage collection.

    AFS supports ACLs on directories, and instead of requiring all
    servlet-related files to be flagged as world-readable, the servlet
    server process ran authenticated to AFS as a particular entity which
    students could grant access to. This reduced the capability of just
    stealing their classmates code using filesystem-based methods, but
    they could conceivably just write a servlet to do the same thing.
    Possibly deeper insight into the java security model could have
    corrected this.

    The RequestDispatcher API was another thorn in the side of security,
    allowing any single servlet to tunnel through a context / web-application
    barrier to any other URI valid on the machine, conceivably allowing
    a nefarious student to snarf up content served by another student’s
    servlets, even if that student had wrapped the servlet in a security
    constraint.

    Symbolic-link misdirection based thefts were not considered at all.

    Ultimately, students were warned many times up and down that this
    was a shared server running your peer’s untrustable code, and that
    you should only be using it for your coursework and explorations into
    the servlet world. Nothing requiring true tamper-proof security should
    be deployed on this box.

    Lessons Learned

    As the service became more and more popular, I wish that I had been able
    to move it to a bigger box, something other than a non-dedicated Sun Ultra
    5 with 256M RAM. Having more memory available to the JVM would have greatly
    helped out when a 30 student section all tried to deploy SOAP-based
    application, each using their own jars for apache axis, xalan, etc.

    Using an inverse-proxy front-end to the system would have allowed splitting
    the users across multiple JVM / Jetty instances, allowing gains on
    uptimes (as seen from an individual’s perspective, since a server kick
    to clear out a runaway thread would cause downtime for, say, 50% or 33%
    of the entire user base, as opposed to 100%). It would also have allowed
    me to have the service facade running at port 80, as opposed to the truly
    evil JNI hack I had to do to have Jetty start up as root, bind to port
    80, then setuid() away its rights N seconds after startup. Way ugly.
    After the setuid() call was made, a latch was set in the custom
    HttpHandler, allowing it to begin servicing user contexts. However, having
    more than one Jetty instance would have complicated the implementation of
    the controlling servlet, requiring it to perform RMI when asked to
    control a non-local user context. This pattern could have been used
    to scale down to one user per JVM, with the inverse-proxy being able
    to fork / exec the JVM for the user upon demand, especially with
    Jetty now having HTTP proxy capability. That would probably be overkill
    for a student service, but having a static inverse-proxy with a fixed
    mapping to 2 or 3 Jetty instances (possibly running on distinct
    machines) would have been a relatively attractive performance and
    reliability enhancer per the effort.

    Impressions from the users were mixed. When all of the code being run on
    the machine was benign, not memory nor CPU-hoggish, all was well and
    the students were generally ambivalent — this service was something that
    they had to use to pass their coursework, servlet coding / debugging was
    slower and more cumbersome than ‘regular’ coding, etc. Having a hot-redeploy-capable container didn’t seem whiz-bang to them because they
    had no other experience in servlet-land. When the machine was unhappy,
    such as if it was 3 AM on the night before the project was due and
    one student’s code decided to allocate and leak way more memory than
    it had any right doing, causing the others to begin to get OutOfMemory
    exceptions left and right, then they were (rightly) annoyed and let
    me hear about it the next day.

    If I were to re-solve the problem today, I would:

    • Use some sort of inverse-proxy to smear the load over more
      than one JVM for higher-availablity, allowing the Jetty instances to bind to an unprivileged port.
    • Use the JDK 1.4’s internal Kerberos client implementation to
      authenticate the campus users. Both of these steps would eliminate all
      C code from the system.
    • Run on at least one bigger dedicated machine.
    • Encourage the faculty to work with me to ensure that their
      central APIs can be loaded by the system classloader as opposed to their
      student’s web-application loader so we don’t end up with 30 copies of
      XSTL or SOAP implementations all at once.
    • Lazy-load web-applications and auth realms upon first demand
      instead of at server startup.
    • Age-out defined web-applications and auth realms if they
      have not been referenced in the past X days, so that they’ll eventually
      be forgotten about completely when a student finished the course.

    [Copyright James Robinson 2004]

  • Filters vs Aspects

    Web Application Filters were added to the 2.3 Servlet specification and have been
    enhanced in the just finalised 2.4 spec. Filters
    allow cross cutting concerns to be applied to a web application, which is
    exactly the gig of Aspect Oriented Programming (AOP).

    Being born and breed with OOP, I have always viewed AOP in the cool but
    useless category. Thus I’ve never given myself the opportunity to
    use them for real. On the other hand, I view webapp Filters as useful
    but ugly. It would be great if AOP could replace/enhance Filters so we
    could get into the cool and useful territory.

    So I downloaded AspectJ with the intent of seeing how AOP cross cutting
    concerns could help. The example I considered was the CompressionFilter, which can be applied to
    a web applications to gzip the content generated on the fly. A compression
    filter can be declared in web.xml with :

    <filter>
    <filter-name>Compression</filter-name>
    <filter-class>com.acme.CompressionFilter
    </filter-class>
    </filter>
    <filter-mapping>
    <filter-name>Compression</filter-name>
    <url-pattern>*.html</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>ERROR</dispatcher>
    </filter-mapping>
    

    This CompressionFilter will apply to any request to a URL ending with html
    that is not an
    include request. The filter wraps the HttpServletResponse object with a facade, that
    in turn wraps any OutputStream or Writer provided by the response with a version capable
    of compression the output. The wrappers also allow HTTP headers to be intercepted and
    adjusted. The multiple wrappers involved have always stuck me as a bit over complex, error
    prone and in need of a better way. But it does allow the compression concern to be applied
    to a web application without considering how the html content is generated.

    So how would aspectJ help applying such a cross cutting concern to a webapplication?
    Reading the tutorial I determined that the basic approach needed was to define a
    CompressionAspect that contains:

    • PointCut definitions that identified the getOutputStream and getWriter calls
      of the response object.

    • Advice to wrap the response stream/writer in a compressing stream/writer
    • PointCut definitions that identified the header setting methods of the response object.
    • Advice to intercept and adjust the HTTP headers and other meta data.

    AspectJ certainly provides the Join Points and Advice types required to create this
    aspect, but unfortunately I was unable to define PointCut that capture the equivalent
    semantics of the CompressionFilter declaration above. I believe that the Point Cut semantics
    required are something along the lines of:


      calls to getOutputStream, getWriter & setContentLength methods
      on objects that implement the HttpServletResponse interface
      when RequestDispatcher.include is not on the calling stack
      and the associated request.getRequestURI() ending with '*.html'
      and the request is being handled by my webapplication/classloader

    It was looking oh-so-good up to those last two clauses! The ending with ‘*.html’ could
    be done with an if() point cut, except that there is no way to navigate from a response
    object to the associated request. I couldn’t find any point cuts that would assist me
    with restricting the aspect to a particular web application or classloader.

    My next thought was to get around this problem by creating a no-op Filter and hanging the
    PointCut off calls that go via it. I think this approach would have allowed me to
    specified the required PointCuts, but then I realized another problem. In order for
    these point cuts to work, I would need to use the AspectJ compiler to modify the response
    classes used by the web container and passed into the web application. This breaking of
    web application encapsulation was not something that I am prepared to do. It would
    modify my infrustructure and aspects from one webapplication to be passed if not
    executred to other webapplications.

    AOP or at least AspectJ, does not appear to be a good replacement for Filters, as:

    • PointCuts are defined in the implementation domain (java calls and classes),
      while Filters are defined closer to the application domain (URLs, requests, responses). Using
      the implementation domain events to trigger application level concerns may be impossible or
      at the very least devoid of the application abstractions we so carefully build in OOP.

    • The technology of AspectJ does not appear appropriate for Container/Infrastructure
      based deployment. It is not appropriate for the container/infrastructure classes to
      be modified in order to support the application concerns of a particular application.

    • The declarative nature of aspects means that PointCuts needs to do a lot of work to
      reduce a global scope to a particular instance. It would be great if procedural semantics
      were available so you could say in code: “wrap that object with this aspect” or “apply this
      advice to that Point Cut”. Such programatic code would also assist with the tracebility
      concerns of AOP.

    So my first attempt at AOP has not been successful and I’m still left with the “cool but useless”
    feeling. The OOP design of Filters does allow cross cutting concerns to be implemented
    in a modular fashion, so useful if not cool applies.
    Maybe I’m still missing something or am trying the wrong problem. I hope that an AOP
    guru reading this will be able to correct the error of my ways?

  • NIO and the Servlet API.

    Taylor Crown has written a short paper regarding

    Combining the Servlet API and NIO
    ,
    which has been briefly

    discussed on the serverside
    .

    NIO Servlets have often been discussed as the holy grail of java web application performance.
    The promise of efficient buffers and reduced thread loads are very attractive
    for providing scalable 100% java web servers. Taylor writes about a mockup NIO server that
    he implemented which shows some of this promise.

    Taylors results were not with a real Servlet container running realistic
    loads. But his results look promising and his approach has inspired me
    to try and apply it to the
    Jetty Servlet container.

    The fundamental problem with using NIO with servlets is how to combine the
    non-blocking features of NIO with the blocking streams used by
    servlets. I have tried several times before to introduce a
    SocketChannelListener to Jetty, which only used non-blocking NIO semantics
    to manage idle connections. Connections with active requests were converted
    to blocking mode, assigned a thread and handled by the servlet container
    normally.
    Unfortunately, the cost of manipulating select sets and changing socket modes
    was vastly greater than any savings. So while this listener did go into
    production in a few sites, there was no significant gain in scalability and an
    actual loss in max throughput.

    Taylor has tried a different approach, where a producer/consumer model is used
    to link NIO to servlets via piped streams. A single thread is responsible for
    reading all incoming packets and placing them in the non-blocking pipes.
    A pool of worker threads take jobs from a queue of connections with input and
    does the actual request handling. I have applied this approach to Jetty as
    follows:

    • The PipedInputStream used by Taylor requires all data read to be copied
      into byte arrays. My natural loathing of data copies lead me to write a
      ByteBufferInputStream, which allows the NIO direct buffers to be used as the
      InputStream buffers and then recycled for later use.
    • Taylors mock server uses direct NIO writes to copy data from a file to the
      response. While a great way to send static content, this is not realistic for
      a servlet container which must treat all content is as dynamic. Thus I wrote
      SocketChannelOutputStream to map a blocking OutputStream to a non-blocking
      SocketChannel. It works on the assumption that a write to a NIO stream will
      rarely return 0 bytes written. I have not well tested this assumption.
    • There is no job queue in the Jetty implementation, instead requests are
      directly delegated to the current Jetty thread pool. The effect of this
      change is to reduce the thread savings. A thread is required for all
      simultaneous requests, which is better than a thread per connection, but not
      as trim as Taylors minimal set of worker threads. A medium sized thread
      pool is being used as a fixed size job queue.
    • Taylors mock server only handled simple requests for static content, which
      may be handled with a simple 304 response. Thus no requests contained any
      content of size and neither do all responses. This is not a good test for
      the movements of real content that most web applications must do. The
      Jetty test setup is against a more realistic mix of static and dynamic
      content as well as a reasonable mix of POST requests with content.

    This code has been written against Jetty 5.0 and is currently checked into
    Jetty CVS HEAD in the

    org.mortbay.http.nio

    package. So far I have not had
    time to really optimise or analyse the results, but early indications are
    that this is no silver bullet.

    The initial effects of using the NIO listener is that the latency of the
    server under low load has doubled, and this latency gets worse with load.
    The maximum throughput of the server has been reduced by about 10%, but
    is maintained to much higher levels of load. In fact, with my current test setup I
    was unable to produce enough load to significantly reduce the throughput.
    So tecchnically at least, this has delivered on the scalability promise?

    The producer/consumer model allows a trade off of some low and mid level
    performance in return for grace under extreme load. But you have to ask
    yourself, is this a reasonable trade? Do I want to offer crappy service
    to 10000 users, or reasonable service to 5000? To answer this, you have to
    consider the psychology of the users of the system.

    Load generators do not have any psychology and are happy to wait out the
    increasing latency to the limits of the timeouts, often 30 seconds or more.
    But real users are not so well behaved and often have patience thresholds set well below
    the timeouts. Unfortunately a common user response to a slowly displaying web
    page is to hit the retry button, or
    worse still the shift retry! Having your server handle 1000 requests per
    second may not be such a great thing if 50% of those requests are retries
    from upset users.

    I suspect that the producer/consumer model may be costing real quality of
    service in return for good technical numbers. Consider the logical extreme of
    the job queue within Taylors mock implementation. If sustained load is
    offered in excess of the level that the workers can handle, then that
    queue will simply grow and grow. The workers will still be operating at
    near their optimal throughput, but the latency of all requests served
    with increase until timeouts start to expire. Throughput is maintained, but
    well beyond the point of offering a reasonable quality of service.

    Even with a limited job queue (as in the Jetty implementation),
    the simple producer/consumer model suffers from the inability to target
    resources to where they are best used. The single producer thread gives
    equal effort towards handling new requests as it does to receiving
    packets for requests that have already started processing. On a loaded
    server, it is better to use your resources to clear existing requests so
    that their resources may be freed for other requests. On a multi-CPU machine, it
    will be a significant restriction to only allow a single CPU to perform any
    IO reads, as other CPUs may be delayed from doing useful work or real requests, while
    one CPU is reading more load onto the system.

    Taylors producer/consumers approach is significantly better than my preceding attempts,
    but has not produced an easy win when applied to a real Servlet container.
    I am also concerned that the analysis has focused too much on throughput without
    any due consideration for latency and QOS. This is not to say that this is a dead
    end. Just that more thought and effort are required if producer/consumer NIO is to match
    the wonderful job that modern JVMs do with threading.

    I plan to leave the SocketChannelListener in the development branch of Jetty for
    some time to allow further experimentation and analysis. However, I fear that
    the true benefits of NIO will not be available to java web applications until we
    look at an

    API other than Servlets

    for our content generation.

  • Servlets must DIE! – Slowly

    Now that the 2.4 servlet spec is final, I believe the time is right to start
    considering the end of life for the API. This may sound a little
    strange coming from somebody on the JSR and who has spent years writing
    a servlet container, but I think the API has outgrown it’s original purpose
    and no longer is the best API to go forward with.

    The problem is that servlets are trying to be too many things to too many
    people. One one hand servlets are protocol handlers, able to control the
    the details of connections, transport and encoding. But they are also
    intended as application components, to be used by presentation programmers
    and to be plugged and played with during deployment. There is also the
    the whole stand-alone versus J2EE application server issue within the
    specification.

    The problems that result are many:

    • Web Applications commonly get deployed with their own CompressionFilter,
      XML parser, logging jars and authentication mechanism. What exactly is the
      "application" infrastructure being provided to them?
    • Because protocol concerns are implemented within application components,
      the extensibility and portability of the container is limited.
      For example, compression could be implemented more simply, uniformly and maintainably
      by the container. Instead we have many web applications shipping their own copy of
      the CompressionFilter, complete with the bugs of the original sample code.
      It also limits the efficient portability of servlets, even over versions of HTTP.
      It is often good practise for Servlets written for HTTP/1.0
      consume memory and CPU calculating the content length so that connections can
      be persisted. Because this HTTP concern has been implemented by the
      application, it cannot be disabled when the servlet is deployed in a HTTP/1.1
      container that does not need content length for persistent connections.
    • Servlet containers are unable to take advantage of non-blocking
      NIO because application servlets do their own IO assuming blocking semantics. Nor
      are HTTP features like range requests, trailers and accept headers able to be
      used without involving the application developers.
    • The contract between servlet and container is not well defined for HTTP headers.
      What does it mean in when a servlet sets a HTTP header?
      Is it a command to the container to do something (e.g. Connection: close), a signal
      that the serlvet has done something (e.g. Transfer-Encoding: gzip ) or a helpful
      hint that the container can use,ignore or enforce (e.g. Content-Length: 42)?
    • There is no standard lightweight deployment package for HTTP consumers
      such as SOAP. A full 2.4 web application container is a bit of overkill if
      all you want to do is transport XML blobs. Why should you have a fully
      capable web tier just to accept web services?

    I believe the answer to these woes is to create a new API that is purely about
    content and is really protocol independent. This API would allow for the creation
    of Contentlets, which are application objects that can be selected and queried for meta data and
    content without reference to HTTP headers, transport encodings, threading or streams.
    Contentlets would be equally able to serve their content over HTTP, email, rsync or
    whatever new protocols that emerge that fit a generic request/response style.

    It would be the responsibility of the transport implementation to pull meta
    data and content from the Contentlet. This is the opposite of Servlets, which push
    HTTP headers and content, even if they are not required or accepted by the client.

    The Container would be able to efficiently implement transport features such as
    compression, conditionals, encodings, ranges and protocol specific features.
    The application components could be written with no concern for transport
    and thus application developers need not become protocol experts in order
    to write save, portable and efficient code.

    Of course Servlets could be used to initially implement Contentlets, but
    the eventual aim should be to have direct HTTP to Contentlet containers,
    perhaps built on a revamped and simplified Servlet 3.0 API? Either way,
    we need to begin thinking about the end-of-life of 2.x Servlets.

  • Open source Closed Project

    This is a repost of an old old blog entry that has become relevant again.

    I was hoping to make my next entry one of a technical nature, but the
    JBoss™ Group have just asked me to remove the JBoss™ image from the Jetty pages!

    The JBoss™ image used has been contributed to the Open Source project and is
    available
    on sourceforge
    plus variations of it are distributed with JBoss releases.
    For several years, it has been used on the
    Jetty home page
    and also on the
    Jetty Powered page.
    Both link through to the JBoss™ project page on sourceforge.

    Jetty is the default web tier of JBoss releases
    from 3.0 to 3.2.1 and continues to be the web container of choice for many JBoss users.
    While I no longer work with JBoss™ Group LLC, I am still very much supportive of the JBoss™
    the OS project and continue to maintain the Jetty integration sar (as I am also supportive of
    Jetty in Geronimo, JOnAS, Avalon, etc…).

    I don’t expect JBoss™ Group LLC to hand out my new business cards for me, but I
    do expect an open source project to be administered on a non-discriminatory basis.
    Unfortunately the administration of JBoss is falling way short of that:

    • My name and photo have been removed from the list of

      current and retired JBoss™ contributors
      . OK, so I’m still in the source and CVS log but
      an open source project should not take commercial alliances into consideration when
      deciding how much credit to give for contributions. At least the
      Wayback Machine remembers
      me.
    • I have been censored out of the jboss-user and jboss-dev mailing lists, even when
      my posts are bug reports or answers to user questions. I have posted 2 training
      announcements to jboss-user, which I believe is appropriate usage for a list provided
      by sourceforge whose moderators
      frequently allow
      such announcements from a
      particular contributor. I certainly have not been trolling the jboss mailing lists
      like JBoss Group employees

      have trolled

      the Jetty lists.
    • Now it is not OK for an open source project to graphically link to
      another open source project because of trademarcs held by an
      individual
      and
      licensed to a particular service provider.

    I guess JBoss™ Group LLC have answered
    Rickards question
    on the server side on the use of trademarcs to control an open source project.

    I believe the jetty project has the moral and legal right to use that image. It is
    an open source image of a trademarc that has not been enforced, linking to
    a project that Jetty made significant contributions to and includes a fork of
    the Jetty code.

    But rights aside, I do not want to go against the wishes of a copyright holder.
    So I have removed the image from the Mort Bay pages and will start the process of
    removing them from the next Jetty releases and thus from the jetty pages.

    I have also responded to JBoss™ Group asking if Jetty could license the trademarc and
    asking what are the not-for-profit non-discriminatory licensing terms. So far the only
    response has been along the lines of: just take down the images or we will get legal on
    your arse. This is not good enough and I believe JBoss™ Group LLC owe the community
    a fair and open policy for the use of the name and image that they have contributed
    to. Something like a LinuxMark would be great.

    JBoss and JBoss Group are a registered trademark and servicemark of
    Marc Fleury
    under operation by The JBoss Group, LLC. All similarity between the terms free speech and
    free beer is purely coincidental. No copyrights have been harmed in the writing of this blog. Individual
    outrage may vary.

  • Project Oort – a cometd cluster

    Cometd Oort is extension to the jetty/java cometd server intended to provide a scalable comet cluster. Cometd Seti is an extension of Oort to enable the identification and location of connected users within an Oort cluster and the routing of messages to specific users.

    The jetty/java cometd server is itself highly scalable and can terminate 10s of thousands of cometd loads. However clusters are desirable for for many deployments either more simultaneous clients are required, message rates may limit the clients that can be supported per server or availability targets are such that multiple servers are required.

    The services that Oort provides include:

    • The discovery and connection of other Oort Comet servers.
    • The distribution of channels

    Once a cluster is established, use

  • Jetty and OSGI at Eclipse

    The last several months have brought a lot oof hangs with the jetty OSGI bits and piecesa of things at eclipse. We have finally standardized the way we distribute our binaries within our various p2 repositories. We have a honest to goodness WTP adaptor for jetty that people can use. We have contributed to both Helios and indigo and have had at least one of our other bundles picked up and contributed to another project (the junit pde testing bundle)
    First a bit about how we are distributing the bundles. Underneath the normal download location of http://download.eclipse.org/jetty we have the updates directory which has jetty-bundles-7.x and jetty-wtp underneath which are composite p2repositories. This location will be the standard place to consume our eclipse signed bundles from. There will be a jetty-bundles-8.x location once we iron out the source locations of the jsp-2.2 dependencies in jetty8. Underneath these top level composite p2repositories we have a development directory which is populated from the hudson.eclipse.org buld server. For the WTP bundles the development repository is being populated with each build. We do this in part so we are certain that our bundles are successfully making it through the whole eclipse signing and packing process. Since the velocity of change in these bundles are not extreme it seems minor to be doing the signing and packing process like is. The benefit is that once tested the development directory can be renamed into a proper version and added into the composite metadata.