Greg Wilkins and Jan Bartel join me for a nice interview with JavaWorld’s Andrew Glover, particularly about Comet support and i-Jetty. Listen in! Podcast Link
Blog
-
Jetty at Eclipse Webcast Available
Greg’s excellent presentation is now posted in recorded form. Check it out, find out about Jetty’s relation with Eclipse, with OSGi, its continued availability under Apache license, asynchronous servlets and much, much more. Link to Eclipse
-
Jetty Webinar – 27 April
I’ll be giving a webinar on Jetty @ eclipse April 27 – 1:00 pm PDT / 4:00 pm EDT / 8:00 pm GMT.
The presentation will be a mixed bag of some project overview/status, some drill downs into some key features and some hopefully cool demonstrations.
For details visit http://live.eclipse.org/.
cheers
-
Jetty, JPL and the Mars Rovers
In what has to be one of the coolest ever uses of Jetty, JPL are using Jetty for missions operations planning on the Mars rovers!!!
Khawaja Shams from the JPL Operations Planning Software team dropped by the Webtide booth at EclipseCon and just blew us all away with this news. So now whenever I check on the rovers’ progress, I get a warm and fuzzy glow knowing that Jetty is helping this extraordinary mission succeed.
It seems to me that the longevity and success of the rover project is due to smart engineering based on well designed components – and that’s something that we continually strive for with Jetty. Our recent move to the Eclipse Foundation has already spurred us on to critically examine every jetty module, excise the cruft, streamline a few things and generally enhance our componentization for jetty-7.
To paraphrase Buzz Lightyear, for Jetty, its “to Mars … and Beyond!!!!”.
-
i-jetty Release 2.0
Release 2.0 of Jetty for Android (i-jetty) is now available in src and binary form from
i-jetty downloads.
This release is the first to also be available (for free) on the Android Marketplace.
To download from the Marketplace, you’ll need to have an Android handset. You’ll find i-jetty under the Applications category in the Communication subcategory.
If you’re using the emulator from the SDK, then you should download thei-jetty-2.0-final-signed.apk
bundle from i-jetty downloads.
In this release, we support Androidsdk 1.1_r1andjetty-6.1.16. We’ve moved to using a combination of json, javascript and xhr for rendering the Console webapp rather than generating html. We’ve also improved the contacts management part of the Console webapp, allowing you to upload an image for a contact, as well as edit all their phone numbers, addresses etc. A new feature in this release is the ability to view your images and video and listen to the music stored on your phone via your desktop browser. We’ll be adding more functionality to the new media serving feature next release around.
Speaking of the next release, I’ll be doing some testing of the newly available SDK 1.5 preview to establish whether or not it fixes some of the outstanding android issues that have been bugging i-jetty, like the Bundle resource problem and the dalvik cache problem which have prevented dynamically downloaded webapps from running on a real handset. I hope to have some info on these two issues in the next couple of days. -
Google AppEngine uses Jetty!
Hot on the heels of Google Widget Toolkit(GWT) switching to Jetty, the little server that can has received some more Google luv’n! Google’s new App Engine Java service is powered by Jetty! With App Engine, you can build web applications using standard Java
technologies and run them on Google’s scalable infrastructure.
Initially it is a little difficult to see Jetty in use, but you can see the jetty classes in the SDK download and if your application throws an exception then investigation of the stack trace in the log reveals the Jetty servlet container is used.
Not only that, the stack trace and other documentation show that Google have really exploited the embeddablility and extensibility of Jetty at a number of levels:- They are using their own RPC style connector to receive requests from their front end web servers.
- They use the google account authentication as the only supported authentication mechanism.
- The HTTP sessions are clustered via the database or memcache
- There is an appengine-web.xml configuration file
- Jetty is embedded in their SDK and eclipse development plugin.
Thus Google have plugged in many new and/or extended components in a way that validates our open, component based architecture. When it comes to application servers we do not believe that one size fits all and strongly encourage such customization for purpose.
We are really pleased that the google App team picked Jetty for their hosting service and welcome them to the ever growing list of Jetty powered projects!
The revealing exception:
javax.servlet.ServletException: This is an exception at com.acme.HelloWorld.doGet(HelloWorld.java:48) at javax.servlet.http.HttpServlet.service(HttpServlet.java:689) at javax.servlet.http.HttpServlet.service(HttpServlet.java:802) at org.mortbay.jetty.servlet.ServletHolder$SingleThreadedWrapper.service(ServletHolder.java:617) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093) at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405) at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:237) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139) at org.mortbay.jetty.Server.handle(Server.java:313) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506) at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:830) at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:63) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381) at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:125) at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:235) at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4547) at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4545) at com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24) at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:359) at com.google.net.rpc.impl.Server$2.run(Server.java:792) at com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56) at com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:489) at com.google.net.rpc.impl.Server.startRpc(Server.java:748) at com.google.net.rpc.impl.Server.processRequest(Server.java:340) at com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.java:422) at com.google.net.rpc.impl.RpcConnection.parseMessages(RpcConnection.java:319) at com.google.net.rpc.impl.RpcConnection.dataReceived(RpcConnection.java:290) at com.google.net.async.Connection.handleReadEvent(Connection.java:419) at com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:733) at com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207) at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:101) at com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:249) at com.google.apphosting.runtime.JavaRuntime$RpcRunnable.run(JavaRuntime.java:373) at java.lang.Thread.run(Unknown Source)
Edited 11 Apr 2009:
In response to the questions about continuations, we found this discussion on the google app engine forums, which says:“We do not support continuations. All requests need to complete their work within the ~30 second deadline and then return control back to App Engine. There is not currently any support for chunked transfer encodings, hanging gets, or background processing, so continuations would not be very useful.”
This is interesting, but we’d like to feedback to google that there are plenty of interesting uses for continuations that do not need waits longer than 30 seconds, background processing or chunked responses:
- We encourage the use of long polling techniques that always send complete responses and thus don’t need chunking etc.
- In many cases, background processing is not needed. Suspended requests can be resumed by other requests (eg chat, auctions, collaborative editing etc.) or even other responses completing (eg quality of service filter).
- For interactive web applications, having a long poll of 20s will still give great latency and throughput advantages over a more frequent polling solution.
Now it maybe that Googles RPC connector cannot operate asynchronously, so they are forced to have a thread allocated. If that is the case, then they should talk to us and we’d be please to teach them how to better scale their infrastructure (we also specialize in teaching egg sucking 🙂
-
Jetty @ Eclipse – Jetty7 and Jetty8 (and Jetty6)
I have had a lot of inquiries about what is going on with the latest versions of jetty being talked about and what they mean to our users so I figured I would give clearing it up a shot.
Greg has recently updated the about page on the jetty eclipse site with some very handy historical (and bleeding edge current) information. Throughout the history of java, jetty has been somewhat a fixture as you can see in the table below, paying particular attention to the rather amusing Status column.Version Home Java HTTP Servlet JSP Status 8.x Eclipse,
Codehaus1.6 HTTP/1.1
RFC26163.0 2.1 Experimental 7.x Eclipse,
Codehaus1.5,
J2ME CLDCHTTP/1.1
RFC26162.5 2.1 Stabilizing Jetty-6.x Codehaus 1.4-1.5 HTTP/1.1
RFC26162.5 2.0 Stable Jetty-5.x Sourceforge 1.2-1.5 HTTP/1.1
RFC26162.4 2.0 Mature Jetty-4.x Sourceforge 1.2 HTTP/1.1
RFC26162.3 1.2 Ancient Jetty-3.x Sourceforge 1.2 HTTP/1.1
RFC20682.2 1.1 Fossilized Jetty-2.x Mortbay 1.1 HTTP/1.0
RFC19452.1 1.0 Legendary Jetty-1.0 Mortbay 1.0 HTTP/1.0
RFC1945Mythical What we see is that jetty has done a pretty solid of performing its major version updates with the updating of the servlet specification, also updating the JDK and JSP versions accordingly. Jetty was well on that track with version 7.0 previously being the first pre-releases of jetty with support for the servlet 3.0 specification, but that has been derailed a bit with the move to eclipse coupled with the postponing of the servlet 3.0 spec until at least the September time frame. Jetty7 has been under development for going on a year next month and it is hardly fair to delay the release of jetty7 and all of the work that has gone on with it until the latter part of the year, much less hold off on released eclipse jetty bundles that long. Jetty pre-release artifacts have been available for a long time and we have been unable to start the release process on it at all because we have been chasing the updated servlet spec. Now that the core of jetty is at Eclipse we need to start the jetty release process as soon as possible to get a stable release available for our users that contains all of the latest and greatest improvements to both packaging and code.
We have taken the opportunity to reorganize the packaging of jetty a bit in the migration of jetty to eclipse and the culmination of these changes are available in the first of our jetty milestone releases 7.0.0.M0 which went out last week. Two of the primary changes from previous jetty7 pre-releases are the package changes and the artifact decomposition. The packaging changes consisted of the obvious org.mortbay -> org.eclipse changes but also include the alignment of maven artifact and java package references. Whereas before in jetty6 the org.mortbay.jetty:jetty-util package may have included classes in org.mortbay.component, org.mortbay.thread and org.mortbay.util packages in jetty7 and future versions of jetty will adhere to the convention of all classes in the org.eclipse.jetty:jetty-util artifact being nested under org.eclipse.util package space. This makes using the existing osgi maven tooling ever so much easier to work with and allows us to work in osgi classloaders without a lot of jury-rigging. In fact we were able to pull out the majority of the custom configuration on the org.apache.felix:maven-bundle-plugin and use the default configuration.
We were also able to wire in generic support for version ranges in the Import-Package: and Export-Package: manifest entries such that the bundles are automatically configured for [7.0,8) which should allow us better future support for working in osgi and eclipse (more on this in a future post covering the osgi http service and some jetty eclipse plugins I have been working on).
As to the artifact decomposition I mentioned, this has to do with cleaning up the transitive dependencies for the using jetty. Jetty is not simply a http server with servlet engine, we also have a robust jetty-client implementation that leverages the solid async implementation under the covers of the jetty server (the soup that lets jetty server scale up to 20k connections). The origin of the client was simple, we needed something on the client side that we could scale up to levels needed to test the server, so jetty-client was born. It is now being used in many interesting places, from proxy server setups to backing the artifact downloads within the maven mercury project. Anyway, the interesting annoyance the was in jetty6 regarding the jetty-client was that it has dependencies on the jetty-server and the servlet-api. Which makes sense given its origins, but was still bothersome to take on another few hundred k of dependencies when all you wanted to use was the client. This has been addressed by the creation of the jetty-io and jetty-http artifacts in jetty7 at eclipse which are shared dependencies of both the jetty-client and the jetty-server and the servlet-api is not longer a dependency of the client. Pretty straight forward stuff but still very important.
If you are one of the people that has been tracking the development of the org.mortbay flavor of jetty7, the jetty7 that is located at eclipse should not be fearful as the changes are not overwhelmingly complex at all. Most of the porting work I have done module wise is taken care of in literally minutes and if you have dependencies on the servlet 3.0 api then jetty8 will be addressing those issues in short order. Jetty7 and Jetty8 will be fundamentally the same codebases with jetty8 containing a thin layer of implementation for the servlet 3.0 api changes on top of the already stable jetty7 core codebase. Jetty7 has been stable and ready to being the release process for literally months while we anticipated the move to eclipse and its packaging changes and the release of the servlet 3.0 api. The only thing holding us back on its release has been the eclipse move and the servlet spec release, heck our plans had originally been to release 7.0 on the day of or the day after the 3.0 spec was released anyway. So now we are in the position to get jetty7 released with the servlet 2.5 support that has been supported since its inception last spring and allow our users to start the process of migrating to the latest stable codebase without the rush to support servlet 3.0 spec.
In addition the forthcoming jetty8 milestone or pre-releases will be taking the place of the jetty7 pre-releases that previously allowed intrepid folks the ability to work with the developing servlet 3.0 api.
Lastly, now that jetty7 and jetty8 are announced and the path for their release should be clearer to all we will start shifting the jetty6 codebase towards a slower maintenance release cycle as we focus on getting jetty7 into the stable category on the chart above. Maybe then we can update the about page again and make jetty5 ‘venerable’ or ‘respected’ and jetty6 ‘mature’. -
Jetty @ Eclipse – 7.0.0.M0
I am pleased to announce the availability of the first milestone build of jetty7 @ eclipse!
Download Jetty 7.0.0.M0!
It has been a crazy few weeks getting all of this together but it finally happened and we crossed a big initial hurdle in our efforts to move through incubation. We are still in the parallel ip verification process which is proceeding well, as expected. The process of getting accustomed to bugzilla and the eclipse infrastructure is also chugging along and as our milestone builds progress we will slowly enable more functionality to the eclipse community. Things like update sites and increased support for osgi are all coming over the next months.
Best make one quick note in case folks are not aware, with the delaying of the servlet 3.0 spec we are altering the development path for jetty7 and dropping support for the 3.0 api and instead jetty7 is the initial release of jetty that has org.eclipse package changes, a base jdk requirement of java5 and other improvements that you will hear about as they crop up. Jetty8 will be the first version of jetty that will support the servlet 3.0 api and builds of that will be available as well soon.
Lastly, I would like to give a quick thanks to the folks within the Eclipse Foundation that have helped us immeasurably to get to this point.
[edit]
I would be remiss to not note to our maven brethren that the location of jetty artifacts has changed within the central maven repository.Maintenance releases of Jetty6 will still remain in the org/mortbay/jetty location within the central repository. In fact jetty 6.1.16 was released today and is available.
-
Maven, m2e and the Nexus Repository manager
Jetty-7 is moving to eclipse, cometd-java is moving from jetty to
cometd.org and the maven build system for dojo has been moved out of
the main dojo tree. So I’m involved in some major refactoring of
three interdependent projects at the same time. This refactoring
would be impossible to contemplate without the tools support for
these projects. Maven, m2e and nexus are making my life a lot easier.Maven
Apache Maven
is a build tool of the -
Property substitution in web.xml and the Jetty Plugin
Many web applications are configured via web.xml.
Primary examples of this are Comet web application, which are configured via a
ServletContextAttributeListener: you may want different listener classes depending on the enviroment you’re working in.Another example is where Spring configuration files are provided via the
contextConfigLocationcontext parameter.Here I want to show how to do property substitution in web.xml based on Maven2 profiles.
Let’s start from the case where you don’t need property substitution.
These are your web.xml and pom.xml files:// web.xml <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <listener> <listener-class>com.acme.CometInitializer</listener-class> </listener> </webapp> // pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <build> <plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.15</version> <configuration> <scanIntervalSeconds>10</scanIntervalSeconds> <connectors> <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> <port>8080</port> </connector> </connectors> <webAppConfig> <contextPath>/</contextPath> </webAppConfig> </configuration> </plugin> </plugins> </build> </project>
As you can see, the pom.xml file specifies the Jetty plugin configuration, with no particular configuration needed: default values are good.
The web.xml file specifies a listener class that initializes your Comet web application.Often times, however, you want your initializer to configure the application differently, for example by stubbing some functionality; as the initializer is complex, you write a different class.
At this point, you want to be able to specify a Maven2 profile that modifies the web.xml with the suitable class (default or stubbed).
Here’s how you do it:// web.xml <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <listener> <listener-class>${initializer.class}</listener-class> (1) </listener> </webapp> // pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <build> <resources> (2) <resource> <directory>${basedir}/src/main/resources</directory> </resource> <resource> <directory>${basedir}/src/main/webapp/WEB-INF</directory> <includes> <include>web.xml</include> </includes> <filtering>true</filtering> <targetPath>${project.build.directory}</targetPath> </resource> </resources> <plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.15</version> <configuration> <scanIntervalSeconds>10</scanIntervalSeconds> <connectors> <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> <port>8080</port> </connector> </connectors> <webXml>${project.build.directory}/web.xml</webXml> (3) <webAppConfig> <contextPath>/</contextPath> </webAppConfig> </configuration> </plugin> <plugin> (4) <artifactId>maven-war-plugin</artifactId> <configuration> <webXml>${project.build.directory}/web.xml</webXml> </configuration> </plugin> </plugins> </build> <profiles> (5) <profile> <id>default</id> <activation> <activeByDefault>true</activeByDefault> </activation> <build> <filters> <filter>${basedir}/src/main/filters/default.properties</filter> </filters> </build> </profile> <profile> <id>stubs</id> <build> <filters> <filter>${basedir}/src/main/filters/stubbed.properties</filter> </filters> </build> </profile> </profiles> </project> // default.properties initializer.class=com.acme.CometInitializer // stubbed.properties initializer.class=com.acme.CometStubbedInitializerLet’s review the changes step by step.
- We replaced the listener class with a property in the web.xml file.
- We added a
resourcessection in the pom.xml file to reference both the standard resource location and the web.xml file.
For the web.xml file we specified that the property-substituted version of the file must go in the standard maven output directory (by default${basedir}/target, referenced as${project.build.directory}). - We added the
<webXml>element in the Jetty plugin configuration, referencing the property-substituted version of web.xml. - We added the configuration for the war plugin, so that building the war will reference the property-substituted version of web.xml.
- We created two profiles that reference different filter files, which will contain the property values to be substituted. The standard Maven2 location for filter files is
src/main/filters.
Now you can build your project as before by specifying the profile if you need the stubbed version, like this:
// Normal build $ mvn clean install // Stubbed build $ mvn -Pstubbed clean install // Stubbed build with Jetty plugin $ mvn -Pstubbed jetty:run
Enjoy !