Tuesday, March 30, 2010

Getting used to Java's Date and Calendar classes

Today I managed to complete the createBooking method of my BookingController. At least it runs without any errors. But the page that shows the week's bookings does not reflect the added booking. I spent quite a lot of time debugging my Calendar-related code. For a while I forgot that its MONTH field's index is zero-based, which caused me a lot of confusion. I was again tempted to start using Joda Time but I would like to refrain from adding too many dependencies. I would also have needed to add joda-time-hibernate and find/create property editors for setting up the Joda Time objects. Sure, this might have been something that would have taken like 15 minutes and worked perfectly, but it could also have led to unwanted trouble.

Anyway, when I was trying to see how far my BookingController was to working, I was doing some really painful manual testing. First I restarted Jetty, then I refreshed my main page, then I had to create a new user, then I went back to the main page, then I clicked the booking time I wanted, then I clicked submit on the form and then finally I would see an exception or error. Not very agile at all. The easiest way to start looking at what's wrong would be to run a separate hsqldb process which I could connect a DB client to and see if my requests have made any changes to the DB. But a better way would be to create a test case that calls my controller instead and then verifies that the expected changes have happened to the database. It would be even better to extract some stuff from my controller so I can test the url routing and form parsing separate from the database-related activities.

Sunday, March 28, 2010

Sorting out how to use Spring Security again

It had been a while since I read about Spring Security. Now that I was trying to create a new booking I had to retrieve the currently logged in user to be able to add the new booking to that user's bookings. So I thought I'd just slap a <global-method-security secured-annotation="enabled" /> in my application-security.xml and then add a @Secured("ROLE_USER") on my method that was mapped to ("/") and Spring should pop up a login form for me when accessing that URL. But unfortunately it didn't work that easily. The page showed up just like before, with no login form in sight. So I went back to reading the Spring Security manual and looking for some posts on Spring's forums and after a while I noticed that other people had solved similar problems by putting the global-method-security element in the same xml file as the one where they set up their Controller beans. Since I use the component-scan element to automatically instantiate my @Controller-annotated classes in my servletname-servlet.xml file, I thought I'd just move the global-method-security element to that file. At first I got a long spew of exceptions and call traces, but that was just related to some incorrectly configured xml namespaces. When I sorted that out Spring Security finally worked.

The exercise also straightened out one misconception I had about spring. I thought the DispatcherServlet's servletname-servlet.xml file created a new application context that was separate from the WebApplicationContext which Spring's context loader sets up. But then I found this in the Spring manual "In the web MVC framework, each DispatcherServlet has its own WebApplicationContext, which inherits all the beans already defined in the root WebApplicationContext." However I still don't understand why the DispatcherServlet context didn't inherit the global-method-security element from my WebApplicationContext which contained my security beans.

Saturday, March 27, 2010

Registering custom property editors with Spring MVC

Recently I've been able to concentrate much more on more normal coding tasks rather than just figuring out how to configure my application. I got to the point where I wanted to receive data entered and use that to automatically fill in property values for a business object. Fortunately Spring does have support for this. You just add a parameter of the type of your desired object and Spring will setup the properties based on their names from the encoded form values.

Spring has built-in support for conversion from Strings to a large variety of types. But if your business objects has a property of an unsupported type you need to register your own custom property editor that converts a String to that unsupported type. It took me a few tries to get it right but I seem to have gotten my custom editor set up properly now.

The mistakes I made were the following:

First I was trying to set up a CustomEditorConfigurer bean in my application context and use its customEditors property to map my class to an editor. Then I noticed that the customEditors property was deprecated in Spring 3. So I changed my setup to use a PropertyEditorRegistrar instead to register my custom property editor. This still didn't work. Then I figured out that if you just add these as beans in the application context they are probably only available for converting Strings inside that application context. If you want your property editors to be available for binding web requests to objects you need to use Spring's Controller's initBinder method to register your editor with a binder. And if you are using annotation-based controller you additionally need to use the @InitBinder annotation on that method.

Sunday, March 21, 2010

First screen shot


Finally started working more on the actual construction of views and models instead of just figuring out all the infrastructure. I have now added a table to the laundry booking system. The data for the model (times and dates) are automatically generated to show the current week. Tomorrow I'll work more on fixing the links to forms for creating actual bookings. The first version is going to be quite Web 1.0 so there will be page reloads for most actions. So I can spend all my time on working with Java EE instead of Javascript. However when I get far enough I plan to add some Javascript and try out jQuery.

Thursday, March 18, 2010

Finally got my whole Java EE stack completed

Ok just a quick update. Adding spring declarative transaction did the trick. I was now able to add a new user account through the a web form -> Spring Controller -> EntityManager and it shows up in my user list for testing purposes. I'm still gonna finish reading the Spring Transaction chapter and then I think I can finally start working on my domain model and then move on to the Controllers and views.

By the way. Annotation-based Spring MVC seems pretty good. There is a great deal of flexibility both in terms of what types of input your controller methods can take and what output they can return. Spring basically reads your thoughts and figures out what you wanted to do. Well not really, but it's very flexible. It almost feels a bit un-Java-like. Spring MVC with annotations basically fulfills the requirements that made me search for a rest-framework without the rest parts that I don't really care too much about when making a human-facing web application (such as content negotiation regarding different input and output formats, like json and xml.)

Settled on Spring MVC

Ok it wasn't as bad as I briefly anticipated to set up a url redirection scheme for getting nice URLs with Spring MVC. I found this nice answer on stackoverflow that actually linked to a sample MVC project in spring's repository that shows a really easy to use example of how to use the Tuckey url rewriting filter.

Firsty you simply map all your Spring MVC classes under a path like /controllers. Then you set up explicit redirects to all your subdirectories that contain static files like /javascript, /css and so on and anything that doesn't match that gets mapped to a url where the path starts with /controllers. After doing this I almost (but not quite yet) have figured out all the parts to be used in a simple web app. I was able to get my Spring-managed EntityManager injected and managed to get it to run some queries. But I still have to read the Spring manual chapter on transactions because I still don't feel like I know that well how they work yet. I could just follow a tutorial and just use the <tx:annotation-driven> element and annotate my classes and methods with @Transactional and everything would probably work. But like with all other technologies I've been learning for Java EE recently, I don't like using stuff without understanding how they work.

Monday, March 15, 2010

Frustration with java web frameworks

I've been delayed in doing any actual work on my first java EE web app because of web framework problems. I gave up on trying to get a definite answer on how @PersistenceContext works and thought I'd just try to see if I could get Jersey Resource backed by an EntityManager to work and output some hello world stuff. After correcting a few configuration mistakes I got some weird exceptions. I found some mailing list discussion that indicated that I was mixing different versions of spring modules. I was a bit surprised because I remember picking the 3.0.X version on all my modules. However it turned out that my jersey-spring integration library depended on a module called spring which was at version 2.5.6. Unfortunately Jersey doesn't have an IRC channel so I wasn't really able to verify if this was causing the problem.

So I did what I was trying to avoid doing. I tried switching to Spring MVC. I had understood it had support for "restful" URLs. After a while though I noticed that you are not supposed to use /* as the url-pattern for Spring's DispatcherServlet because the views are resolved through the DispatcherServlet. This means that if you try to redirect to /WEB-INF/jsp/myresource_show.jsp for example, DispatcherServlet will try to match that URL to a Controller. Since you probably haven't defined this as the mapping for a Controller you will get a No mapping found error. This also means that the DispatcherServlet will attempt to map all static files (images, css, javascript) to Controllers. This is probably because Spring isn't that different from Struts as I had hoped for, and it wants you to suffix actions with something silly like ".do". But I don't want to do that. Another solution is putting your resources in a special resources subdir and putting that as your url-pattern for DispatcherServlet. Alternatively you should be able to do create some sort of elaborate url-rewriting scheme. Uuugh. Why couldn't just jersey-spring play nicely?

Friday, March 12, 2010

Integrating a Spring application context with a web application

I think I finally figured it out last night. Most of the tutorials and documentation on using Spring's DI container seemed to only show to programmatically create an ApplicationContext by instantiating a subclass of it in a main method. So I was trying to figure out where you were supposed to do this in a web application. I had forgotten that you could use a ContextLoaderListener that would create an ApplicationContext (known as the root app context) from the xml files listed in an init-param in the web app context. But even when I rediscovered that, I had trouble figuring out if my Jersey Controllers were supposed to manually get beans from this root app context somehow.

So I spent a while browsing through various tutorials and the Spring documentation, and asked a lot of questions in the #spring IRC channel. At one point it eventually clicked and I figured out that most web frameworks need to provide some way of integrating with Spring, as opposed to this being completely standardized from Spring's side. The thing that made me figure this out was that I looked at how Spring MVC integrates with Spring beans and how Jersey integrates with Spring beans.

- Spring MVC has a DispatcherServlet that retrieves beans which extend Controller from an application context on the classpath that is named servletname-servlet.xml
- Jersey retrieves classes annotated with @Component from the root web app context
- Struts uses a Spring plugin that defines the application context file where the required Struts Actions are wired

And when I realized this, I noticed why I had been going about it the wrong way earlier when I was trying to figure out how to get the root web app context to manually get my beans from there. Although I also learned about Spring's WebApplicationContextUtils which would allow me to do that if needed.

Wednesday, March 10, 2010

Much progress with hibernate and JNDI with Jetty

Today I've been reading a lot about Hibernate and setting up JNDI objects in Jetty. I was trying to find out more about how to solve the problem of loading the same sample data set into an hsqld database every time I start Jetty.

At first I had planned to create a servletContextListener that would use DbUnit to import the data when the context is initialized. But since I am using Hibernate's hbm2ddl.auto option for automatically creating the database tables, I wanted to make sure the tables had been created by the time the servletContextListener is supposed to import the data into them.

The first step was to figure out how worked in servlet containers and specifically how to configure Jetty to create them. I set up an hsqld.DataSource and stored it in the InitialContext so it can be retrieved using JNDI. I also noticed you can get objects from JNDI Contexts in Spring's DI container.

Then I moved on to finding out what causes Hibernate to create the tables. First Persistence.createEntityManager(nameOfPersistenceContext) is called, which in turn causes a Hibernate SessionFactory to be created. This automatically exports schema DDL to the database when hbm2ddl.auto is true. Well I took a long break here and noticed that I have to continue with this tomorrow. I have to see if you are supposed to create some webapp-global objects in the servlet container itself or if Spring has some way to create beans that would be global for the servlet container.

Tuesday, March 9, 2010

Filling a database with some test data

I think I've got a decent understanding of Spring security now and would like to test that everything works. I need to figure out a way to put up a new database when running Jetty and put some rows into a user table. I am using hsqldb for the few small persistence tests I've written so far. I thought I would also use hsqldb for manually testing my application when it runs in Jetty. The Java EE-book I've read mentioned that you can use DbUnit to import data into a database from an XML file. But I think the main problem at the moment is that I have an inadequate understanding of hsqldb, so I'll have to start by learning more about that.

Friday, March 5, 2010

Learning about authentication

So now I have my Hibernate EntityManager working and a simple User entity that works. Jersey also seems to be working. The next step was thinking about user authentication. I've rolled my own user authentication earlier with PHP where I just had a simple salt and stored the password's hash, then when a user logs in his/her authorization-related details are stored in the session data. I could probably have translated this to Java but decided to look at some standard ways of doing it instead. So I did some internet detective work. The java EE-book I had been using mentioned Wicket's WASP (or maybe it was SWARM) system for authenticating users. WASP/SWARM also seemed to rely on acegi security so I googled for that and found out that it's now part of the Spring Framework as Spring Security. Then I watched a very nice introductory presentation video about Spring Security. It seems both easy to use and seems to be very flexible so I think I'm gonna go with Spring Security.

Choosing a Java EE Web framework

One of the things that has taken me the most time in making my first Java EE web app has been deciding on what web framework to use. I somehow neglected that maybe I would have gotten pretty far with just plain servlets in the beginning.

So one of the things you notice when looking at Java EE frameworks is that there seems to be a bit too many of them. This page lists about 60 in total. One of the first things I read about when learning Java EE was Struts 1 but after having gotten used to the idea of thinking about resources on the web, it felt slightly wrong to use a framework where URLs map to actions. Then I found out Struts 2 had a rest-plugin which I looked at, but the documentation was pretty poor and I couldn't really figure out how you would specify which controller "/", the root binds to. Later I found out about restlet and got interested in that. Then when reading about restlet I heard about Jersey which is the reference implementation of the JAX-RS (JSR-311 I think) which is the Java standard for making restful web applications. There doesn't seem to be any consensus about which of jersey and restlet is better as seen here. I think both are probably perfectly capable. At this momemnt I went with Jersey because it's planned to be a Java standard. I wouldn't mind trying out restlet in some other project later though.

Monday, March 1, 2010

Learning Java EE

During the last month I've been learning about Java EE. At first I was reading the free tutorials on coreservlets.com about subjects like servlets, struts, spring, hibernate and a bit about JSP.

After about 2-3 weeks I went to a bookstore to use a gift card I had received last year. I happened to find a Finnish book about Java EE-development which I bought. Buying the book turned out to be a good idea. Firstly I got to repeat a lot of the topics that I had read about the earlier weeks. Secondly the book was nice because it goes into almost all the necessary technologies for Java EE-development in the appropriate order in one place instead of me having to hunt around for tutorials online. Last but not least the book allowed me to catch up on a lot of Finnish programming terminology.