Showing posts with label spring. Show all posts
Showing posts with label spring. Show all posts

Sunday, February 24, 2008

TDD Gone Wrong

Last time I wrote about TDD. I read this article from some guy at Spring about doing TDD with the Google Web Toolkit. I have to say this is a good example of how TDD zeal can lead to some twisted thinking.

The article starts by point out how GWT enables RIA development in pure Java. That's a good thing. He then talks about some of the difficulties he's experienced trying to write unit tests for GWT widgets and concludes:

views are usually very hard to test, therefore they should know and do as little as possible ... Most of the GWT code has pretty much all the logic in widgets, so most developers using GWT extend a widget and just add some more logic. My advice is simple: don't go there.

RIAs are all about putting lots of logic in your view. Now it's not just any logic, but view logic. You see there is logic involved in creating a rich user interface and the place for that logic is the user interface. So this guy's obsession with testing has led him to the conclusion that you should dumb down your view code so you can test it. This completely defeats the purpose of using GWT. Very sad.

I think the author does bring up some valid points on unit testing GWT. If you place a huge importance on unit test coverage, then the more logical conclusion is that you should not use GWT. Don't try to dumb down the technology so that you can sleep better at night. Just pick a different technology.

Monday, May 14, 2007

Interceptors vs. AOP

One of the subtle but interesting things that Gavin King said last week at the Web Beans session at JavaOne was how AOP is overkill for most things. He said that Web Beans will support a rich interceptor model (take a look at Hibernate's for an example,) but no built-in AOP. He described AOP as a massive programming solution that is often inappropriately used to solve simple problems. That got me thinking.

We used AOP a lot at Ludi Labs. We were using Spring AOP. I started thinking, could we have use an interceptor pattern as a replacement for AOP? First off, the only reason I would even go down this line of thinking was because AOP presented some problems for us at Ludi. There were the annoying-but-trivial problems such as bloated logs and obfuscated stack traces. There were much more significant problems around performance.

Let's take a concrete example. Any time we store data, there was some "boilerplate" metadata we would store as well. For new data, this would be things like creation time and created by. For updates to existing data, it would be things like update time and updated by. Everyone stores this stuff, and often do it via database table definitions or even database triggers. We weren't storing our data in a traditional database, so we couldn't rely on those common solutions to this problem. Enter AOP.

We created advice for adding this metadata. We were storing user information in a thread local that could be accessed via an injectable stateless service. So it was easy to write advice that could figure out the created or updated info, and it was easy to write a pointcut to specify when to apply this advice.

Obviously this could have been done with an interceptor. But wait, there's more. Once we had this advice in place, there was more boilerplate stuff we wanted to keep track of. For any object we had some common metadata that could be applied to it. This included related objects (for example we could have a jpeg that was the cover art for an mp3,) user comments, and typical web 2.0 tags. We maintained all this together in an atomic object, but that could imply a lot of baggage to pass around.

So we added advice to disconnect this metadata when an object was read. We then re-used the previous advice to re-attach the metadata when the object was being written.

Again, this would have been easy to accomplish with an interceptor as well. There's one more wrinkle. The above metadata could be altered, and everything still worked. For example, an extra comment could be added by one person while somebody else was changing the description of a photo. This just wound up being more advice to write, no big deal.

So is this easy with an interceptor as well? I think this one could be a little trickier. Before we had a clear event in our component lifecycle: updating object data (say the title of a photo.) Now we're updating its data still (adding a comment) but it's data we want to manage separately even though it's persisted in the same data structure. If we are using the same component model, we probably need some kind of bifurcation of logic since these will be the same events. I guess the more OO way to do thing would be to model the events in the component model explicitly, i.e. something like saveData() and saveMetadata() not just save(). Or you could move your interceptor up the stack to distinguish when between these events. That's what would correspond more to the AOP way: define your point cut higher up.

The nice thing with AOP is that you don't have to change any component code to handle this refinement. It's that extra flexibility from having "a huge software solution." If you're able to plan out your needs ahead of time, then interceptors are fine.

This brings up the other bad part of interceptors. Take a look at the Interceptor interface in Hibernate. It has 15 methods. Of course there's the concrete class EmptyInterceptor which provides empty implementations of all 15, so you can extend it and only implement what you need. That's still ugly. You can imagine introducing interceptors on your own components, and then constantly having to expand the interceptor interface and any corresponding helper classes for it.

Thursday, May 03, 2007

Guice, Spring, and Arid

I was reading this article on Arid POJOs on TSS today. Chris Richardson, the author of Arid, has a nice introduction to it. One thing I found amusing was the statement at the beginning
...an important benefit of using XML is that it completely decouples the components that are being assembled from the mechanism that is assembling them This is not true when using annotation-based dependency injection such as that provided by the Guice framework. Components that use those kinds of annotations are tightly coupled to the framework and are definitely not POJOs!
I've been known to make my own digs on Google frameworks, but sometimes you have to call out FUD when you see it. The POJO argument usually comes from the requirements of writing EJBs prior to EJB3. You had a lot of interfaces to implement, and some of these interfaces required a lot of methods (typically lifecycle callback methods) to implement. To be an EJB you had to look like an EJB to the container, hence all those interfaces and methods to implement. The term POJO came about because POJOs don't look like EJBs.

So it is ridiculous to somehow say that a class that uses a com.google.inject (or javax.ejb for that matter) Annotation is not a POJO. Can a POJO not have any Annotations? Can a POJO not reference third party packages? Better remove all your Jakarta commons import statements...

As for tightly coupling to a framework, I will concede that it is nice to be able to switch out your DI provider without having to change code. I guess that is one drawback of using Guice. The Guice solution of writing a Module class for doing all the wiring and thus isolate the dependency doesn't seem realistic. You could do the same thing in Spring: programmatically create your configuration and thus wire together your classes. Nobody does that though, they all use XML files or maybe auto-wiring.

So maybe Chris Richardson has a valid point here. Bob Lee and the Guice gang at Google make some strong arguments for switching to Guice from Spring. You have to change code to make that switch, and you'd have to change code again to switch back.

I think in many cases, it is worth the "pollution" of your code. The thing I like about EJB3 and Guice annotations is the explicit dependencies. I have to worry about not only writing code, but also about writing code that other developers can understand. I have to worry about the learning curve I create for new developers I hire. There is a lot of clarity in something like:

@ImplementedBy(MyClassImpl.class)
public interface MyClass { ... }

There is also a lot of clarity in seeing a unit test that creates a module to override the bindings to allow for mock versions of certain classes.

At Ludi Labs, we used Spring in just about every way it can be used. Sometimes we got a little carried away and patted ourselves on the back about how clever we were. Then we would bring on a new developer and they would struggle to figure what the heck was going on with our application. We would have to patiently walk them through some things until things started to click. I have a feeling that Guice would have made this less painful for new developers, though there were definitely things we did with Spring (especially using its AOP support in conjunction with DI) that I'm not sure you could do with Guice.

Wednesday, February 28, 2007

Seamless Spring

I saw this post on TSS this morning. I read it, mostly because I like Seam so I wanted to see what was new with it. I was particularly pleased to see that Seam 1.2 was supposed to have "out of the box integration with Spring." I had to find out about this, so I read the man page on it.

I have to say, wow. The integration is really nice. When I started to read it, I immediately started to think "how is this going to work, Seam is all about statefulness and Spring is rather stateless?" Then I noticed the syntax on injecting a Seam component into a Spring bean:

<seam:instance name="someComponent"/>

I knew that when Spring 2.0 went XSD that we'd see things like this, i.e. a complimentary system integrating by importing its own XSD into a Spring config file. Next I noticed the unqualified name of the element, "instance." That sounded very stateful to me! Indeed from the doc:

Seam was designed from the ground up to support a stateful component model with multiple contexts. Spring was not. Unlike Seam bijection, Spring injection does not occur at method invocation time. Instead, injection happens only when the Spring bean is instantiated. So the instance available when the bean is instantiated will be the same instance that the bean uses for the entire life of the bean. For example, if a Seam CONVERSATION-scoped component instance is directly injected into a singleton Spring bean, that singleton will hold a reference to the same instance long after the conversation is over! We call this problem scope impedance. Seam bijection ensures that scope impedance is maintained naturally as an invocation flows through the system. In Spring, we need to inject a proxy of the Seam component, and resolve the reference when the proxy is invoked.

The <seam:instance/> tag lets us automatically proxy the Seam component.

That's just beautiful. Using a proxy like that is very common in both Hibernate and Spring, so this solution to the scope impedance problem is exactly what you would expect.

The doc details even more cool features. I love the way that Spring beans are injected into Seam components using @In("#{someSpringBean}"). The combination of using the annotation and the expression language is really nice. I would assume that something like @In("#{someSpringBean.someProperty}") would also work. Of course there are definitely some drawbacks to using all this syntactical sugar, but you can't argue that it's not fun.

Of course another interesting angle on this to me is that Seam is part of JBoss, which in some ways competes with Spring. Spring is often viewed as a "lighter" weight alternative to full app servers like JBoss. Indeed, when I met some JBoss developers last year they were somewhat incredulous about why people liked Spring. They thought it didn't do anything new, it just made some things a little easier...


technorati tags:, ,

Monday, November 27, 2006

JRockit and Tomcat

I decided to try out BEA's JRockit JVM a try as my server JVM. It bills itself as being a much faster JVM on x86 machines. So far it doesn't seem that much faster, except when running the JVM in debug mode. For that, it seems to launch much faster than HotSpot did. Actually there seems to be little difference in its startup time in debug mode vs. "normal" non-debug mode.

The only weird thing was that when I attached Eclipse to it, Eclipse complained about some line numbers not being reported by the code. This had no effect on any of the breakpoints I had set. Those worked flawlessly. It seemed to be around CGLIB enhanced byte-code, but there were obviously no breakpoints set in such code. I set a breakpoint in code that I knew would be CGLIB enhanced, but that still worked fine.

Just for kicks, I decided to also use JDK 1.6. I had a colleague tell me that "Mustang" was a lot faster than JDK 1.5. I was in for quite a surprise. My application threw an NPE while starting up. Why would changing JVMs cause an NPE? The startup was indeed much faster, but that was because the NPE caused less things to load. The NPE happened while Spring was "gluing" together several beans. I investigated a little, but found nothing obvious. Maybe I will dig deeper later.

Update: Not sure what caused the above problem, but since the official release of Mustang, I've switched over to using very successfully. There are definitely some big performance improvements, both in the client and server modes. I'm looking forward to making use of its scripting language features.

Tuesday, August 29, 2006

Spring MVC and Servlets

I've been using Spring MVC for a variety of web applications. It really does have a lot of nice advantages over Struts making it one of the better request-based frameworks (as opposed to the component based frameworks like Seam.) I came across an interesting use case that doesn't seem to be covered by Spring MVC.

I had a URL mapped to a controller. The URL needed to work for a variety of devices, not just
"full" web browsers like IE and Firefox. In particular it needed to work with a J2ME application. The controller needed to inspect the user agent of the HTTP request, build a model based on this information, and then forward to a view. The view would be different for different devices.

The wrinkle came when the developer working on the J2ME application told me he wanted the view to output a binary data stream. This could be done in a JSP, but is more suited to using a servlet. So I needed to configure a view in Spring MVC that was a servlet.

Spring MVC includes many view implementations. Several JSP-variants, and many other specialized views for working with various technologies such as Jasper Reports, Free Market, POI, PDF, etc. But nothing for a user built servlet like the one I needed to forward to. Seems like kind of a hole in Spring MVC.

Turns out it is not too hard to work around. The key is using the "forward:" prefix. Simply append this to the URL path specified in your servlet mapping, and it will short-circuit the Spring view lookup and forward directly to the desired servlet. So for example, if in your web.xml you had specified "/myServlet" as the mapping to your servlet, then having your controller return something like new ModelAndView("forward:/myServlet", "myModel", model) would forward to your servlet, and allow you to retrieve the model you had built in your controller using a simple request.getAttribute("myModel").

So it was easy to work around, but it still seems like Spring should have a servlet view. Maybe I will try to submit one to them...



technorati tags:,



Blogged with Flock