Sunday, March 24, 2013

Pros and Cons of Google Web Toolkit, Part 2


Last time we talked about Google Web Toolkit (GWT) and reviewed the advantages. Here we’ll look at some of the disadvantages and see when you might not want to use it.


(Side Note: This blog post is just about my own personal experience. Recently Vaadin put out a very nice set of infographics about GWT which covers a more statistically significant view of the strengths and weaknesses of GWT since it surveyed many GWT developers.)


The primary disadvantage in my view is compile time. Granted: many people are building large applications with GWT and large applications take a long time to build no matter what language you’re using. But the fact remains that even small to medium sized projects take far longer to compile than you would expect for something of that scale.


GWT also has a lack of good UI components. Generally we need to write all of our widgets from scratch and spend a lot of time on styling, as opposed to choosing a full featured widget library and theming it. Granted: this is by design, GWT does not pretend that it is there to provide a strong set of UI components. But it would be nice to have more components built in than it does, since it already provides everything else for you to structure your entire application. Additionally, the widgets it does have generate a lot of (needless to say, non-semantic) markup, complicating your CSS. How many times have I worked with a UI designer who cursed the markup that GWT was generating!


One of the strengths I mentioned before is also a weakness: Coding in Java.
  • More Code: There is simply more code to write in Java than there would be in Javascript. Strong typing gives you compile time type checking at the expense of much more code where types are close but not the same and cannot be inherited. Additionally, programming for the web requires something much more like callback-oriented programming, and Java is not designed for that. Things that would be a one or two-liner in Javascript can take 5 or 10 lines in Java.
  • Unit Testing: GWT tantalizingly provides a  GWTTestCase for unit testing UI classes. However, any test that runs based on this class is going to be agonizingly slow - increasing the pain of build times and destroying the possibility of having fast unit tests.
  • Finally, the strength of making front end development accessible to back end developers actually comes at the expense of excluding the majority of front end developers in the world. Most front end developers will be fluent in JS/CSS/HTML but not GWT and Java.

The only other disadvantages I’ve noticed are miscellaneous but worth mentioning.
  • There is sometimes a difference between “compiled” mode and “dev” mode. This is very very rare (it happens to me maybe once per year), but when it does happen it is next to impossible to debug.
  • Can’t debug network traffic: If you are using GWT-RPC or GWT-Dispatch, the network traffic is encoded and impossible to manually inspect. While developing this is not a problem since you can set a debugging breakpoint just before objects get marshalled or unmarshalled. But in a production environment, it will be impossible to troubleshoot a problem by looking at the network traffic (say, to see what data the productionserver thinks it’s getting). This can be alleviated by using RequestBuilder and  overlay types to call JSON REST services, although this is more work.
  • Given that many services are allowing multiple application clients (like what happened with Twitter) and that growth of mobile devices is outpacing growth of desktop computers, there is a disadvantage to requiring one language or framework for a front end application to interact with your services. If you use GWT-RPC or GWT-Dispatch, you can’t easily write mobile apps for your service - and neither can anybody else. The client would have to be a GWT client capable of making GWT calls. Again, this can be alleviated by using RequestBuilder and  overlay types to call JSON REST services, although this is more work.


So: when should you not use GWT?
  • You have front end developers who are already fluent in JS/CSS/HTML
  • You are planning on allowing third party development of applications for your services
  • You are planning on writing native mobile applications for your services
  • You don’t have enough money to buy extremely powerful build servers to compile your GWT code (Just Kidding! Or am I ?!?)

Sunday, March 17, 2013

Pros and Cons of Google Web Toolkit, Part I

I’ve been using Google Web Toolkit (GWT) off and on for the last 4 years (nonstop for the last 2), and was going over my experiences with a friend recently. GWT transpiles Java code into Javascript, allowing you to effectively write Java for the browser. There are some definite pros and cons to this approach, here are some of my own thoughts on the subject.

[EDIT This blog post is just about my own personal experience. Recently Vaadin put out a very nice set of infographics about GWT which covers a more statistically significant view of the strengths and weaknesses of GWT since it surveyed many GWT developers.]
 
In this post we’ll review the advantages. The advantage of GWT falls into two main categories: the fact that you’re using Java, and the capabilities of the framework itself. Let’s start with the first of these.

Because the front-end code is written in Java, you can leverage the ecosystem’s very mature IDEs such as Eclipse and Netbeans. You can use the same IDE to develop the front end and the back end, providing a seamless end-to-end development experience. The same is true for debugging - the debugger steps from front end to back end and you never have to leave your IDE. Other big advantages of using a mature IDE include refactoring support, functionality to find usages, and other code navigation.

You can leverage language features not available in Javascript directly, like a built in module system (Java’s packages). For large projects, it is easier to use modules to manage one million lines of Java than one million lines of Javascript. Support for unit testing in Java has been first class for many years with JUnit and TestNG. Javascript does have unit testing capability (say, with Jasmine), but I don’t have the impression that unit testing in Javascript is as widespread or easy as it is with Java.

Finally for the “you’re using Java” aspect: you can leverage Java developers. For a small software shop that doesn’t have the resources or needs for a pure front end development team, it makes a lot of sense to make use of the skills your developers already have. I have seen several workplaces where this was the case, and it has generally worked out pretty well, making efficient use of existing development resources.

The other advantage of GWT lies in the capabilities of the framework itself. GWT as a framework doesn’t do anything that you can’t do with the right combination of other Javascript libraries. But as an AJAX framework, GWT pulls together a cohesive set of functionality for building a RIA and gives it to you out of the box. For example: AJAX handling (actually multiple communication techniques: GWT-RPC, RequestFactory, and direct HTTP requests), history and place management, templating system with UI binder, form binding, and internationalization.

In conclusion, GWT is a mature and proven product, it is still being actively maintained and used, and it provides a lot of advantages to the software shop where it’s a good fit (say, a small team of Java developers who don’t have front end developers). As for whether or not GWT is always a good choice: As usual, it depends. In the next segment we’ll look at some of the disadvantages and see when you might not want to use it.

Sunday, March 10, 2013

Setting up HTTPS with CA certificates on Tomcat

There’s no doubt that every website needs to consider security. And serving critical portions of your site over HTTPS instead of HTTP is an important first step to securing your site.

There are any number of tutorials for setting up SSL on Tomcat. Many of us have generated our own keys and self-signed certificates at some point for side projects and personal development, that part is easy. But when you are ready to take your site public and a browser finds a self-signed certificate and it’s not from a certificate authority (CA), the browser will display all kinds of scary warnings about your site being unknown and potentially dangerous (which objectively it is at that point).

To resolve this, you need to get a certificate from an actual CA. They will verify your identity and send you a certificate that you can use with your site, and your site will become part of the CA’s - and hopefully the web’s - circle of trust.

Some CA’s that provide inexpensive certificates include Thawte, Digicert, and GeoTrust. To get a certificate from a CA, you generate a private key and use it to create a Certificate Signing Request (CSR). Send the CSR to the CA, and they will send you back a certificate that is registered with them that you can use on your site.

Ok here are the steps to setting up HTTPS with CA certificates on Tomcat. If nothing else, take note of step 7 - it’s the hardest step to figure out if you don’t have these directions.

  1. You’ll need the password for your java keystore, or you’ll need to create a new java keystore. If you don’t know it you can always create a new keystore and point tomcat to that. A keystore is just a single file with keys and certificates inside it. Don’t be afraid to experiment, if you create a key in your keystore that you don’t want, you can just delete that key. And since a keystore is just a single file, you can always back it up, restore it, start over, etc. If you forget information about your keystore (such as its password), and tomcat was already configured with it, you can just review the keystore information in tomcat’s server.xml file to recover that information.
    1. list the contents of my keystore: keytool -storepass password -list -keystore keystore.jks
    2. you can always delete a key if you mess something up: keytool -storepass password -delete -alias tomcat -keystore keystore.jks
  2. Read up on the documentation to make sure you understand what goes where. You can start with the Tomcat documentation.
  3. Use openssl to generate a certificate signing request (CSR). This creates a .csr and a .key, the .csr is what you send to your CA and they will return a .crt that corresponds to your private key.
  4. Keep the .key file, and send the .csr to your CA. The CA accepts the CSR and sends back possibly multiple .crt files (a root certificate, possibly some intermediates, and the one for your site).
  5. Create a new keystore if you don’t have one already (see step 1). Creating a new keystore is easy with these handy notes. You can create a keystore with a single dummy key and delete that key later if you want.
  6. You can import all of the certs from the CA into your keystore using the java keytool. The command looks something like this: keytool -storepass password -import -trustcacerts -alias intermediate_cert_name -file intermediate_file.crt -keystore keystore.jks
  7. Here is the tricky part: You also need to import the private key (the .key file created at the same time as the .csr) into the keystore. This is the tricky part because the Java Keytool does not natively import the .key file, and you need to use two steps.
    1. Use openssl to convert the key along with the .crt for your site (the .crt for your site that you got from theCA) into a .p12 file (technically another keystore) that the java keytool can import. The command looks something like this: openssl pkcs12 -export -in www_mycoolsite_com.crt -inkey  mygeneratedkey.key -out www_mycoolsite_com.p12 -name "www_mycoolsite_com_private_key"
    2. Import the .p12 file as a keystore into your keystore. The command looks something like this: keytool  -storepass password -importkeystore -srckeystore www_give3_org.p12 -srcstoretype PKCS12 -destkeystore keystore.jks
  8. Configure tomcat’s server.xml to use the https connector, you will need to modify the port, keystore file location, and keystore password. There are plenty examples of how this is done  online.
  9. Finally, configure the app to serve the site on HTTPS. This is done in web.xml
  10. If the certificate is only good for “www.yourdomain.com” rather than “*.yourdomain.com”, you can test the certificate locally by editing your /etc/hosts file so the site corresponding to the site certificate actually goes to the local machine. Add a line like “127.0.0.1    www.yourdomain.com”

And there you have it! Enjoy serving your site with HTTPS, and don’t neglect all the other aspects of security that need to be addresses for your public-facing site.


Sunday, March 3, 2013

Strong Type Weak Type


I was playing around with handlebars the other day, and I got to a point where the json object going into my handlebars template had a date (number) that I wanted to convert and format into a date string.

I quickly ran through a few thoughts: Can I execute javascript inside the handlebars template? Nope. Can I use a JSP Scriptlet? No this is on the browser. Do I need to define a new string field on my domain object on the server just so the json comes through in a way that I can display what I want in the UI? Ugh, besides requiring a change to my domain model and recompiling, that is mixing up my server side code with my display which is not what I want.

Waaaait a second...

Javascript objects are dynamically typed! I can just format the date and add the string as a new property to the object in javascript before passing the object to my handlebars template, and reference that new property from inside the template. Problem: solved.

Ok, this sounds like a trivial exercise for anybody who has ever coded in a dynamically typed language. It even sounds trivial to me. But even after having read some javascript books (including Javascript the Good Parts... a few times), and writing and practicing javascript on the side, years of programming in Java have oriented my brain to a certain way of thinking. That way of thinking at a fundamental level includes the idea of redefining a class and recompiling if I want to add an attribute to an object.

The new ways of dynamic typing DO come. But they do not come first. That is the experience of a strongly typed programmer moving into a weakly typed language.

Sunday, February 24, 2013

Dependency Injection Part V: When to use (or not)

Previously we looked at Dependency Injection in detail, looking at the advantages and disadvantages in detail, and examining ways to overcome some of the disadvantages. I’d like to summarize by exploring when to use it and when not to use it.

In general it would be a good idea to use DI when the advantages outweigh the disadvantages, or the disadvantages can be mitigated. A careful review of the advantages and disadvantages we’ve already discussed might point you in the right direction. We don’t have hard and fast rules to say “use it here” and “don’t use it there”, we really need to investigate the pros and cons and see how the apply to what we’re trying to build. The decision is an architectural one and generally needs to be made early in the design of an application.

As a rule of thumb however, using a DI container could be a good choice at the very least if you are starting a project and want a standard technique to compose subsystems and orchestrate the large scale construction. This is another advantage that I didn’t mention before, but many of the large scale structures in an application are singletons, and DI containers facilitate a solution to the Singleton anti-pattern. Rather than controlling singleton instantiation yourself (which is easy to get wrong, common solutions include double-checked locking or enum singletons) the container controls the instantiation of a singleton.

As another rule of thumb, there are times when DI might not be a good choice. If you are working with a large legacy system that does not use DI at all, it could be prohibitively expensive to bolt on. DI is high-level and is best introduced at design time. Java lang objects that really are implementation details, such as Lists and Maps should probably not be injected. And objects created late in the scope's lifecycle should be not injected (or the scope of the object should be rethought). Finally, if your project is a library or a small application, the overhead of using a framework (indeed, any framework, not just a DI framework) tips the scale in favor of not using it. For software in general it’s good to keep things as simple as possible for as long as possible.

Sunday, February 17, 2013

Getting Started with Selenium

Selenium is a neat little tool for integration testing with browser automation. If you’re not familiar with it already, check it out. The Selenium IDE can record and playback actions on your browser, with the caveat that it’s normal to have to go back and manually tweak some of the steps that it recorded. Here are some notes from when I first started out with it, and some issues that I worked through. Hopefully reading this will save you some headaches.

The native file format for tests cases in Selenium IDE is html, but you can convert Selenium IDE files into unit tests in the language of your choice. The big advantage of this is running automated tests as a part of your build process. For Java, navigate to file -> export test case as -> java / junit 4 / webdriver. Selenium unit tests need to run on a machine that has graphics capabilities so it can open a browser, but it is possible to configure a headless machine to run selenium. Some gotchas related to unit testing with selenium test cases:

  • Tests tend to be brittle. If you start building a complete test suite with code, look into the Page Object pattern, this will make your test more resilient.
  • If a unit test fails an assertion, the rest of the test will fail to run, which can hurt if each test does setup and teardown for itself and subsequent tests expect a “clean” state before they start running. It’s best to not depend on teardown steps in your test.
  • If you’re testing with webdriver and firefox, then firefox must be shutdown before running selenium tests because selenium currently can’t attach to a running instance and a new instance of firefox can’t be started if it’s already running.
  • Selenium must run in sequence per machine, they can’t be run in parallel tests because of the aforementioned firefox issue. Parallelized selenium tests can be achieved with selenium grid.

One thing that you generally have to tweak in any tests generated by Selenium IDE is the timing of the steps. When you record, you have natural pauses in your activity but the test case runs each step one after the other as quickly as possible. I had a test case that hit an update button, verified the response, and logged out at the end of the case. However the javascript that would have received the update response stopped running on logout, and verification subsequently failed. You need careful use of andWait / waitFor / pause commands to make sure your app functions correctly under test. Also, if you use a pause or a clickAndWait as the last command of a case (say, to log out at the end of a test case), the case will not actually pause or wait because the time is added to the beginning of the next step of a test case, not the end of the current command. You can get around this by putting an echo as the last command of the case.


Sometimes the selectors that Selenium IDE generates are either too brittle or not working at all. One thing to try is to select the element you want to click in firebug and view the xpath from that, and use that in the selenium step. Another (preferred) option is to be more intelligent about how you select it, say by selecting element by text content or by css class if you know that they will be unique on the page.

Sunday, February 10, 2013

Dependency Injection Part IV: Responses to Arguments Against Dependency Injection

In the previous post, we looked at arguments against using dependency injection frameworks. I posted the arguments because I thought they were all valid points, so my response won't just be "no its not a problem." rather I want to show how these problems can be mitigated so that DI can made worth your while.

About complexity: yes example code online using DI is usually more complex than the straight-up counterparts. But examples are just examples, when we are demonstrating code online the code has to be small enough to fit on a page (or small enough for a newcomer to wrap their head around easily). With a small example or even small projects, the overhead of DI can be a significant part of the overall code leading to the first impression that it’s very heavy or very imposing on your code. In reality, for large real-world projects, DI amounts for a very small amount of our overall code, so the overhead is relatively small. In other words, DI is too complex for small examples but shines on large object graphs with varying scopes. We just don’t usually see examples like that when we discuss DI online. So the problem of overhead and complexity is mitigated by saving DI for larger projects.

As for breaking encapsulation, yes you can break encapsulation if you inject concrete classes which are your implementation details. I would respond that if we inject a concrete class then we are indeed advertising our implementation, but if we inject an interface we are advertising much less (given that we’re using the Interface Segregation Principle). At that point we are advertising not so much the implementation as we are the dependency on a subsystem. To “do it right” we should inject interfaces for each element of your object tree and use a DI container. The top level class depends on a minimal interface, the implementation of that class itself depends only on minimal interfaces, and so on. Additionally, encapsulation can be managed with visibility control provided by our language.

Sometimes some members should be final but we might think we can’t inject final attributes. In fact we can inject final attributes... In this case, we just cannot use setter injection. Instead we need to not assign the member when it’s declared and use constructor injection.

It’s been said that even though DI eases changing configuration at runtime, we'd rarely change configuration anyway. But I'd like to point out that we change configuration every time we use a mock or stub object in a test. If you do not use unit tests, then the original argument holds water. But if you do not use unit tests, I would say we need to have a different conversation about why unit testing is helpful in the first place. If you see the benefits of unit tests, then you will see the benefits of DI for making your code more testable.

Using a DI container ties us to a framework. Each container offers its own annotations that threaten to invade our code and make it very difficult to ever disentangle from that framework. however, if we only code with the javax inject annotations, the annotations in our code can be just standard JEE.  We can code it so that the only framework specific code is in the wiring, and if that is always in one place it should not be a big deal to swap one DI container implementation for another.

Finally, some DI containers use XML for their configuration. XML is not quite in fashion like it used to be. But fortunately newer DI containers (newer versions of Spring and Guice for sure) allow us to write our configuration in code rather than XML. This gets around the problem of using strings to identify and wire dependencies, and lets us leverage our IDE for things like refactoring and renaming classes, navigating with "find usages", and so on.


Hopefully this shows you how to work around some shortcomings of DI so that you feel better about adding it to your software engineering arsenal.