Wednesday, 20 June 2007

GWT and JSP 2.0 (Oh the Pain!)

So it's been four weeks now and I'm moving along at a steady pace with GWT.
I found by shear accident that a new feature added into GWT 1.4 is that you don't need the gwt.js anymore or the <meta..> tag in the HTML and you can just include the module.nocache.js file directly. (good change guys).

I have been trying to host my modules (GWT modules) into an already existing JSP page that is written in JSP 2.0 of the XML variety. I find these good because it means you are forced to create valid HTML markup. Anyways, combining the two, GWT and XML JSPs meant I was completely unable to get the GWT modules to attach and appear on the page.

I was getting JavaScript Errors, j.write is not a function. Now, the GWT compiler is compiling by default using the OBFuscation setting. Which means that the JavaScript, is well, obfuscated, a little hard to read. Not knowing yet what the other settings are to change it (I think there is detailed and something else I saw) I dove (breifly) into the JS to see what j.write was all about.

It took a bit to track down the problem.

Essentially weird things happen to your markup, it gets all compressed to one line (obfuscated HTML) and open, no content, close tag elements get changed to /> elements to make it more valid XML. For those that have worked with JSP XML documents (ie, the <jsp:root> ...</jsp:root> variety) will know what I am talking about.

The problem is that a jsp marked up this way just fails straight away with GWT in the works. I recalled a similar problem I had two years ago that was making javascript fail because the <script> tags written in the jsp as open <script> and closing </script> with no content in the middle (ie, a <script src="somefile.js"></script>) will get collapsed in the browsers view of the HTML as <script .. />. ie, just one tag.



To get around this JS error, back then, was to add a CDATA and put a comment delimeter in the CDATA. This way the JSP XML parser would preserve the open and close tags.

This looked like the following ..


<script src="somfile.js"><![CDATA[<!-- -->]]></script>


Which will bre rendered correctly as

<script src="somfile.js"><!-- --></script>

And the problem, can't remember what it was, but javascript loading issues, would work.

Alas, this was not my problem with GWT as I changed the <script ...></script> and the <iframe.../> to have this CDATA hack and it didn't resolve my j.write is not a function error.

So .. the quick simple test, cut and past the output of the JSP that has the GWT <script></script> in it, and put that as an HTML file and try that. So, refresh my broken page, view source, cut and paste the ugly format (hard to read for others) HTML and put it into a new .html file and load that, it worked.

So I have two files, tester.jsp which has the <jsp:root> top and bottom and then a html file which is the "output" viewed from the browser of this jsp file. So as far as the browser is concerned, hitting the /tester.jsp and /tester.html renders exactly the same looking HTML.

Which lead me to only one conclusion, it was not "format" of the HTML presented that the browser was barfing on, (and then GWT not loading) but rather the Headers that the server was sending that caused the problem.

Loading up firebug (just clicking my little firebug icon in firefox.. thank you thank you firebug authors), I inspected the headers of the tester.jsp and tester.html, low (lo) and behold,

tester.jsp : Content-Type: text/xml;charset=UTF-8
tester.html: Content-type: text/html

This then leads to the quick fix, change the content type for my JSP.

<jsp:root version="2.0" jsp="http://java.sun.com/JSP/Page">
<jsp:directive.page contenttype="text/html; charset=UTF-8"/>

And then all is good.

So, what is happening here ? It would appear that the browser (Firefox 2.0 on Mac OSX in this instance) is not creating a DOM that the GWT javascript can interact with when the content type is XML as opposed to when the content type is HTML.

This is evidenced by the line in question in the GWT module.nocache.js which is

j=document;

And a few lines in,

j.write("<script>...</script>")

From this called attempt to write out some dynamic javascript to the page, the specific error message obtained is as follows

j.write is not a function

Which just shows that the DOM is not how it is supposed to look. I am sure someone from the firefox community could explain that one a little more. (to how it structures the DOM based on content-type).

So this one was not because of GWT pain, but JSP pain :-)

All good so far. I have a few more improvements to the m2 GWT plugin which I will post in the next few days.

Saturday, 9 June 2007

GWT and Maven 2, OH the pain!

GWT - Maven2 and Eclipse .. Ouch!

Using GWT for all of 3 weeks now, I am finding it is nice. It's logical, well thought out and simple.

But, I think there is a little way to go when it comes to using some de jure standards. I am a big Maven 2 fan because in an Enterprise (captial E for 'ooh' fancy) environment, standards go a LONG way and Maven 2 dictates a nice and well understood way of doing things.

So, what's me beef with GWT ? Simply this, gosh it has been hard to get it working with Maven 2.

Now, part of this is because I am still trying to get my head around how it works. I have been using the applicationCreator script to setup a quick hello world sample, then move that into the src/main/java and src/main/resources folders.
But what does that do to my src/main/webapp ? where do the images get pulled from ? why don't index.jsp load in the GWTShell (when it's tomcat underneath) ? So many questions.

So, there is a maven 2 plugin. I am currently using the 1.5.2 version of it.

Google Code Homepage : http://code.google.com/p/gwt-maven/
Maven 2 Plugin Doc : http://gwt-maven.googlecode.com/...
A list of some problems : http://code.google.com/p/gwt-maven/wiki/FAQ
Maven Repo : http://gwt-maven.googlecode.com/...
SVN Repository : http://gwt-maven.googlecode.com/.../

and as it turns out, there are a few bugs and features which need some work. (I wish I saw that FAQ page first before diving in)

The first issue I cam across was the "plural" vs "singular" naming convention. In Maven 2, a configuration item for a plugin that requires more than one value is pluralised .. ie

<options>
<option>...</option>
<option>...</option>

</options>

What's the problem ?

Well, the com.totsp.gwt plugin needs a configuration line like

<compiletarget>org.sobbo.ui.Home</compiletarget>

However, this config value in the plugin source needs an [] array or targets. (logical yes) but m2 plugins, dictate that the property name is then plural (compileTargets) otherwise you get this kind of error message.

[INFO] Failed to configure plugin parameters for: com.totsp.gwt:maven-googlewebtoolkit2-plugin:1.5.3-SNAPSHOT

(found static expression: 'org.sobbo.ui.client.Home' which may act as a default value).

Cause: Cannot assign configuration entry 'compileTarget' to 'class [Ljava.lang.String;' from 'org.sobbo.ui.client.Home', which is of type class java.lang.String

so .. the AbstractGWTMojo has to change to have a plural of configurationTargets (there must be a way else how would they be using it right now ?

It turns out there is an issue logged for this .. http://code.google.com/p/gwt-maven/issues/detail?id=37

Anyways, what's the next pain ? well to checkout the src from the subversion repository, you get this nice little gem.

$ svn co http://gwt-maven.googlecode.com/svn/trunk/maven-googlewebtoolkit2-plugin/

svn: REPORT request failed on '/svn/!svn/vcc/default'
svn: REPORT of '/svn/!svn/vcc/default': 400 Bad Request (http://gwt-maven.googlecode.com)

BANG, and there is my pain. This looks like a straight up Google SVN problem. Funny enough, I have an SVN downloaded script that works to "download" src from SVN repositories using wget.

See the end of this post for the shell script.

So .. my third issue ? Well there was some unusual "Java Execution Mojo Bootstrapping" stuff going on, and it's broken. Essentially when trying to launch java to compile (testing, shell etc) it (the GWT maven plugin) couldn't find it (java) and died. I found the problem (after downloading the src and corrected it) and logged this issue with a patch @ GWT M2 Plugin Issue 43

So .. is it ready ? This Maven 2 plugin really needs to be working, maven 2 is big and GWT / M2 / Spring / Eclipse is pretty important (to me at least).

I'll keep battling with it because this way I can probably make it a little better. I hope that it gets better.

So, that SVN downloader script, it's not completely "safe" because the revision could change by a third party part way through your download, but hey, it works.
#!/bin/sh
# Author: Ramon Buckland ramon#at#thebuckland.com
# Quick hack script to pull the latest SVN Revision version from a repo repo when you have no SVN tools
# or SVN through ISA proxy servers are just not working ..
#


function usage {
echo "$0 "
echo "svn-url: SVN URL is a URL to the trunk or a tag you interested in"
echo " eg: http://svn.apache.org/repos/asf/incubator/servicemix/trunk/"
echo "product-name: A short name of the product so that we can create a directory for you"
echo " eg: servicemix"
echo "(also, set the http_proxy=http://hostrunning-ntlmaps:port)"
exit
}

if [ "X$1" == 'X' ]; then
usage
fi

if [ "X$2" == 'X' ]; then
usage
fi

if [ "X$http_proxy" == 'X' ]; then
echo "WARNING: http_proxy is not set. Do you need it ?"
fi

SVN_REPO=$1
PRODUCT_NAME=$2

mkdir ${PRODUCT_NAME}-svn-pid-$$
cd ${PRODUCT_NAME}-svn-pid-$$

# nv=non-verbose
# nH=noHost directory created
# -np=no ascend to paremt dirs
# --cut-dirs=3
# -erobots=off .. don't look at robots.txt to see what you are and aren't allowed to do
# -m mirror

wget -nv -nH -np --cut-dirs=3 -erobots=off -m ${SVN_REPO}

NEWDIR=`grep Revision index.html | grep h2 | cut -d':' -f1 | cut -d'>' -f2 | tr ' ' _`
cd ..
mv ${PRODUCT_NAME}-svn-pid-$$ ${PRODUCT_NAME}-svn-${NEWDIR}
find . -type f -name index.html | xargs rm


Hope that helps someone. I use it a bit here and there.

Tuesday, 5 June 2007

Switching Domains

In my new role I have been pouring my brain into a new domain (industry) for the past 2 weeks.

For the years I have been writing code, moving from one language to another has never a big issue. ie, from Pascal to Modula-2, C to C++, Perl in the middle, Java from the dawn of ages, dabble in C#, poor over XML and become a quasi-guru in XSLT's. So when a new language comes about, it's a matter of learning a new language construct or few (expansion of the language domain) and then give it a crack. Being bi-lingual is not too difficult. It is probably because not a lot of things have been written under the sun recently that bend the brain.

For the most part, the "spoken language description" or nomenclature of the languages is the same ie: objects, methods, procedures, closures, fucntions, instance variables, parameters etc. So only when someone bakes up a new "thing" and gives it a name, do you have a learning exercise. This is to exclude the obvious of learning a new feature or third party system which is ever-on-going.

For those who have been coding for many years in many languages you will know what I mean. It's fun looking at new languages and it's not long before you are proficient. For ths most part, coding in another language is only slowed by the environment in which it has to operate, so OS, execution platform (JVM, native) the IDEs, no IDE, dynamic, compiled etc.

So .. how about switching the domain in which you are coding for? This, I have not done often. I have currently side stepped from funds management and trading over to insurance. I knew there would be challenges and yes there are. Insurance is another whole industry unto itself, there certainly are links and in the FM and Trading game you come across these links a bit.

It's not so much the concepts of insurance, they are easy, or easy enough, but it's the nomenclature that is used and when it applies, and who owns what. My view point is that I MUST be proficient in understanding the business before I can really code. Sometimes you won't have that luxury, perhaps due to time pressure. But if you work for an ISV or interact with a department, not being able to speak their language gives you no credibility and also makes you untrust worthy. The business domain experts will instantly pick up on this.

I am studying insurance like it's a new degree for me.

.. it's real Domain Driven Design back again (for me). It's fun. It's fun because it's forcing me to think outside the square and, as an outsider (at the moment) see how things work and then twist my brain around it to understand how it hangs together.

A policy, quotations, indications, endorsements, declines.. the list goes on. and to write a system I first have to understand the domain.

It reminds me of 7 years ago when I was first cutting systems for fund management. What a battle in the brain that was. I am finding this new domain a bit easier now than then. Perhaps because I know the right types of questions.

I think working with business people who are amenable to your plight (lack of knowledge) helps, of course :-)

So.. I encourage anyone who faces new domains, often or not often, study it, learn it. You will be noted as a good developer simply because it shows you actually do care. And, BTW, this goes for not only coding, but Systems support and DBA's and everyone.

We are like Vets, we have to know a lot in order to do our job.

Current 5 booksmarks @ del.icio.us/pefdus