![]() | Java Persistence with
Hibernate
with Gavin King Manning Publications, 2006 841 pages (English) 703 pages (German) |
![]() | Hibernate in
Action
with Gavin King Manning Publications, 2004 408 pages (English) |
![]() | Unternehmen
im Internet
with I. Petzke, M. Mueller Oldenbourg, 1998 300 pages (German) |
I guess the biggest news item for Cling beta4 is the switch to LGPL. Figuring out what I want from Cling as a project and maybe in the future as a product took a while. I decided that the most important aspect is to get Cling into as many hands as possible, even OEM/ISV companies who want to include a UPnP library with their fresh Android hardware. The code should stay open, so the LGPL is the best choice to prevent closed forks. I don't want to buy an Android TV in half a year which runs my own (possibly modified) library and then realize that there's no way to get the source.
Other than the license change, there are a few bugfixes in
this release and unfortunately an API change which requires migration. One superfluous class
(DeviceService) had to go and you can just rip it out of your application code as well,
it shouldn't take you longer than 2 minutes.
I've updated the Android demo application as well, get the source code archive here and the APK you can install with your phone here.
I need a Java HTTP server/client framework for my next project. I have to work at a low-level first and integrate it with Cling, so I need access to raw HTTP messages, headers, entities, and so on. After that I need higher level abstractions and resources, so easy content negotiation, URI routing, and even XHTML representations (HATEOAS) are important. In fact, the last thing I need is a servlet container, and I absolutely do not want any WAR, deployment, classloader, web.xml stuff.
Here is my shortlist of projects which I'm evaluating:
Important factors that also come into play are: I need a WebDAV implementation and I'm fine with integrating Milton myself, however, if the HTTP framework provides it already or some extension points, that would be good. Secondly, I need something LGPL and GPL compatible, so Jersey is out. I'm going to switch Cling to LGPL with the next release, by the way.
Back to last week. I've now spent 10 days with Restlet and wrote a small integration project.
Restlet reminds me of Hibernate 0.8: It's a kind of middleware that I guess many developers need and many projects could benefit from. It avoids the established standardized approaches (Servlet, JAX-RS), so it might actually move faster and offer better features without legacy cruft and wasting time on TCKs and similar fun activities. I'd even say that REST/HTTP as a background is comparable to thinking within the Relational Model but working with SQL. There are a couple of dedicated developers behind it who try to make a living from supporting open source software. They are writing a book with Manning as a publisher, which would probably be the first book about their software.
Unfortunately, there are also similarities between Restlet and early Hibernate that are not all good. The Restlet website needs work. This is rather significant if you are trying to sell a web framework. Navigating the five or so different wiki sub-sections is awkward, you get lost all the time. The sparse documentation is just some randomly linked pages. Here is an excercise: There is a way to download the Restlet 1.1 and the 2.0 documentation in a single HTML or PDF document. Find the link.
Restlet documentation content is an issue. You have to read the Restlet code, you'll only find the most simple examples and "getting started" hints in the documentation. Restlet has an extensive and often convoluted API, for one simple task there are ten different possible solutions. If at all you will find an example for one or two of them, and you will never find an explanation why a particular approach should be preferred. Much of the API and usage is completely undocumented except for one-line Javadoc. The authors probably think that their Restlet in Action book will improve the documentation situation. I don't think it will. First, I've been reading the available chapters several times and I still don't know much more than before - show me more than one way to solve a problem, please. Secondly, you can of course improve an open source project's documentation with a book that goes into much more detail than the reference documentation of the software. But you absolutely have to provide good reference documentation! A book is not a substitute.
The Restlet community/collaboration setup should be simplified. The variety of mailinglists, archives, and forums is confusing and deterrent. You need to register with the extremely popular tigris.org website to subscribe to a mailinglist. You have to pray that when you post on the Restlet Nabble forum, an e-mail will be send to the right mailinglist (it worked a few times, now it's broken). You can't reply via e-mail to Nabble messages, someone forgot to finish the integration. My recommendation: Stop all of this, archive what you have, and start over with a straightforward and simple setup that requires no website registration for mailinglist subscription, and one forum for users. Considering the low traffic, I think a single Nabble forum/mailinglist would do just fine.
Hibernate 0.8 had one thing going for it that made all other concerns irrelevant: It worked immediately on my first evaluation test case. Back then, no other alternative even passed this simple test. I really wanted to believe that Restlet would be the same and that at least the software is great, even without documentation.
My results are mixed. Some features of Restlet could obviously be very nice, others are just not well thought out. This is by no means a complete evaluation of all aspects of Restlet! It's just what I experienced for my particular use cases.
I first tried to understand the concepts behind a Restlet Component, Application, Connector, and Resource. I don't agree with the separation of concerns between these artifacts but since this would lead to a rather longer design discussion, I'll accept that this is how the Restlet folks are interpreting Fielding's holy words. I definitely needed the Restlet in Action book for this, there is no other documentation about Component and Application.
Next I had to filter an HTTP request, read the headers and body, process it internally in Cling, and then
create and return a response. Or, let the request pass through the filter if it doesn't have the right
headers, etc. This was my first contact with the Router and Filter API. The Filter swallowed any
RuntimeException in the beforeHandle() method silently, fortunately that was fixed with the
released Restlet 2.0.0 last week.
Moving on to URI mapping with the Router: It took me at least an hour to get some very very simple requests routed properly, again suffering with no documentation. Then I had to read HTTP headers of a request, all of them. Oh, there is no API for that? In an HTTP/REST framework? You can't be serious... and making it the first question in your FAQ is really not the right solution.
I've tried to use the @Get, @Put, etc. annotations on interfaces, with
server-side implementation subclasses and automatically created client proxies. I understand that this
seems like a major feature but it is the minimum I expect today from a high-level HTTP framework. I
don't like the annotation design, @Get("xml") is not a good idea. This is
not a MIME type but another Restlet-owned mapping string which I have to look up in some Javadoc
(not in the @Get Javadoc no less). There is not much wrong with the JAX-RS annotations, this
looks like NIH.
Converting resource representations is another major feature I expect in a REST framework. I have a Java
instance and I want an XML document, or a JSON representation. A submitted HTML form shoud be available
as a multi-valued Java map. The Restlet converter service unfortunately looks like an afterthought and
from what I understand was even much improved in version 2.0. You still have to write two classes,
a ConverterService which will determine what conversion to use and a subclass of
ConverterHelper, which does the actual conversion. (Naming something
FoobarHelper is a sign that you should rethink what you are doing.) Note that this is one annotation and a simple
implementation of two methods in JAX-RS. I understand that Restlet gives you more flexibility over
content negotiation scoring, etc. but that should all be optional. I really don't want to
implement three slightly different "write this to string" methods for a single conversion.
So after a rather long while I had organized my Component, Application, Router, and Filter in such a way that requests could be processed. Next I wanted to write a Resource with negotiated content representation. One method should return an XHTML for browsers, the other method an XML representation for some other clients. It turns out that content negotiation is broken with anything but the built-in server connector.
I'm moving forward with the built-in server connector that is provided "not for production use". I
soon know why: Non-persistent HTTP connections from the JDK 1.6 HttpURLConnection are
timing out.
I've already decided that I can't continue at this point and I have to look for an alternative. But to
complete my evaluation, I want to at least write some unit tests to see how the mockups work.
Most of the Restlet artifacts, such as Request, Response, Form, etc. can be directly instantiated so that is nice for testing. With a bit of documentation, unit testing could be a strong side of Restlet, no messing around with fake WAR deployments, servlet contexts, and so on.
The project has potential and there is definitely a need for a comprehensive HTTP framework that offers flexible request routing, filtering, and content negotiation and marshalling. Go easy on the Component and Application stuff, people might not agree with how you think software should be organized. The big selling point beyond a plain JAX-RS implementation is most likely the client-side request and response handling. But when JAX-RS frameworks like RESTEasy and Wink already move in that direction, the space for Restlet gets smaller if it ignores JAX-RS. And, JAX-RS is really not that bad so if your project is pushing hard for an alternative approach, you need some absolute killer features. I haven't found them with Restlet in the last 10 days. My conclusion is that I'll have to look at alternatives and can't continue with Restlet at this time.
P.S. Putting new releases of Restlet only in a private Maven repository and making people wait 15 days for an udpate of the public repository is not a good way to make money with Free Software. It's a different story if your private repository provides an enhanced version, e.g. with extensive QA, certified, etc. I might be willing to pay for that extra value if I'm a corporation. I'm not going to pay you if I can drop the same unzipped JAR into my local repo with a single command, it's just inconvenient and developers don't like it.
It was a struggle but Cling finally works on Android platform level 7. I had to
rewrite all of the XML parsing routines because, and this is truly hard to believe, you can't even print an
org.w3c.Document graph into a string. There is no transformer on Android 2.1, only in platform 8.
The code that generates XML descriptors (the actual strings) is therefore really ugly and I will revert that as soon as 2.2 is more mainstream.
(Naturally, in 2.2 they added a SchemaFactory but it's broken, so now you can print your DOM but you still can't validate it. It's a good thing then that you can't validate UPnP descriptor XML with W3C schema anyway. Those MSFT geniuses sure were planning ahead.)
So now I'm able to run and test Cling on my Motorola Milestone with Android 2.1. I've updated the demo application (UPnP browser). Get the source code archive here and if you are feeling adventurous, you can install the app on your phone: Browse to http://teleal.org/projects/download/misc/ on your phone and click on the APK archive. After the download finished, click on the downloaded item which should bring up the installer.
Here is a video of the browser and the binary light service running on the phone, which I'm switching from the Workbench application on my desktop:
Alright, what's next then...