Spring Web Services seems to be the technology I have been looking for recently. I am not a Spring bigot (too XML oriented), but here the Spring folks have something right.
I used to work with Web Services the simple way: create a java class (or EJB), expose it as Web Service through Axis or RAD, generating the WSDL in the process. And then a client would just be the reverse, take the WSDL, use a tool (Axis or RAD) that creates client Java classes from it automatically. Simple, easy.
But this process starts to fail if you have:
several very similar WSDL: you want reuse instead of copy.
other means of communicating XML represented by the XML schema embedded in the WSDL, for example via direct MQ use.
In those cases, the contract first approach is particularly interesting. However most tools, if they allow contract first approach, they don’t give you enough access on the message itself, and you can do 1), but not 2). I always found a bit silly that Axis or RAD had to have the logic to marshall/unmarshall java objects, but they did not give any explicit API access to do it, or to replace it with a standard way (JAXB 2 for example).
I found 2 techs that can help:
SDOs (Service Data Objects): from my short experience, I find it a bit too verbose, and not yet fully mature, as you depend on libraries external to SDO ones for it to work in the case of web services. It can work, and if you use IBM products, it could be a good way to write Web Services Providers/Clients.
Spring Web Services: I have not tried it yet, but it seems to solve exactly the kind of problems I described earlier. And you can plug-in any marshalling/unmarshalling framework you want :).
There are so many libraries to do web services, and different approaches, that an initiative like Spring Web Services is more than welcome!
After seeing Scala had elements of Erlang through Actors, I decided to take a closer look at the language. There is an interesting new web framework in Scala, called Lift. One drawback of Lift is that it seems to be very cutting edge and not that easy to grasp. While reading its source code, I stumbled upon a strange pattern:
Storing the ServletRequest in a ThreadLocal.
I had not seen that before, and was wondering why one would do such a thing. It seems to be unintuitive. I found my answer through… GWT widgets. In this page, the author explain motivations behind doing such a thing:
While not 100% in tune with the MVC pattern, it is often convenient to access the servlet container, the HTTP session or the current HTTP request from the business layer. The GWT-SL provides several strategies to achieve this which pose a compromise in the amount of configuration required to set up and the class dependencies introduced to the business code.
The easiest way to obtain the current HTTP request is by using the ServletUtils class which provides convenience methods for accessing the HttpServletRequest and HttpServletResponse instances. Please note that it makes use of thread local variables and will obviously not return correct values if used in any other than the invoking thread.
Still one can doubt if this is good design. In my long experience of web apps in Java I never had the need to do such a thing. Have you seen that pattern before?
Initially I adopted Eclipse instead of Emacs because it was more powerful to search code, and it allowed refactoring. I regularly tried other IDEs but always end up back to Eclipse, even though there has been less big improvements in Eclipse in the past years (but lots of small ones).
I just saw today that Eclipse allowed programmatic refactoring. Now that’s something quite amazing, and I don’t think other IDEs do that yet. Someone even had fun writing an Eclipse extension in Scala to add a particular kind of refactoring to Eclipse.
Getting started with Tapestry 5 is easier than with Wicket 1.3. Some readers will complain that it is again the view of someone who has no deep knowledge of either Tapestry or Wicket. But I think it is important for projects to be easily accessible to developers. Wicket seems to have more buzz around these days, and has a detailed wiki with plenty of useful information in it. But that's the problem I see with Wicket, it is not simple to do simple things, that is why there is so much information to do simple things in the Wicket wiki.
Granted my test was based on a specific case for component frameworks, I was not so much interested into statefulness, I wanted to display a bookmarkable "user page" with content coming from hibernate.This kind of behaviour is quite general in web applications, especially in web 2.0.
It was relatively easy to have the page working with Wicket, although I was disappointed at their hibernate integration. Hibernate integration in wicket means either using the full databinder project, or creating your own solution. I chose the later based on source code from databinder, but I actually rewrote everything in the end. I was disappointed that databinder, a specific Hibernate oriented framework did not really handle Hibernate sessions the simplest way possible. Tapestry5 got that right. To manage Hibernate sessions right, I had to dwelve into Wicket code as no documentation offers insight about inner workings of wicket. The code was too complex for my taste. In my short experience, I saw it seemed the developers are changing it to the better, removing some unnecessary abstractions.
In the end I got frustrated many times with Wicket, and did not manage to have a bookmarkable page the way I wanted. You can have a bookmarkable page, but after some action on the page, it would become unbookmarkable. Furthermore, the structure of the URL is not very flexible without yourself rewriting completely the bookmarkable page feature of Wicket.
With Tapestry5, I was at first worried about the small amount of documentation on the site, the use of maven in the tutorial. I was wrong, documentation proved to be exactly what I needed, and detailed enough. It is much easier to understand how Tapestry5 works after reading the doc than Wicket. Concepts in Tapestry5 are simpler and more powerful. Maven use is in the end not that big of a deal, I am still not as comfortable with it but I am productive enough that it is not an issue, much more productive than with Wicket. The standard tutorial setup is a very good one.
Doing a bookmarkable page was trivial, it also was easy to have the format i wanted, and it was kept after action in the location bar. Hibernate integration was trivial, since Tapestry5 provides the tapestry-hibernate module, a few classes that helps managing the session and transactions for you. The only drawback is maybe the yet another inversion control system to learn. Tapestry5 IoC is very near from Guice in its philosophy. I wish Guice was made the default for IoC in Tapestry5.
To conclude, there is no doubt about it, Tapestry5 is the winner.
I just found it while browsing netbeans website, here is the link. Netbeans is starting to be much more interesting that it used to be before 5.5, even though shortcuts are a pain, because so different from most other editors, and not always defined for important tasks. I like the all integrated feeling without plugin and slugishness by default.
This is not something I would have though a few years ago. It is something I learnt after working on many different projects, some using an ORM layer like Hibernate, Entity EJBs, or JDO, some using JDBC approach via Spring Templates or custom frameworks. Many projects that use ORM have performance problems, that don't seem that common with projects using JDBC. But the size of the database model of ORM projects is often much bigger than the one of JDBC projects (which actually makes sense). If you have only a few queries to do, why bother with ORM? This would be complexity for nothing.
But for most enterprise projects, the size of the database model is quite big, and the model itself can be complex (many relations between many tables). With this kind of model, ORM is more efficient. It is faster to develop with, creates less bugs due to string misspelled, or types badly read. It is also better performing. Doing 1 giant query to retrieve everything in 1 step is not faster, especially if you don't always need all the information retrieved. In a complex model, many cases are specifics, only useful in 10% of the cases. The temptation is high with a JDBC approach to do one giant query, because it is substantially longer (and more work) to do N queries. With ORM, it is a bit the opposite, by default N queries is easier to do. The problem is that N(ORM) tends to be very high if one is not careful with the mapping to avoid the N+1 problem. However it is simpler to reduce the number of queries by joining tables, rather than splitting queries, ORM performance optimization feels more natural.
Martin Fowler tends to be also pro ORM in its "Domain Logic and SQL" article. He also mentions something interesting about SQL query optimization:
It's also worth pointing out that this example is one that plays to a database's strengths. Many queries don't have the strong elements of selection and aggregation that this one does, and won't show such a performance change. In addition multi-user scenarios often cause surprising changes to the way queries behave, so real profiling has to be done under a realistic multi-user load. You may find that locking issues outweigh anything you can get by faster individual queries.
In the end it is up to us to make ORM or JDBC approach perform. JDBC provides much more direct access to database, and in benchmarks (always simple database models) or in theory it should be faster. But in the real world, I argue that ORM optimization is simpler and therefore, often ORM projects will perform better.
I recently found a bug in software we are developing. I traced it and found the root was improper JDBC handling. The application is written using EJBs, Spring and plenty of other relatively complex technologies. I was surprised that developers who were able to use all those technologies had no understanding of basic JDBC.
They fetched all the data (including double, decimal numbers) from the database as String using rs.getString() !
While this is most of the time possible, it is also most of the time not desirable (in the code they were actually converting it to numbers, etc.). More importantly, this can lead to nasty bugs due to different Locales (the . vs , game for example). And this is what’s happening in our application.
IBM RAD comes with many wizards, to create EJBs, to create Web Services, do struts mapping… They are quite well done, making EJB < 3.0 usable, and Web Services look simple.
But wizards sucks at:
typos correction
repetition
But when you do a typo in your wizards, then all the files generated/changed are wrong, and you don’t necessarily know if you can just do a search and replace. Plus you don’t necessarily know all the files that were affected by the typo.
In RAD, there is even a wizard to help you create a JSP. What does it do? Well, for example it generates those 2-3 lines of tag libraries include. The first time you write a JSP, it might help you, but the second time, it’s much faster to copy/paste. Generally, when you have to do an wizard operation many times, it is much slower than doing it via copy/paste and few modifications here and there, or to use a more configurable alternative like XDoclets.
The other complaint I have about wizards, is that they hide too much how things are working. As anybody can use them, it makes you think the operation it does and technologies behind are simple.
More generally it feels to me like wizards are only there because of some over-complicated design somewhere. EJB 3.0 are much nicer to work with than EJB 2, a wizard will help you much less with EJB 3.0, and yet EJB 3.0 are more powerful.
My first trials of Maven were failures. As I am stubborn, I tried again, on a new project, a quite simple one. It works, but it makes some easy things overkill. And the default way of using it makes a developer lose lots of time.
If I have a project with common classes, a standalone app, and a web app, then logically you do 3 projects, 2 of them depending on the common one. That’s how the default maven setup works, and that’s what their documentation presents. Now when using maven eclipse, this will create 3 project, none depending on each other. If you modify something in the common code, it won’t be seen by any of the other code, you have to publish it with maven first, this takes way too much time. Furthermore I did not see any way to force rebuild the common automatically from one of the other project. If you modify code in common and web app project, you need to call maven twice. I find all this very counterproductive, because you do those steps extremely often. Now there are probably some ways to do that with Maven2, but it is not the default behavior. I could add project dependencies in eclipse manually, and forget about maven while working in eclipse, but then the maven eclipse plugin is really useless. And you’ll face the same issues when you want to use maven tomcat deploy.
Even more worrying, after moving back to Ant, I saw a strange bug with Spring context loading disappear. Maven is hiding so much, that it becomes not obvious how your app is deployed.
Developers lose power with Maven. It’s a pain to do something a bit differently that the default Maven way. With Ant, people gain power. I see both as being the distinction between a framework approach (Maven) and a library API approach (Ant). By default, Maven tries to do a lot, while Ant tries to do nothing. It’s very easy to build exactly what you need with Ant, while it is of course difficult with Maven.
Some parts of Spring have a similar disadvantage to Maven. If you do everything in XML with the most Spring magic, you’ll spend hours trying to figure out how to do things and why it does not seem to work like you think it should. If you use Spring as an API, like the wonderful Spring JDBC, development will be fast (faster than with straight JDBC for example), and your program flow is easy to follow.