My name is Juri Strumpflohner and this is my technical blog. I'm a software architect, .Net, Android, Web and Java dev, TDD and best practices promoter and martial arts practitioner.

Recent Posts Subscribe

Dear reader of Juri's TechBlog,
I moved my blog to a new domain and a new hosting solution as well. I'm now blogging on juristr.com.

GWT meets Spring

GWT is quite evolving recently. There are a couple of reasons for that:

  • Coding apps like Gmail and Google Wave
    We all appreciate the speed of the Gmail UI. It's just like operating on a local client. Moreover the coming (already popular) Google Wave has been build using GWT.

  • Cross-browser compatibility
    The produced outcome by GWT is pure JavaScript, optimized for performance and cross-browser compatibility. The major advantage: there is no need for installing a runtime, plugin or whatever. It's just plain JavaScript!

  • IDE support and Hosting solutions
    The new Google Plugin for Eclipse makes it easy to develop GWT apps. Debugging, hosted mode browsing without the need of a deployment makes it feel like developing desktop clients.
    Moreover a 1-click deploy to Appengine is provided which can be used as the hosting solution with Google-like DB already integrated.
 For making this enterprise ready however you probably would like to use some more powerful tools especially at the server-side. You know Spring :) ? If not, you should get in contact with it.

What I tried to do is to integrate GWT with Spring and Google Appengine. I tried to do that already about 2 years ago and succeeded but unfortunately I didn't have the time to continue. Meanwhile GWT has evolved and there is a lot of support available on the web and even on the GWT Googlecode hosting for integrating both (just google for it).

The central element for connecting both is to have the GWTController which accepts the incoming HTTP requests, decodes the Google-RPC payload and invokes the correct implementation of the server-side service, catches the response, encodes everything and sends it back.
So I configured the standard GreetingService demo and launched my GWT app and see there..
WARNING: Nested in org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException:
java.lang.NullPointerException
    at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:163)
    at com.google.gwt.user.server.rpc.RemoteServiceServlet.doUnexpectedFailure(RemoteServiceServlet.java:284)
    at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:99)
    at com.myapp.demo.server.GWTController.handleRequest(GWTController.java:51)
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:781)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:726)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:636)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:556)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
    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.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
    at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:121)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
A nice NullPointerException when the "javax.servlet.GenericServlet.getServletContext()" gets invoked. Perfekt, was not even my code. I searched a while for a solution, when some hints on the web lead me into the right direction. For avoiding this problem the GWTController has to be made "context aware". Basically it has to get the ServletContext injected. By doing so, the GWTController code should look like this:
public class GWTController extends RemoteServiceServlet implements Controller, ServletContextAware {
 // Instance fields
 private RemoteService remoteService;
 private Class remoteServiceClass;
 private ServletContext servletContext;

 // Public methods
 /**
  * Implements Spring Controller interface method.
  * 
  * Call GWT's RemoteService doPost() method and return null.
  * 
  * @param request
  *            current HTTP request
  * @param response
  *            current HTTP response
  * @return a ModelAndView to render, or null if handled directly
  * @throws Exception
  *             in case of errors
  */
 public ModelAndView handleRequest(HttpServletRequest request,
   HttpServletResponse response) throws Exception {
  doPost(request, response);
  return null; // response handled by GWT RPC over XmlHttpRequest
 }

 /**
  * Process the RPC request encoded into the payload string and return a
  * string that encodes either the method return or an exception thrown by
  * it.
  */
 public String processCall(String payload) throws SerializationException {
  try {
   RPCRequest rpcRequest = RPC.decodeRequest(payload,
     this.remoteServiceClass);

   // delegate work to the spring injected service
   return RPC.invokeAndEncodeResponse(this.remoteService, rpcRequest
     .getMethod(), rpcRequest.getParameters());
  } catch (IncompatibleRemoteServiceException e) {
   return RPC.encodeResponseForFailure(null, e);
  }
 }

 /**
  * Setter for Spring injection of the GWT RemoteService object.
  * 
  * @param RemoteService
  *            the GWT RemoteService implementation that will be delegated to
  *            by the {@code GWTController}.
  */
 public void setRemoteService(RemoteService remoteService) {
  this.remoteService = remoteService;
  this.remoteServiceClass = this.remoteService.getClass();
 }
 
 @Override
        public ServletContext getServletContext() {
           return servletContext;
        }

        public void setServletContext(ServletContext servletContext) {
           this.servletContext = servletContext;
        }

}
In this way the ServletContext gets fetched from here. Note, if your service implementations classes do also need to use the ServletContext, you have to basically do the same thing: implementing the ServletContextAware interface and overriding the corresponding methods. Then you should be done and everything should just work seamlessly :) Just comment if you have any questions about it.

Are C# regions a good thing??

Well, I'd say it depends. If you use regions to logically group your code in your class, then it may be a good thing 'cause people come to your class and see something like

public class MyDummyClass : IMySuperInterface
{
   public MyDummyClass(...)
   {
      ...
   } 

   #region Properties
   ...
   #endregion

   #region Utility
   ...
   #endregion

   #region Implementation of IMySuperInterface
   ...
   #endregion
}
In such case it may increase the organization of the code inside your class. I wouldn't say it increases the readability of your class since it's just a matter of code reorganization.

Many times however you find people using regions like
public class MyBLClass : IMySuperInterface
{
   public MyBLClass(...)
   {
      ...
   } 

   public IList ReadAllOrComputeWhatever(...)
   {
      if(parameterA >= someNumberOrString)
      {
         #region Check for blablabal
            // 30LOC+ hidden here of CC 10+
         #endregion
         ...
      }
   }
}
...then regions suddenly aren't that nice any more. I find that a lot of people actually use it for hiding their ugly, "smelling" pieces of code which would highly have the need of being refactored. I think this is very much related to this here.

So...
  • logically grouping: good thing, though it depends on preferences (I personally don't like it that much)
  • code hiding: bad practice. Sign of a code smell and you should consider to refactor it.

Law of Demeter: Nice metaphor

I just came across a nice metaphor for explaining the Law of Demeter. For those of you that didn't yet hear about it, the Law of Demeter is a object oriented design principle. A guideline basically which leads to nice and testable OO code, but Wiki will tell you more.

The metaphor is the following:

Imagine you are in a store and the item you are purchasing is $25.

Do you give the clerk $25?

Or do you give him the wallet and let him/her retrieve the $25?
Intuitive I guess :) . The same actually holds for the design of objects. Consider this example:
class Goods{
   AccountReceivable ar; 

   void purchase(Customer customer){
      Money m = customer.getWallet().getMoney();
      ar.recordSale(this,m);
   }

}

You still may not see the problem but it'll come out when testing the purchase method. For doing so the following code has to be instantiated:
class GoodsTest{

   void purchaseTest(){
      AccountReceivable ar = new MockAR();
      Goods goods = new Goods(ar);
      Money money = new Money(25, USD);
      Wallet wallet = new Wallet(money);
      Customer customer = new Customer(wallet);

      //finally
      g.purchase(customer);
      assertEquals(25, ar.getSales());
   }
}
Looks horrible, doesn't it?

Instead, when following the Law of Demeter, we would design it as follows:
class Goods{
   AccountReceivable ar; 

   void purchase(Money money){
      ar.recordSale(this,money);
   }

}
and test it like
class GoodsTest{

   void purchaseTest(){
      AccountReceivable ar = new MockAR();
      Goods goods = new Goods(ar);
      
      g.purchase(new Money(25, USD));
      assertEquals(25, ar.getSales());
   }
}
Looks already much nicer and much more correct in my opinion. Why should the Goods class know where the money comes from?? It just shouldn't care about that.

In my eyes this is a really nice explanation of the Law of Demeter and moreover it shows how unit testing uncovers flaws in your code. When unit testing gets hard or impossible is a big indication of problems in your code. That's why a lot of people don't like unit testing...just because they're writing untestable code.

I've another draft post in my blog list about how you can improve testability and software design by using dependency injection. It's very tightly coupled to this topic here. I just did not yet find the time to finish it and btw...now I really have to continue to study for my Statistics exam this Friday...

New equation editor makes GDocs even more usable!!

I always liked the idea of having a office-like suite on the web. I already used Writely for taking quick notes or just short documents, already before it was acquired by Google and merged - together with Google Spreadsheets - to the Google Documents service. But still most commonly at the end I used my local office suite (MS Office normally).

But since the switch to my new MacBook Pro notebook (I really like it ;) ) I started to use GDocs really heavy. I didn't install MS Office (for Mac) but Open Office. GDocs comes in very handy. Ok, I admit, as a software developer you don't write much documents (normally) but for my master studies there is plenty to write. So for documents that have to be written more formally (architectural documents, reports, ...) I started to use LaTeX (together with the Texclipse plugin), which is really great once you're comfortable with it's syntax. For the remaining, GDocs is just perfect. It opens quickly, extremely responsive, even offline support and you're not bound to it which is of major importance. You can export the end result in a plenty of formats



Other nice features are revisions of your file and the nearly (real-time) collaboration on the same document (nice for writing documents in parallel with others).
The only problem I had till now is when it comes to write notes for some scientific stuff where you have a lot of formulas, what then. Well this was one reason for using LaTeX instead of MS Office or OpenOffice. But GDocs?? Today I came across this when making some notes in preparation for my Statistic exam and look there, GDocs has now (I guess since a couple of days) a new equation editor that supports LaTeX syntax!!

While you write the LaTeX syntax on top, it will simultaneously write you the end result in the preview below. Really cool :)

Microsoft Ajax CDN

Scott Gu' just announced the launch of Microsoft Ajax Content Delivery Network. The name already explains mostly everything. It allows you to retrieve Ajax script libraries for your web application by specifying things like this

<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js" type="text/javascript"></script>

Asp.net 4.0 will make this support even easier by just specifying the "EnableCdn" property on the ScriptManager with the effect that the files will be retrieved automatically.

Content delivery networks (CDNs) are composed of "edge cache" servers that are strategically placed around the world at key Internet network points.  These "edge cache" servers can be used to cache and deliver all types of content – including images, videos, CSS and JavaScript files.

Using a CDN can significantly improve a website's end-user performance, since it enables browsers to more quickly retrieve and download content.  For example, instead of having a browser request for an image traverse all the way across the Internet to your web server to download, a CDN can instead serve the request directly from a nearby "edge cache" server that might only be a single network hop away from your customer (making it return much faster – which makes your pages load quicker).
Source: http://weblogs.asp.net/scottgu/archive/2009/09/15/announcing-the-microsoft-ajax-cdn.aspx
Moreover, the service is free :) . This are good news, since also Google provided such a service already for a longer time under the name Google Ajax Libraries API (see also the great playground for them). The difference, they host a lot more libraries already.

I'm generally excited about the release of Asp.net 4.0. They place a lot of weight on going into the Ajax direction which in my eyes is really important for creating more interactive and usable web applications. This will save me a lot of work...good that I didn't yet start to develop my own ajax-enabled server controls (since there were already some ideas around) :) . Unfortunately I didn't yet have the time to look into some more deep demos but I have to.

Add semantic through your code, not through commenting

Is it good to have a lot of code comments, explaining things s.t. your other team members know what was your intention when writing certain pieces?? Well, not fully. Having a lot of code comments throughout your code is also considered to be a code smell and should therefore be avoided. But so, what should be done? Just remove the comments? No, the key part is to add semantic by writing explicit, well readable code.

One way (of many such as writing meaningful variable names) of adding semantic to your code is in my eyes tightly related to the "Extract Method" refactoring. I'd like to mention it here shortly with a real example because I think people should care about this and apply it (where appropriate of course).

The method below shows a "real" code sample, where a comment has been added for explaining the purpose of the following lines of code.

if (someConditionHolds)
{
    //formats the date according to the given culture
    DateTime date;
    if (DateTime.TryParse(textBoxDate.Text, new CultureInfo(this.PreviousCulture), DateTimeStyles.AssumeLocal, out date))
    {
        textBoxDate.Text = date.ToString(this.DisplayFormat, Thread.CurrentThread.CurrentUICulture);
    }
}
This code looks quite complex, you see the reading of the culture from the current thread, then there is some other code involved which is creating a new culture object based on the previously used culture etc...Basically a lot of complex stuff which I don't want to bother about if I was not the developer who wrote this piece. So one would read the comment above and understand, ok, these lines are just formatting the date according to the current culture and assigning it to the textbox.

In such a case Fowler suggests to apply the "Extract Method" refactoring and restructure it as follows
if (someConditionHolds)
{
    textBoxDate.Text = GetCultureFormattedDateString(textBoxDate.Text);
}

private string GetCultureFormattedDateString(string toFormat)
{
    string result = toFormat;

    DateTime date;
    if (DateTime.TryParse(textBoxDate.Text, new CultureInfo(this.PreviousCulture), DateTimeStyles.AssumeLocal, out date))
    {
        result = date.ToString(this.DisplayFormat, Thread.CurrentThread.CurrentUICulture);
    }

    return result;
}
Now this really looks simple, doesn't it? When I read over the code, I come across the method call and I immediately catch what is going on by reading the method name. Then, if I'm interested in this special thing, I can go and read the complex implementation, but otherwise I just don't care and go on.

Watch out when cloning objects

Cloning is never a good thing. I would say in most cases there is a better alternative for reaching your goal, but now and then it happens that you need it. But in such a case, be careful. Assume you have something like this:

class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }

    public Person Clone()
    {
        return MemberwiseClone() as Person;
    }
}

class Address
{
    public string Street { get; set; }
    public string Country { get; set; }
}
Note, to clone I have to use the inherited method "MemberwiseClone()" from Object and expose it publicly. This creates a shallow copy, meaning copying just the surface. So if you then have somewhere
Person p = new Person
{
    Name = "Juri",
    Address = new Address
    {
        Street = "Bolzano",
        Country = "Italy"
    }
};
(using inline initialization just for the purpose of this demo) and then cloning the object by calling
Person clone = p.Clone();
...you'll have the situation that the following statement will be true
clone.Address == p.Address;
If you read the documentation on MSDN it will also be clear why this is the case:
The MemberwiseClone method creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed. If a field is a reference type, the reference is copied but the referred object is not; therefore, the original object and its clone refer to the same object.

One has to pay particular attention to this. If you ignore this and you expect to have different Address objects you may get weird behavior in your program which may be difficult to debug later on.

So basically what would be expected above is to not do a shallow copy, but a deep copy. In such a case you shouldn't expose the Clone() method yourself but rather implement the ICloneable interface. The deep copy logic has to be implemented by yourself. The example above could then look like this
public class Person : ICloneable
{
    public string Name { get; set; }
    public Address Address { get; set; }

    #region ICloneable Members

    public object Clone()
    {
        Person clone = MemberwiseClone() as Person;
        if (this.Address != null)
        {
            this.Address = this.Address.Clone() as Address;
        }

        return clone;
    }

    #endregion
}

public class Address : ICloneable
{
    public string Street { get; set; }
    public string Country { get; set; }

    #region ICloneable Members

    public object Clone()
    {
        return MemberwiseClone();
    }

    #endregion
}
This could be one way of doing it. However be sure that you have the control of the whole object hierarchy. Cloning customer server controls (that inherit from the standard web controls) won't be such a good idea since there are too much dependencies among the object hierarchy which could lead to strange side effects. I was experiencing some of them, but I'll post an update as soon as I found the exact reason.

Brad Abrams mentions some comments on implementing the ICloneable interface which may be worth looking at.

"It is not about writing tests, its about writing stories"

Writing unit test and moreover having them in place when developing is a great thing. They give you some kind of assurance (if well done). I mean, you can modify things without fearing to break existing code. Afterwards you just run your tests and check if everything is still fine. Of course this does just hold if tests are written properly and you have a quite large test coverage.

But explaining people which did never work with unit tests nor even heard of them at all is extremely difficult. I mean, it's clear. Why should I code more, "waste" more time to reach the same goal? As I said, it's difficult and in such situation don't even start talking about test-driven development or the less used name test-driven-design.

But if you're interested in reading something about it, here's a blog post on the great Google Testing Blog, which describes a nice analogy between building software and a car. And it really highlights very nicely the advantage of adopting test-first strategies versus test-last.
Read here:

Dropbox iPhone app will soon be released!

The official Dropbox blog announced that they submitted their iPhone app for approval.


Just some of the features they mentioned:
  • Access your Dropbox on the go -  All the contents of your Dropbox are available for viewing.  You can even stream music and movies in your Dropbox straight to your iPhone.
  • Download files for offline viewing  - Add files to your ‘Favorites’, and they’ll be accessible at any time.
  • Take photos and videos and sync them to your Dropbox  - Take a photo from your iPhone and email its public link to a friend in less than a minute.
  • Share links to files in your Dropbox  - What?  Any file in your Dropbox?  Srsly?
  • Photo galleries  - Just like the ones online.
It will be great since this will finally allow to have some kind of file manager on your iPhone and moreover automatically synched with your PC, Mac or Linux machine, thanks to Dropbox. So support these guys, they're doing a brilliant job!!

If you don't have an account yet, let me know, so I'll send you an invitation. We will have benefit both in gaining more storage space :)

Here's the official post.