Category: Software Dev


Travis CI for Android

I’m currently contributing to BiteMoi to teach myself some Android. When we kicked off the project we started with a Continuous Integration spike and Travis CI was the winner. Travis CI is a free hosted Continuous Integration platform for the Open Source community. This tutorial will get you up and running with the Maven Android quickstart project and Travis CI.

Prerequisites:

  • Maven (>= 3.0.3)
  • Android SDK

What is the plan?

The objective here is to hook up a skeleton Maven Android project (hosted on GitHub) to Travis CI. We will then configure Travis CI to build our project when we push code changes.

The BiteMoi project grew from Android Maven quickstart skeleton code. If you want to generate your own project you can use the android-maven-plugin using the android-quickstart-archetype by doing something like the following:

$ mvn archetype:generate -DarchetypeArtifactId=android-quickstart -DarchetypeGroupId=de.akquinet.android.archetypes -DarchetypeVersion=1.0.8 -DgroupId=com.codenes -DartifactId=my-android-application -Dplatform=16

At this point, if you’re using your own Maven quickstart project you should be able to build it by executing the Maven install goal on the command line:

$ mvn install

Maven will try to download the internets but be patient, it won’t happen every time. If you created your own project, it’s time to host it on GitHub.

It’s time for introductions

To introduce your project to Travis CI you will need to create a file called .travis.yml in the project root directory. This file basically contains a bunch of commands that instructs Travis CI how to build your project. Paste the following into your .travis.yml file:

language: java
jdk: oraclejdk7
before_install:
- sudo apt-get update -qq
- if [ `uname -m` = x86_64 ]; then sudo apt-get install -qq --force-yes libgd2-xpm ia32-libs ia32-libs-multiarch; fi
- wget http://dl.google.com/android/android-sdk_r21.0.1-linux.tgz
- tar -xzf android-sdk_r21.0.1-linux.tgz
- export ANDROID_HOME=~/build/BiteMoi/BiteMeAndroid/android-sdk-linux
- export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
- android update sdk --filter platform-tools,android-16,extra-android-support,android-17,sysimg-17 --no-ui --force

The commands we pasted are basically telling Travis CI to do the following:

  1. Spin up a Vagrant VM suitable for Java development
  2. Use Oracle JDK 7
  3. Get info about the latest packages available to me
  4. The Travis VM has a 64 bit OS but I need to install a lib that will allow me to run 32 bit Android SDK on it
  5. Download the Android SDK r21.0.1 Linux distro
  6. Explode the Android SDK distro
  7. Setup my ANDROID_HOME environment variable
  8. Put Android tools and platform-tools on my PATH
  9. Download Android platform 16 (we don’t want all platforms as we have limited space in the Travis CI environment)

Add the new file to Git in your root project directory and commit your project.

Travis CI Configuration

  1. Create a Travis CI account (you can sign in with GitHub)
  2. Navigate to your Travis Profile page
  3. Select and copy your Travis CI token

GitHub Configuration

  1. Navigate to your project on GitHub
  2. Select Settings
  3. Select Service Hooks
  4. Under the Available Service Hooks section select Travis
  5. Under User enter your Travis CI username
  6. Under Token paste your Travis CI token
  7. Check the Active checkbox
  8. Press the Update Settings button
  9. To trigger a Travis CI build from GitHub press the Test Hook button

When I first did this it took AGES for Travis CI to pick up my build. Do not despair. You can help things along by enabling the service hook via your Travis CI Profile page. Navigate to your project repository and turn on the Travis service hook for your project. Sometimes the Travis CI job queue is so big that your job will take a while to get to the top of the queue. This is really annoying as you won’t get instant feedback about your commit and you will have to wait a while to discover if you broke the build in the CI environment.

Travis CI Build

At this point you should have a successful build in Travis CI. See the console output here for the equivalent BiteMoi first green build (note the project has since been forked). By default, Travis picks up that we have a Maven project and executes the Maven install goal for us so we don’t need to put it in our .travis.yml file unless we want to execute a different goal.

Troubleshooting

It’s more than possible you don’t have a green build, to debug it you have a couple of options.

Basic

Inspect the Travis CI build console output and depending on what your error message is, try putting some basic debugging statements into your .travis.yml file e.g.

before_install:
- pwd // Print current working directory
- echo $PATH // Check your PATH environment variable
- mvn -v // What version of Maven is my Travis VM using?

And so on… You will quickly realize debugging in the Travis CI environment is a nightmare.

Better

When we develop code we want all of our environments to be as similar as possible. It is asking for trouble to develop on a Mac for example and then expect your build to work in the Travis CI (Linux) environment.

To set up a development environment that is close to the Travis CI VM we can use Vagrant and the Travis CI JVM Vagrant box to spin up our own development VM.

  1. Install Vagrant and VirtualBox
  2. Download the Travis CI JVM box (this file is ~3 gig)
  3. Add the Travis CI JVM box to Vagrant:
  4. $ vagrant box add travis-jvm /path/to/travis-jvm.box
  5. Create a directory to store your vagrant file:
  6. $ mkdir travis-dev
    $ cd travis-dev
  7. Initialise the VM:
  8. $ vagrant init travis-jvm
  9. Edit your Vagrantfile:
  10. $ vim Vagrantfile
  11. Insert the following in the Vagrant::Config.run do |config| section:
  12. config.ssh.username = "travis"
  13. Spin up the VM:
  14. $ vagrant up
  15. SSH to the VM:
  16. $ vagrant ssh

Once you SSH to your VM you are ready to Git clone your repo and start developing on your Travis development VM. Before you commit code, execute your Travis commands locally. If your builds are passing locally you can be pretty confident they will pass in the Travis CI environment.

Sencha recently introduced a Sass and Compass based theming system to customise the look and feel of Ext JS 4.x web applications. I recently had a play around to see how easy it would be to customise a button in Ext JS 4.1.

I’m using:

  • Mac OS X 10.7.4 (Lion)
  • Ext JS 4.1
  • Compass 0.12.1
  • Sass 3.1.17
  • SenchaSDKTools-1.2.3

To keep things simple, I’m going to modify one of the Ext JS 4.1 examples so you don’t have to create a new project to see how it works.

  1. First up, download Ext JS 4.1 (GPL).
  2. Unzip the download to your local web server. Note. If you are on a Mac you already have Apache web server installed. Make sure your firewall is on Apple -> System Preferences… -> Security and Privacy -> Firewall tab. Next, go to Apple -> System Preferences… -> Sharing. Check “Web Sharing” and select  ”Open Computer Website Folder”. Drop the exploded download “extjs-4.1.0″ into this folder (/Library/WebServer).
  3. Check that your web server is working by opening a browser and navigating to “http://localhost/extjs-4.1.0/examples/form/checkout.html”. You should see something like this:
  4. Before we go any further we need to install Compass. If you are on a Mac you already have Xcode which automatically installs Ruby so you are ready to install the Compass gem on the command line. Open a Terminal and enter:
  5. $ sudo gem install compass
  6. Download and install Sencha SDK Tools. This step is optional but recommended if you are developing your own apps and wish to utilise the slicer and/or JSBuilder tools at a later date.
  7. Back in the Terminal, navigate to “/Library/WebServer/Documents/extjs-4.1.0/examples/form”:
  8. $ cd /Library/WebServer/Documents/extjs-4.1.0/examples/form
  9. Copy the “resources” template over from the Ext JS distribution to the current directory:
  10. $ cp -rf /Library/WebServer/Documents/extjs-4.1.0/resources/themes/templates/* .
  11. Change to the “resources” directory:
  12. $ cd resources
  13. Make an “images” directory:
  14. $ mkdir images
    $ cd images
    $ mkdir default
  15. Copy the “default” image resources over from the Ext JS distribution to the “default” directory you just created.
  16. $ cp -rf /Library/WebServer/Documents/extjs-4.1.0/resources/themes/images/default/* default
  17. Edit “config.rb” as follows (if you don’t like Vim use your favourite text editor) to configure the path to Ext JS 4.1 SDK:
  18. $ cd /Library/WebServer/Documents/extjs-4.1.0/examples/form/resources/sass
    $ vim config.rb
    ...
    # $ext_path: This should be the path of the Ext JS SDK relative to this file
    $ext_path = "../../../../../extjs-4.1.0"
    ...
  19. It’s time to customise “my-ext-theme.scss” as follows to create a new button UI called “purple”. Replace the contents of this file with the following:
  20. $ vim my-ext-theme.scss
    // Unless you want to include all components, you must set $include-default to false
    // IF you set this to true, you can also remove lines 10 to 38 of this file
    $include-default: false;
    
    // Insert your custom variables here.
    //$base-color: #dabeff;
    
    $light-purple: #dabeff;
    $medium-purple: #9e7dcb;
    
    @import 'ext4/default/all';
    
    // You may remove any of the following modules that you
    // do not use in order to create a smaller css file.
    @include extjs-boundlist;
    @include extjs-button;
    @include extjs-btn-group;
    @include extjs-form;
        @include extjs-form-field;
        @include extjs-form-fieldset;
        @include extjs-form-checkboxfield;
        @include extjs-form-checkboxgroup;
        @include extjs-form-triggerfield;
    @include extjs-panel;
    @include extjs-qtip;
    @include extjs-window;
    @include extjs-messagebox;
    @include extjs-viewport;
    
    @include extjs-button-ui(
    'purple-small',
    
    $border-radius: $button-small-border-radius,
    $border-width: $button-small-border-width, 
    
    $border-color: saturate($light-purple,10),
    $border-color-over: darken($light-purple,10),
    $border-color-focus: $light-purple,
    $border-color-pressed: darken($light-purple, 25),
    $border-color-disabled: gray,
    
    $padding: $button-small-padding,
    $text-padding: $button-small-text-padding,
    
    $background-color: saturate($light-purple,10),
    $background-color-over: darken($light-purple,10),
    $background-color-focus: $light-purple,
    $background-color-pressed: darken($light-purple,25),
    $background-color-disabled: gray,
    
    $background-gradient: color-stops(darken($light-purple, 10) 20%,darken($medium-purple, 10) 80%,darken($medium-purple, 10)),
    $background-gradient-over: color-stops(darken($light-purple, 15) 20%,darken($medium-purple, 15) 80%,darken($medium-purple, 15)),
    $background-gradient-focus: color-stops(saturate($light-purple, 10) 20%,saturate($medium-purple, 10) 80%,saturate($medium-purple, 10)),
    $background-gradient-pressed: color-stops(darken($light-purple, 15) 20%,darken($medium-purple, 15) 80%,darken($medium-purple, 15)),
    $background-gradient-disabled: $button-default-background-gradient-disabled,
    
    $color: $button-default-color,
    $color-over: $button-default-color-over,
    $color-focus: $button-default-color-focus,
    $color-pressed: $button-default-color-pressed,
    $color-disabled: $button-default-color-disabled,
    
    $font-size: $button-small-font-size,
    $font-size-over: $button-small-font-size-over,
    $font-size-focus: $button-small-font-size-focus,
    $font-size-pressed: $button-small-font-size-pressed,
    $font-size-disabled: $button-small-font-size-disabled,
    
    $font-weight: $button-small-font-weight,
    $font-weight-over: $button-small-font-weight-over,
    $font-weight-focus: $button-small-font-weight-focus,
    $font-weight-pressed: $button-small-font-weight-pressed,
    $font-weight-disabled: $button-small-font-weight-disabled,
    
    $font-family: $button-small-font-family,
    $font-family-over: $button-small-font-family-over,
    $font-family-focus: $button-small-font-family-focus,
    $font-family-pressed: $button-small-font-family-pressed,
    $font-family-disabled: $button-small-font-family-disabled,
    
    $icon-size: $button-small-icon-size
    );
    
    // This line changes the location of your images when creating UIs to be relative instead of within the ExtJS directory.
    // You MUST set this to true/string value if you are creating new UIs + supporting legacy browsers.
    // This only applies to new UIs. It does not apply to default component images (i.e. when changing $base-color)
    // The value can either be true, in which case the image path will be "../images/"
    // or a string, of where the path is
    $relative-image-path-for-uis: true; // defaults to "../images/" when true
  21. To turn our SCSS file into CSS, we need to compile it with Compass:
  22. $ compass compile my-ext-theme.scss
  23. The CSS file “my-ext-theme.css” is created under “/Library/WebServer/Documents/extjs-4.1.0/examples/form/resources/css”. Note. To avoid compiling every time we make a change, set up a watch on “my-ext-theme.scss” so that any future changes to this file are automatically compiled for us:
  24. $ compass watch my-ext-theme.scss
  25. Now we need to modify “checkout.html” to use our CSS file:
  26. $ vim ../../checkout.html
    ...
    <!-- ExtJS -->
    <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
    <script type="text/javascript" src="../../ext-all.js"></script>
    <link rel="stylesheet" type="text/css" href="resources/css/my-ext-theme.css">
    ...
  27. To use our new button UI we need to modify “checkout.js” so that the “Complete Purchase” button specifies the “purple” button UI configuration:
  28. $ vim ../../checkout.js
    buttons: [{
                text: 'Reset',
                handler: function() {
                    this.up('form').getForm().reset();
                }
            }, {
                text: 'Complete Purchase',
                width: 150,
                ui: 'purple',
                handler: function() {
                    var form = this.up('form').getForm();
                    if (form.isValid()) {
                        Ext.MessageBox.alert('Submitted Values', form.getValues(true));
                    }
                }
            }]
  29. It’s time to preview our changes. Back in the browser, refresh “http://localhost/extjs-4.1.0/examples/form/checkout.html”. Note. If you are having issues seeing CSS changes in the browser, try clearing your cache (CTRL+Shift+delete) or inspecting the CSS for the page in a tool such as Firebug.
  30. Lets go one step further and change the base colour in “my-ext-theme.scss”. The “base-color” variable is a Ext JS global which we will set to the value of our custom “light-purple” variable:
  31. $ vim my-ext-theme.scss
    ...
    // Insert your custom variables here.
    $light-purple: #dabeff;
    $medium-purple: #9e7dcb;
    $base-color: $light-purple;
    ...
  32. Because we set up a watch earlier, all we need to do is save the file and refresh the page in the browser:

If you’re looking for the official docs to get started with Ext JS 4.x theming, checkout the Theming Learning Guide.

 

 

I’m learning Puppet and Cobbler at the moment, and one problem I had recently was getting Puppet to automate OpenSSL self signed certificate generation. Scripting it just proved to be a little bit of a pain and so I’m hoping by posting my script here it might help someone faced with the same problem. First and foremost, I need to give big ups to this blog entry I found which mine is clearly based upon.

The following script has been tested on CentOS 6.2 with httpd and mod_ssl installed.

Note. The plain text password in this snippet is clearly not secure so you will want to harden it up for your purposes.

#!/bin/sh

echodo()
{
    echo "${@}"
	(${@})
}

yearmon()
{
    date '+%Y%m%d'
}

fqdn()
{
    (nslookup ${1} 2>&1 ¦¦ echo Name ${1}) \
	    ¦ tail -3 ¦ grep Name¦ sed -e 's,.*e:[ \t]*,,'
}

C=AU
ST=SA
L=Adelaide
O=codenes
OU=nes
HOST=${1:-`hostname`}
DATE=`yearmon`
CN=`fqdn $HOST`

csr="${HOST}.csr"
key="${HOST}.key"
cert="${HOST}.cert"

# Create the certificate signing request
openssl req -config /etc/pki/tls/openssl.cnf -new -passin pass:password -passout pass:password -out $csr <<EOF
${C}
${ST}
${L}
${O}
${OU}
${CN}
$USER@${CN}
.
.
EOF
echo ""

[ -f ${csr} ] && echodo openssl req -text -noout -in ${csr}
echo ""

# Create the Key
openssl rsa -in privkey.pem -passin pass:password -passout pass:password -out ${key}

# Create the Certificate
openssl x509 -in ${csr} -out ${cert} -req -signkey ${key} -days 1000

If you put this snippet in a file e.g. genSelfSignedCert.sh it’s just a matter of configuring Puppet to copy the script over to your destination machine and execute it.

Surprisingly it is not straightforward to draw a circle in Google Earth. Googling led me to this KML Circle Generator web form which is currently not working. Submitting the form leads to “Go back and make sure you have entered the values we need”. So I found this alternative which does the trick.

Browse to Google Maps and paste the following URL into the “Google” search field:

http://www.nearby.org.uk/google/circle.kml.php?radius=5km&lat=-34.928622&long=138.599958&geomColor=ffffffff

Modify the URL with your own lat, lon, radius, units*, and geometry colour and press Enter. Google Maps displays your location as the center of a point radius.

* Supported units are kilometers, miles, meters, feet and km.

Fixed Circle in Google Maps

Fixed Circle in Google Maps

To view the circle in Google Earth paste the same URL into the URL address field of your browser and press enter. The file “circle.kml” is generated and downloaded by the browser. Browse to your download folder and open the KML file in Google Earth and wholah.

Fixed Circle in Google Earth

Fixed Circle in Google Earth

Android Helloworld

I’m just starting to look at writing Android apps for the first time and lets just say my Helloworld experience was not ideal. Things just didn’t exactly work first go and when it did work it would suddenly stop working, then start working again and so on (see Troubleshooting for details). Not all that inspiring when all you are trying to run is Helloworld!

Preconditions

Allow me to set the scene:

Platform: Mac OS X 10.6.5 (Snow Leopard)
IDE: Eclipse
Android SDK: 2.3

I’m using Eclipse because it would seem that it has better Android support than NetBeans currently (and comes recommended by http://developer.android.com) so let’s roll with that. Being a Java developer I already had Eclipse Java EE for Web Developers – Galileo (64-bit) on my machine so I am using that. Check http://developer.android.com/sdk/requirements.html to see if your version of Eclipse is compatible before proceeding.

Setup

I will try and gloss over the setup instructions for Android dev since you can find them in great detail online already. In brief:

  1. Download the Android SDK http://developer.android.com/sdk/index.html and extract (avoid white space in your path to SDK). Add/modify your PATH variable within .bash-profile (where <pathToAndroidSDK> is something like “yourInstallPath/android-sdk-mac_86″):
  2. export PATH=${PATH}:<pathToAndroidSDK>/platform-tools:<pathToAndroidSDK>/tools
  1. Install the ADP plug-in for Eclipse. In Eclipse go to Help –> Install New Software… –> Work with: https://dl-ssl.google.com/android/eclipse/ –> Press Enter. Check “Developer Tools” when it appears in the list and complete the install.
  2. Open Android SDK and AVD Manager (Note. This can also be done inside Eclipse Window –> Android SDK and AVD Manager) :
  3. $ cd <pathToAndroidSDK>/tools
    $ ./android
  4. In Android SDK and AVD Manager create a new virtual device. Mine had the following custom properties:
  5. Name: Android2.3
    Target: Android 2.3 - API Level 9
  6. Once your AVD has been successfully created, start Eclipse.
  7. In Eclipse, create a new Android project File –> New Project –> Android Project. Mine had the following custom properties:
  8. Project Name: AndroidHello
    Build Target: Android 2.3
    Application Name: Hello
    Package Name: com.codenes
    Create Activity: AndroidHello
    Min SDK Version: 9
  9. Expand the newly created project in the package explorer. Under the src directory you will find AndroidHello.java. We are going to modify this file ever so slightly to present the text “Hello, Android” on application startup. Modify this file to look like the following:
  10. Save your project. Let’s try and run it. Right click on your project in the package explorer and select Run As –> Android Application.
  11. You should see the emulator appear and your Eclipse console should print out some promising messages as it launches the emulator, uploads, installs and finally starts your app. I have to say that this whole process is pretty darn slow for my liking.
  12. The only notable thing at this point is the application doesn’t always start up automatically which was what I expected. It seems like it only does the first time it is loaded onto a new emulator as far as I can tell. I found that I had to hit the menu button subsequent times to launch it.
  13. Check out your app (in all it’s awesomeness) then navigate to the apps screen in the emulator to discover that it can also be launched through the icon “AndroidHello”.

Removing Your Application

  1. Start the Emulator if it is not already running.
  2. Open a terminal:
$ cd <pathToAndroidSDK>/platform-tools
$ ./adb shell
# cd data/app
# ls (to view all of the .apk apps installed on the emulator)
# rm <yourApp.apk>
# exit

Troubleshooting

  • Be careful specifying a SD card size when creating your Android Virtual Device. Initially I put some default value in this field and I was getting the following error in the Eclipse console (app killed almost immediately after startup):
  • Use LogCat to examine more meaningful error messages if you are having problems running your app. In Eclipse go to Window –> Show View –> Other –> Android –> LogCat. E.g. for the above problem with the SD card value I was seeing “Low Memory” messages in LogCat prior to processes being killed which led me to the problem.

I’m going to assume that you have already created a new SVN repository for your project in preparation for the import. As a headsup, I came into problems when I created a SVN repository with default folder structure (branches/tags/trunk) so if you encounter issues trying to import the dump file (step 6) you may need to remove your default folder structure from the SVN repository and try again.

Note. I would not attempt to import the CVS Repository from a production environment, work from a copy.

  1. Download cvs2svn (http://cvs2svn.tigris.org/) and untar the tarball cvs2svn-2.3.0.tar.gz.
  2. If you are on a Windows box, download and install Cygwin (http://Cygwin.com/setup.exe). Choose the following options during installation:
    - Install from the Internet
    - Choose install location E.g. C:\cygwin (all users)
    - Use IE5 Settings
    - Select Download Site: E.g. ftp://mirror.internode.on.net
    - Select the following packages: cvs, svn, cvs2svn, python, gnutls and rxvt (and any others you would like)
  3. Copy the extracted cvs2svn contents into your Cygwin user directory E.g. C:\cygwin\home\user\cvs2svn-2.3.0.
  4. Copy the “CVSROOT” folder and the module folder “yourProject” for your project from your CVS repository into a new folder “cvs” in your Cygwin user directory (C:\cygwin\home\user\cvs\).
  5. Run Cygwin and enter the following command *:
    $./cvs2svn-2.3.0/cvs2svn --dump-only --dumpfile ./cvs2svn.dump --fallback-encoding utf_8 ./cvs/
  6. Locate the svnadmin tool on the server hosting the SVN repository. It is now time to import the cvs2svn dump file into the SVN repository (where pathToDumpFile is the location of cvs2svn.dump generated in step 5).
    C:\Program Files\visualSVN Server\bin>svnadmin --parent-dir yourProject load pathToSVNRepository < pathToDumpFile
  7. Now is a good time to checkout the contents of the SVN repository (command line/TortoiseSVN) and check that everything is there as expected and the full history for your project is available.

* If the repository you are converting is huge and/or contains large binary files you may see “Memory Error” in the cvs2svn output which means it has fallen over. To easily fix this I suggest trimming the offending files out of the repository and repeating step 5. Note. the fallback encoding is optional, I found it was required when I converted my project due to the encoding of some commit comments.

Suitable for:

  • Glassfish Application Server V2.1
  • Windows XP

In a production environment we want Glassfish Application Server to be running with no users logged into the host machine (WinXP in this case). This post explains how to run Glassfish as a service which will automatically start up when the host machine is rebooted.

To create the service:

>sc create domain1 binPath= "C:\Sun\AppServer\lib\appservService.exe \"C:\Sun\AppServer\bin\asadmin.bat start-domain\" \"C:\Sun\AppServer\bin\asadmin.bat stop-domain\""

To check that the service has been successfully created right click on My Computer –> Manage –> Services and Applications -> Services. The service domain1 should appear in the list. Right click on the service –>Properties –> change the startup type to be Automatic and select Apply, then OK. The service should run as Local System (default).

If you need to remove the service, run the following command (make sure the Computer Management window is closed first):

sc delete domain1

Note. Glassfish can be controlled by the command line, through an IDE or as a service. It is not recommended to mix these approaches when stopping and starting the server.

Recently I started noticing this irritating message (repeated multiple times) in my NetBeans Glassfish Application Server log. The message is triggered by Glassfish start up and on application deployment.

SEC5046: Audit: Authentication refused for [admin].
Web login failed: Login failed: javax.security.auth.login.LoginException: Failed file login for admin.

It annoys me because when I installed NetBeans, I specified my own admin password for Glassfish (instead of the default admin/adminadmin). Later when starting the Glassfish server through NetBeans, it prompts me for my password and I supply it yet stubbornly this message continues to appear in my log. What the hell NetBeans?

So I’ll admit I ignored it for a while.

Today, I fixed it. I simply went into the Glassfish admin console (http://localhost:4848) and changed the Administrator’s password to the one specified during NetBeans installation. I restarted Glassfish and what do you know the message is no more.

This is just a little post that comes about from my frustration in working with dates in Java. I say in Java, generally speaking, because it still bugs me that sometimes you end up with a java.util.Date object and sometimes with a java.util.Calendar and I constantly seem to have to convert between them to end up with the one that I actually want. To add to that in my GWT projects Calendar is not supported client side so I usually use Date which is not my preference.

Anyway, to end my little rant, the motivation for this post is actually javax.xml.datatype.XMLGregorianCalendar, all I could think of was not another one! I noticed in one of my web service projects that JAXB was binding <xsd:dateTime> to XMLGregorianCalendar when what I really wanted was a Calendar. I could have written a conversion method but that seemed stupid and I found a better solution in the form of JAXB binding declarations.

All you do is take your WSDL or XML schema and add the following annotation block below the <xsd:schema> element:

<xsd:schema

     targetNamespace="com.codenes"

     xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"

     xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"

     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"

     xmlns:xsd="http://www.w3.org/2001/XMLSchema"

     xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0">

     <xsd:annotation>

          <xsd:appinfo>

               <jaxb:globalBindings>

                    <jaxb:javaType name="java.util.Calendar" xmlType="xsd:dateTime" parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime" printMethod="javax.xml.bind.DatatypeConverter.printDateTime" />

               </jaxb:globalBindings>

          </xsd:appinfo>

     </xsd:annotation>

     ...

Note. The JAXB namespace and version are specified as attributes of the <xsd:schema> element.

After modifying my WSDL as above in NetBeans I then just refreshed the web service and did a build, and the xjc (JAXB Binding Compiler) generates source with Calendar objects in place of the default XMLGregorianCalendar.

Just a short post to say that I recently had this problem – I needed to get my event web service pushing messages to my GWT server side code. But how to expose the GWT server side code like a web service? The solution I found was using the GwtRpcCommLayer library. Using this library you can expose your GWT server side methods to any Java application (Swing or command line) or in my case a Java web service. It’s very straightforward to use and there is an example Eclipse project which you can easily get up and running. For my purposes I then used the gwt-comet library to push the event messages from the GWT server side code (without polling) to my GWT client side code/browser for presentation. Very cool!