Today I learn something useful.
Apparently Google (perhaps all openId providers) as a open id service provider do not consider these two realms to be the same http://subdomain.domain.com and http://*.subdomain.domain.com . This is a major pitfall since it might cause you (as it did for me) to make users start using your service with a faulty realm. Which later on might cause them / you a substantial hassel when their openID is not linked to any user account (since the realm changed).
GWT selling points
I would like to state for the impatient reader that THE main reason for choosing GWT in front of plain Javascript (home brewed) is “Compile time checking” and “Static typing”. So if these are features that you feel are crucial for the success of your project you have found your tool. However if you feel that “Static typing” and “Compile time checking” do not completely convince you as selling points or rather you dont understand how they can be the main reasons for GWT since you hate them and they are the main reasons for your life being miserable, keep on reading.
I came across GWT late 2009 and I did not initially understand what the purpose of it was. However since then I have used it in projects with both failure and success as a result. Since my technical domain usually is the web new technologies such as GWT is discussed on architectural project upstart forums. I have from time to time in such forums been asked to present some of the pros and cons that I have encountered using GWT. I though it might be of interest for someone else so here it goes..
Misconceptions
Often (mistakenly) the main reason for choosing GWT is that it solves the awkward browser quirks, we as web developer have to cope with. Since these quirks are such boring and cumbersome tasks for web developers to solve, we soooo eagerly want to believe every attempt and product sales pitch that argues that it have solved it. However I have yet to se such a product that works flawlessly GWT is no exception! Choosing GWT will not solve this problem completely for you!! It will however give you standardized framework to plugin your own fixes for each quirk using what GWT calls “deffered bindings“.
Another misconception about GWT is that you will not need to know anything about javascript to use it. Unless your future application is anything more complex than the example application google provides (and if your application is that simple I cant really motivate the GWT choise), you will need to understand some basics of javascript. You will need to solve some problems with JSNI Javascipt Native Interface which relies heavily on knowledge about javascript.
Nice features
GWT has a few rather nice features that is to seldom promoted.
Resource bundles
Resources on the web is scarce one of the most scarce resources is the capacity of the network it self. As processor resources follow more’s law networks do not. As processors gets faster and therefore also cheaper we are getting more and more competent devices in our hands. All this computing power gets rather dull if not utilized in a network however since the network do not follow the same progress as processors we need to utilize the network as smart as possible. This has been done for quite some time in the web with the technique of using css sprites. So if this has been around for some time what is the deal with GWT and resource bundles? Well as nice as css sprites are they are not real easy to create. For them to work you first need to create a large sheet with all (or some) of your images then calculate and position them with css. This has to be repeated each time you add a new image to your site, it tends to get rather cumbersome. What GWT does is at compile time do this for you.
Name spaced css with strict scoping
Have you ever started out defining css class names at the start of a project just to go back renaming them since you realized that the names you gave them does interfere with some new features? If answered yes on that question I guess that you also remembered what a search & replace hell that was? If you answered no, might it be because you did not bear doing it, instead you keept the old names and gave the new features quirky names that did not really represent what the feature was all about?
Well GWT brings name spaced CSS to the table along with strict scoping. What is that? GWT mapps a .css file to a interface and mapps each css class name to a method. In doing so it also gets the benefits of the JAVA name spaces. If you use this feature in GWT you can in one part of your application give the “largeButton” css class the meaning of a red 100px wide button and in another part 500px wide without the classes interfering with each other. Above that GWT will at compile time tell you if a css class no longer is used or if you misspelled a css class name. This is a real time saver.
Dependency injection
This is not really plain GWT however if you include reference to the GIN modules you get an almost (It do not support all features of Guice) feature complete dependency injection framework. I cant really cover the benefits with a DI container in this post so you either already know what DI framework does or you really need to read up upon it.
Solves browser caching
GWT name all .js files baed on a hash algorithm (not sure although I believe it is MD5). This is done by using the javascript content as input to the hashing. This sort of automatically solves the issues with browsers not wanting to download changes in your javascript.
Design patterns
GWT has utilized many proven GOF and Fowler patterns such as MVP, Observer, Command etc. There are a few examples using these patterns which can help you to start of in the right direction.
Draw backs
Well no framework is flawless and they all have their trade offs.
Turn around time
The biggest trade off you need to consider is the turn around time i.e. the time it takes you to add some small feature to a UI and until it shows up on your browser. This obviously has to do with the fact that GWT compiles you JAVA source into javascript. I must say though that the guys behind GWT has improved this tremendously since the earlier releases (2.4 when writing). Now the compilation is done in parallell and utilizes all CPU cores which makes it go faster. There is also the hosted mode redering (you use this during development in conjunction with a browser plugin) which goes at lot faster although it has not always been flawless when I used it. I think that this issue must be communicated and understood by all team members prior to choosing GWT if not you might end up with a developer riot on your throat.
Complexity
GWT certainly is the enterprise way to go about javascript (read web client side ui) development. With that said you as a decision maker need to understand what kind of team your have at you hands. Are your team skilled in development with frameworks and concepts sch as JAVA EE, SPRING, MVP, TDD etc. and are your team eager to learn? If yes you will need less of an effort to be successful with GWT. If no, you will probably be more successful using a more light weighted framework such as JQuery in conjunction with home brewed javascript. Which might be the right decision either way depending on your project complexity.
java.util.Date
GWT still depends on java.util.Date for time and date logic. This is not good since many of the methods on the Date class is deprecated. read more here..
Bottom line
So how can such old and boring things as “compile time checking” and “Static typing” be the main reasons for GWT?
Well as stated above that argument is only valid if you intend to use GWT in a relative large project. To define a large I would argue that it is a project which has more than 2 active developers in it or that will result in more than aprox. 200 lines of javascript. GWT in its core is nothing more that compile time interpreted JAVA into javascript. In doing so all benefits with JAVA comes with it. Benefits you say?
Yes a dynamically typed language as javascript has many strong sides (me not being very proficient in javascript, you might have guessed it
, cant count them up) but refactoring and testing support is still scarce. This makes it a poor language to work on in a team setup. I guess it could work if all team members are proficient in javascript and you find your self a good testing and refactoring tooling. Although if you have this then you probably would not be looking towards GWT in the first place would you? With JAVA and all IDE’s that support it you get type safety, extensive refactoring tool support, unit testing support etc. When you are in a large project these tools is what keep your WFT count to a minimum or at lest they should help you keeping it down.
Need more input before making a decision? Read this:
http://blog.codecentric.de/en/2010/11/inner-dialog-on-gwt-benefits-and-drawbacks/
Generate view for external model with Grails
If you like me are using a legacy domain (java / JPA) model with grails you might have encountered the question, how to do I use the grails view generation scripts? You cant just write :
grails generate-views domainclass
Grails will not recognize domainclass as a domain class instead you need to specify the whole package path as well:
grails generate-views my.project.domain.domainclass
and voila! Grails will generate the views for you.
Mocking closure with Groovy in Spock
I recently found my self in a pickle needing to verify arguments passed into a Groovy closure (to be precise it was the sendMail closure in the Grails MailService plugin). The solution was to use a Expando add a sendMail closure onto it and point all argument closures to it as well. This way I could fetch a reference to the Map passed into the body closure. Se details below..
def "A remind me request shall send an email with the users email embedded within links"(){
given: "a mail service"
def mailService = new Expando()
mailService.sendMail = { callable ->
callable.delegate = mailService
callable.call()
}
and: "a closure"
def model
mailService.to = {}
mailService.subject = {}
mailService.body = {Map map ->
model = map["model"]
}
and: "the remind me service"
def service = new RemindMeService()
service.mailService = mailService
and: "a user"
mockDomain(UserImpl, [user])
and: "a action with a correct email"
def action = new RemindMeAction("tester@test.com")
when: "service is invoked"
service.remind(action)
then: "mailservice shall be invoked with links containing users email"
model["iphonelink"].contains(":tester@test.com")
model["weblink"].contains(":tester@test.com")
where: "there is a user which has such an email"
user = new UserImpl(email: "tester@test.com")
}
Spock
After practicing TDD (with emphasis on driven) for aprox. 3 years now I recently encountered Spock. I really starting to like Spock since it adds a readability and recurring structure to the tests. We can all agree upon that it is just as important that the test code is well written as that the production code is well written. This since the tests are the specifications of the system.
Before I found Spock the way I wrote my test mostly looked the same however to ofter I found it hard to understand what or how the test tested, coming back to the test code. Spock seem to give us a nice structured way to write our test in a way that it is readable what the code test and how it test. Spock runs on Groovy wich enables it to have functions / closure which i can be named by a string this enables us to write out test name as a sentence. Moreover Spock tests (or specifications as they are called in Spock lingo) are all structured in the sections given: -> when: -> then: -> where:.
given:
This section is somewhat like the unit test setup method.
when:
This section is where you invoke the code under test i.e. the playback phase.
then:
This section is where you write your expectations.
where:
This section is where you provide your test data.
Putting all this together gives us more readable test with a few comments test will become a few sentences which describes what and how the test test. Given the test below it could now be written as
“Given a mail service and a closure and the remind me service and a action with a correct email. When service is invoked then mailservice shall be invoked with links containing users email. Where there is a user which has such an email.”
def "A remind me request shall send an email with the users email embedded within links"(){
given: "a mail service"
def mailService = new Expando()
mailService.sendMail = { callable ->
callable.delegate = mailService
callable.call()
}
and: "a closure"
def model
mailService.to = {}
mailService.subject = {}
mailService.body = {Map map ->
model = map["model"]
}
and: "the remind me service"
def service = new RemindMeService()
service.mailService = mailService
and: "a user"
mockDomain(UserImpl, [user])
and: "a action with a correct email"
def action = new RemindMeAction("tester@test.com")
when: "service is invoked"
service.remind(action)
then: "mailservice shall be invoked with links containing users email"
model["iphonelink"].contains(":tester@test.com")
model["weblink"].contains(":tester@test.com")
where: "there is a user which has such an email"
user = new UserImpl(email: "tester@test.com")
}
dev@Cloudbees, Jenkins, Grails & GWT
Today I finally got my Grails with the GWT plugin built with help of dev@cloudbees. It took some tinkering about, here is what I did.
The first issue was to setup jenkins to build a Grails app. There is a jenkins plugin that enables this however that plugins needs to be installed and enabled. To do this navigate to Jenkins Builds -> Manage Jenkins -> Manage Plugins. Look among the plugins under the “Available” tab (if not there, it might already be installed and should thus be under “Installed”) look for “Jenkins Grails plugin” and enable it (might require that jenkins is restarted). 
Then we should create a new job navigate to Jenkins Builds -> New Job. Name your job and choose “Build a free-style software project”. In the configuration form specify your SCM settings under the Source Code Management section, then look for the “Build” section. Click on the Add build step and choose Build with Grails. In the new section that appears fill in the Grails version you use, under Targets fill in the Grails command you wish to execute (ex. “prod war”) do not forget to enclose it in double quotes. Click save! If you only have a vanilla Grails project to build you are done here. Though if you use the GWT plugin and aim to build the GWT code as well there are some steps left.
The Grails GWT plugin depends on a GWT install directory and does so by the usage of the environment variable “GWT_HOME”. To support this in Jenkins we need to install one more plugin. To do that navigate to Jankins Builds -> Manage Jenkins -> Manage Plugins look under available plugins after “Hudson Setenv plugin” and enable it. Now we also need to make the GWT install directory reachable by the build environment. This can be done by uploading it to you private repository in cloudbees. You should have three different repositories available namely a “private”, a “release” and a “snapshot” repository these can all be mounted as webdav drives. Mount your private repository and upload your GWT install directory into it (you should note that a GWT installation is quite heavy aprox 300MB however that is with all java docs and example projects etc. Those should be left out, you shall only upload the .jar files from the installation directory.). Now navigate back to Jenkins Builds -> Click on your job you previously created -> Configure. In the configuration form look for the “Build Environment” section, check the “Set environment variables” and enter “GWT_HOME=/private/username/my-gwt-folder” were username should be the login you use to access cloudbees and my-gwt-folder should be the name you gave the folder which you placed all GWT .jar files into in the previous step. Voila! your are setup to build your Grails / GWT project in Jenkins on Cloudbees.
ShareKIT and authorize#error error unknown
Have you encountered this error when you try to share to facebook with the sharekit API? Then it might be that you have not entered the App ID (see facebook api) correctly. In my case I did not understand that the hash att the start of the App ID should be included. I only entered the App ID like so: “com.mydomain.myapp” however your App ID should look something like “adflkg.com.mydomain.myapp” where the “adflkg” is the part I forgot.
Debugging a grails application
I do from time to time tend to forget what the command line command for starting a grails application in debug mode is. So here it is if you also have forgotten it:
grails-debug run-app
HTML 5 cache manifest and NETWORK: section
If you experience problems when using the application cache feature (in the HTML 5 spec.) and online javascript. It is probably because you need to specify a NETWORK: section within your manifest file. This specifies the resource you expect to only work online (in my case google maps api). I thought that everything not specified in the manifest file would be treated as online resources. However as it turns out resources not specified in neither the CACHE: nor the NETWORK: section will / can behaive strange. To solve this in one blow just add a “NETWORK:*” section in your manifest file.
CACHE MANIFEST #Version 1.1 CACHE: myoffline_javascript.js NETWORK: *
Struts 2 build versioned css
A common problem a web developer faces is the way browsers cache css files. If not handled properly the end user could get a rather funny looking web page from time to time depending on how often the web page changes styling.
A way to circumvent this is to rename the web page top most css file each time the styling is changed. In a distributed development team it can easily get cumbersome to coordinate the renaming of the css file so that referring css links not get broken. Another issue with renaming of files in a development team (using any kind of versioning system) creates a lot of noise in the commit log.
If you are using maven as your compile agent there is a nice way to write the build version into the WAR MANIFEST file.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>minvolvo</warName>
<archive>
<manifestEntries>
<Implementation-Version>${project.version}-b${build.number}</Implementation-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
Having the version number in the manifest file you can use that version number to fool the browser that we change the css file name on each build.
Create logic which can read the version number from the manifest file.
public class ManifestBuilderImpl implements ManifestBuilder,
ServletContextAware {
private ServletContext servletContext;
@Override
public Manifest build(String relativePath) throws IOException {
File manifestFile = getRealPath(relativePath);
Manifest manifest = new Manifest();
manifest.read(new FileInputStream(manifestFile));
return manifest;
}
private File getRealPath(String relativePath) {
String realPath = String.format("%s%s", servletContext.getRealPath("/"), relativePath);
File manifestFile = new File(realPath);
return manifestFile;
}
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
}
Create some sort of cache to store the manifest values in a accessible manner for actions.
public class ManifestCacheImpl implements ManifestCache,
ServletContextAware {
private ManifestReader reader;
private ServletContext servletContext;
@Override
public String getManifestValue(String attributeName) {
String key = String.format("MANIFEST-%s", attributeName);
String value = (String) servletContext.getAttribute(key);
if(value == null){
value = reader.getManifestValue(attributeName);
if(StringUtils.isNotEmpty(value))
servletContext.setAttribute(key, value);
}
return value;
}
@Override
public String getVersionNumber() {
return getManifestValue("Implementation-Version");
}
public void setManifestReader(ManifestReader reader) {
this.reader = reader;
}
public ServletContext getServletContext() {
return servletContext;
}
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
}
Create a common Action class (or add the same logic to a action with the same responsibility) that all actions that need this dynamically renamed css inherit from. ex. GenericAction.
public class GenericAction extends ActionSupport implements ServletRequestAware,
ServletResponseAware, ServletContextAware {
private ServletContext servletContext;
protected HttpServletRequest request;
protected HttpServletResponse response;
protected HttpSession session;
protected ManifestCache manifestCache;
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
@Override
public void setServletRequest(HttpServletRequest httpServletRequest) {
this.request = httpServletRequest;
}
@Override
public void setServletResponse(HttpServletResponse httpServletResponse) {
this.response = httpServletResponse;
}
public HttpSession getSession(){
return request.getSession(true);
}
public ServletContext getServletContext() {
return servletContext;
}
public ManifestCache getManifestCache() {
return manifestCache;
}
public void setManifestCache(ManifestCache manifestCache) {
this.manifestCache = manifestCache;
}
public String getVersionNumber(){
return this.manifestCache.getVersionNumber();
}
public String getUrlFriendlyVersionNumber(){
return getVersionNumber().replace(".", "-");
}
}
In all jsp where you have your css link change to the following.
<link rel="stylesheet" type="text/css" href="/css/layout-<s:property value="urlFriendlyVersionNumber" default="static.css"/>">
Here we append the dynamically read property from GenericAction.getUrlFriendlyVersionNumber() to the css link path.
After this we now only need a Action which takes care of all requests made on “/css*”, disregards the version number and serves the actual “layout-static.css”.
public class VersionedCssAction extends GenericAction {
final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
@Qualifier("cssResource") private Resource resource;
private InputStream inputStream;
private final int CACHE_MAX_AGE = 86400;
private String resourcePath = "/css/layout-static.css";
@Action(value = "/css/*",
results = {
@Result(
name = ActionSupport.SUCCESS,
type = "stream",
params = {
"contentType", "text/css",
"inputName", "inputStream"
})
})
public String execute() {
response.setHeader("Cache-Control", String.format("max-age=%s", CACHE_MAX_AGE));
inputStream = getServletContext().getResourceAsStream(resourcePath);
return SUCCESS;
}
Thats it! As long as you create new versions for each deploy you will never get fluky behavior caused by css.
