Saturday, August 10, 2013

Moved

This blog has moved to wordpress!

Please update your bookmarks.

Friday, July 26, 2013

Review of the Grails Gradle Plugin

UPDATE: Using the bootstrap configuration for the Tomcat plugin excludes it from the grails-war task.

See https://github.com/grails/grails-gradle-plugin/pull/43


Gradle support for Grails is maturing slowly and I must say that I can't wait for Grails 3.0. "Oh yeah, I'm excited!" :-), almost.

There are still few bits that I'm not clear about though in terms of how tight the integration will be, not specifically from an IDE usage perspective.

I watched a presentation from Luke Daley (aka alkemist) on Youtube(gr8conf 2013). It showcased the Gradle plugin for building Grails applications using the grails-gradle-plugin.

I was able to create a small POC and I want to share that experience with you.

General notes

Building a war and running Grails commands? Not a problem.
gradle grails-run-app
gradle grails-war

You can configure the Grails environment using -PgrailsEnv as command line argument.
-Dgrails.env= or -Pgrails.env= doesn't seem to work.

Arguments can be specified using -PgrailsArgs
gradle -PgrailsArgs='com.Domain' grails-create-domain-class

For some reason, the grails-gradle-plugin seems to require a closure with a Grails version specified twice (assuming that version is only used for bootstrapping the initial call??, while grailsVersion is used for building). I think that it should probably be consolidated...

grails {
  grailsVersion '2.2.3'
  version '2.2.3'
}

Below is a build.gradle file that does work for the Grails Gradle plugin 2.0.0-SNAPSHOT. Dump the file into some folder and run gradle init first.

buildscript {
  repositories {
    mavenCentral()
    maven { url 'http://repository.jboss.org/maven2/' }
    maven { url 'http://repo.grails.org/grails/repo' }
    maven { url 'http://repo.grails.org/grails/plugins' }
    maven { url 'http://repository.springsource.com/maven/bundles/release' }
    maven { url 'http://repository.springsource.com/maven/bundles/external' }
    maven { url 'http://repository.springsource.com/maven/libraries/release' }
    maven { url 'http://repository.springsource.com/maven/libraries/external' }
  }

  dependencies {
    classpath 'org.grails:grails-gradle-plugin:2.0.0-SNAPSHOT',
    'org.grails:grails-bootstrap:2.2.3' 
  }
}

version='0.0.1'

apply plugin: 'grails'

repositories {
  mavenCentral()
  maven { url 'http://repository.jboss.org/maven2/' }
  maven { url 'http://repo.grails.org/grails/repo' }
  maven { url 'http://repo.grails.org/grails/plugins' }
  maven { url 'http://repository.springsource.com/maven/bundles/release' }
  maven { url 'http://repository.springsource.com/maven/bundles/external' }
  maven { url 'http://repository.springsource.com/maven/libraries/release' }
  maven { url 'http://repository.springsource.com/maven/libraries/external' }  
}

grails {
  grailsVersion '2.2.3'
  version '2.2.3'
}

configurations {
  all {
    exclude module: 'commons-logging'
    exclude module: 'xml-apis'
  }
  test {
    exclude module: 'groovy-all'
  }
  compile {
    exclude module: 'hibernate'
  }
}

dependencies {
  compile( "org.grails:grails-crud:$grails.grailsVersion",
           'org.grails:grails-gorm:1.3.7')

  bootstrap "org.grails:grails-plugin-tomcat:$grails.grailsVersion"
}

Sunday, June 30, 2013

About Java Software Installers and Launchers

1 Introduction

In the early stages of your software projects, it's a good practice to think about the distribution aspect. It doesn't matter how good a product is, if no one can perform the installation or run the application.

Generating software installers is not always easy, regardless of the installer product used.

If you're lucky enough to have a good commercial software installer, you can generate quickly packages without too much pain:

  • Easy generation of application launchers.
  • Good default settings with flexibility for splash screens, installer icons, pre-installation/post-installation actions, etc.
  • Generation of software packages for a variety of platforms (OSX, Unix, Linux, Windows, etc.).

2 Application launchers

Now that your application development phase is complete, you may be worried about writing couple of launchers.

Writing a Java application launcher can become fairly complicated depending on :

  • The amount of libraries dependencies used by the program.
  • The configurations and properties to resolve or create in order to run the application properly.
  • Any tasks that need to be executed prior to launching the application.

For Java based applications, below are the common steps performed by launchers scripts:

  • Find the Java executable (JAVA_HOME detection if needed, common locations depending on the Operating System).
  • Validate the Java version requirements as well as potential optional settings.
  • Setup any environment variables or system properties needed by the application.
  • Construct the Java classpath from the application dependencies.
  • Perform any actions need prior to launching the program.
  • Invoke the Java command with the classpath and JVM arguments to start the application.

ClassWorlds is a simple Java application launcher framework that has been around for a while. It superseeded the forehead framework launcher. Forehead was used by many tools such as Maven (now using ClassWorlds).

What makes ClassWorlds compelling is that it's really easy to bootstrap an application launcher without much effort. All that Classworlds needs is a simple java command that references a boot jar file and your application configuration file(to load libraries).

3 Software Installers and packaging

Depending on the application's type, target audience and operating systems, many options are available. Commercial Software package generators usually provide good results without too much work. Decent to really good products for Java software packaging include InstallAnywhere and Install4j.

Some free Java-oriented installers generators can be found on java-source.net. A popular choice is IzPack.

Generating software packages by hand still gives you an overall better user's installation experience at the expense of time and potential bugs (typos, logic errors, etc.).

When your installation packages are ready, you then need to test them on all supported platforms, just to be safe.

Zip distributions are very convenient for many users:

  • No administration rights needed most of the time, which is useful when you don't have administrative rights on a machine.
  • One step installation, just a matter of extracting a software archive.
  • Easy uninstallation which is a simple folder deletion.

When generating software packages, don't forget the simple way of distributing files via zip archives.

Saturday, June 22, 2013

A good dev Linux Distribution - Fast with many packages

Fast with many packages is not the only selection criteria for a Linux distribution, but it's important. "Click and wait... Download manually packages on a regular basis??" -> "no thanks".

I've used many Linux Distributions over the years: Redhat, Mandriva(previously Mandrake), Debian, Gentoo, Slackware, CentOS, Fedora, Knoppix, Suse, Zenwalk, Ubuntu, etc.

My main machine at work usually runs some Linux variant. I was lucky enough to always have that luxury since I started to work "As long as you don't need support and you can work with it, you can run Linux on your PC".

Linux distributions perceived speed
Redhat based distributions have to be the slowest around, so I tend not to use them, unless I have to. Among the fastest Linux distros(non minimalistic), I would count in Slackware, Gentoo and few others.

Today I tried Arch Linux for the first time. I must say that I'm very much impressed with the raw speed. I would even dare to say that it feels faster than Gentoo or Slackware, without any additional optimization or custom kernel compiled.

Linux distributions with nice package managers
Couple of years ago, RPM based distributions were annoying. It was a real dependency hell depending on where you grabbed your RPM package... Nowadays things are better(yum, etc.), but RPM dependency resolution traumatized me for good...

As soon as I was introduced to Debian, I never looked back. For a quick install in few minutes Ubuntu will do and for a server a pure Debian distro is nice. Once in a while, I try couple of Linux distributions just for fun.

Having a nice set of packages available is cool especially when your distribution has a "reliable and powerful" package manager.

What a dev like me wants from a Linux distro
These days, I only need few things from a Linux distro:
  • It has to be fast, as I like to multitask but I also have couple of GB of RAM to spare.
  • No RPM based distro, Debian or something else. I've always preferred Debian for its apt-get super powers. apt-get has been around for a while and I like it a LOT.
  • I don't need a graphical installer but I also don't want to a full installation from chroot with tons of steps, unless I have time to kill...
  • Many packages should be available via the package manager of the distribution, as I try to avoid compiling too many applications.
  • Flexible installation options (base system vs full desktop/server system). When I have time, I build a system with only what I need...



Saturday, June 01, 2013

Maven wrapper project - from Jar library to Maven plugin

Last month, the maven-wrapper project caught my attention on Github.

This morning, I had time to kill and I decided to take a closer look at it. I eventually played with it, forked it and added a quick and dirty feature "basic Maven plugin support".

The maven-wrapper project is a port of the Gradle wrapper to Maven.
It will download a Maven distribution automatically for you and set it up. Currently the project is just a library, more or less a work in progress at this time.

Again, I can't emphasize enough on the importance of build tools wrappers, especially on build machines. The release management folks doesn't need to follow any detailed setup guide, nor do they need to worry about managing multiple versions of the same build tools.

"Plugin-ifying" the maven-wrapper project
I did a very quick and dirty implementation of a Maven plugin, so that the code could be reused as a plugin in new or existing Maven project.

It was just a matter of adding few dependencies and writing a simple Mojo.
I eventually renamed the artifactId to have auto-mapping enabled in terms of namespace and goals.

Nowadays, it's possible to write Mojo descriptors with Java annotations instead of xdoclet-like comments.

I opened a pull request to merge the code in the original project few hours ago.

Maven wrapper plugin usage
Checkout the maven-wrapper forked project and run the Maven install goal.
mvn install

In another Maven project, add the following to your build->plugins section

    <build>
 ..
 
         <plugins>
   ..
      <plugin>
        <groupId>org.apache.maven</groupId>
        <artifactId>wrapper-maven-plugin</artifactId>
        <version>0.0.1-SNAPSHOT</version>
      </plugin>
   ..
    </plugins>
 ...
    </build>
    
Maven version compatibility
In terms of compilation, it should work with Maven 3.0.2 dependencies and above. The default distribution URL contains some maven versions from 2.0.9 to 3.0.5.
The distribution URL is not customizable automatically at this point (when generating the wrapper supporting files).


What would be nice to have in terms of configuration

  • POM driven customization of the default settings (launcher names and location, distribution URL). It's currently possible to do it manually though.
  • Token substitution inside the plugin when generating wrapper artifacts.


Saturday, May 11, 2013

Build Tools Wrappers

Today I stumbled upon a new project called maven-wrapper.
I haven't tested it myself, but it looks like a very promising effort. Users/Developers will be able to perform builds without an existing Maven installation.

Grails and Gradle already have a way to generate wrappers.
Antw seems similar to gvm in terms of concepts and approach.

Those tools wrappers allow users to build programs without having the software already installed on their local machines.

This is particularly interesting for build servers, and more specifically continuous integration servers:
  • Many projects may require different versions of a build tool.
  • Sometimes the setup of the build tools on a server involves following many processes and getting couple of approvals.
  • There's a risk of human error that will result into a corrupted non-working software installation (i.e. moving few files around to follow corporate conventions -> broken scripts, file permission issues, etc.).

There are often issues related to build tools in terms of software distribution and usage:
  • People got a copy of the source code, but they don't know how to build it.
  • The user knows the build tool to use, but he doesn't know how to set it up (Environment variables, PATH manipulation, etc.)
  • The user knows how to setup the build tool and build the application, but not how to configure the project inside an IDE
  • etc.

I expect more and more build tools (as well as full-stack frameworks) to provide the ability to generate seamless wrappers, as it is a very convenient feature.

Wednesday, March 06, 2013

Gradle over Maven for Groovy/Java projects

* "The Ant" problems

For many years, I've been down with Maven and I still am. In many projects, I've seen some gigantic Ant scripts. Ant has often been a maintenance nightmare in huge applications, fix a script and notice that your eyes are bleeding.

As "most"corporate developers don't use Ivy to resolve dependencies with Ant, you typically end up with 3 scenarios:

  • The dependencies are stored in the version control server, that can get people fired at few places.
  • There's some kind of repository concept with jars at dedicated locations (Windows shares, NFS, etc.). The dependency resolution involves tons of scripting or some Ant tasks.
  • Dependencies are stored at a secret location(mapped drive to a Windows share that you'll know about one day) and you can only build after lots of configurations.

Some of the good things about Ant are flexibility, accessibility, documentation. Most developers know how to use Ant and writing custom tasks is not usually hard.

Maven 

My initial Master thesis subject was supposed to be about Apache Maven, but I bailed out... If I recall correctly Maven had only beta releases at that time with very little documentation.

After downloading Maven binaries, I didn't know what to do and how to use it: close to zero documentation and not really "accessible". When I was about to finish my MBA, I decided to give it another shot. It felt like "I looked at Maven and I got scared...".

The Jelly Issue


While many people didn't like Jelly, it provided some basic scripting capabilities inside the build file. If I recall correctly plugins also needed some Jelly files and many developers were annoyed by that constraint.


Sometime ago, I wrote an automation tool with Commons Jelly to setup Web hosting on Tomcat.
The tool was a launcher with few relatively small Jelly scripts to perform the following:

  • Read the list of users from an excel spreadsheet or XML file 
  • Setup FTP accounts 
  • Modify the Tomcat XML files to create application context paths for Web applications 
  • Populate the user information in a database(credentials, ftp and tomcat information)
  • Send email notifications with the account details.


Understanding Jelly made my life easier with Maven until it reached 2.x and Jelly was dropped at that time, if I recall correctly.

Maven evolution

With Maven 2.x things got cleaner and more stable, documentation got better and so on. Still many companies didn't give Maven a second chance. Then came Maven 3 and things haven't changed that much at the corporate level.

Most Java development companies still use Ant and few of them use Ivy to resolve dependencies. I do see Maven here and there, time to time, but not that often.

Maven adoption

From my experience, Maven has always been an issue in non Open-Source projects: too complicated, not worth the effort, too much impact on the typical IDE or build/release workflows.

While convention over configuration introduces a potential "lack of control" or flexibility, it also have its pros.

Gradle to the rescue

In the past, I've not really been a big fan of any kind of dynamic or scripting language, unless it's used for scripting or as an extension module. I would probably never have considered Gradle and similar tools in the past, because it would have made me feel "uncomfortable".

Nowadays, I'm willing to take advantage of Groovy, Jython, Clojure or whatever.

If I were doing some Clojure, I would try cake or lein as build tool, unless there's a feature that I need that is only available in Maven. Why? For just 3 main reasons :
- A tool dedicated to a programming language, often means more power and integration.
- There are not many attempts to do too many things or to be too generic, things are easier.
- Having scriptable builds and zero XML is cool.

Accessible to Java Developers

While a Groovy DSL to write a build script is no XML or Java, it's more expressive.
Learning some basic Groovy concepts is easy for Java developers.

Solid documentation

I was impressed when I saw the Gradle manual. It's very good and it's easy to read and understand.

Readable files

Last year, after migrating few personal projects from Maven to Gradle, I felt relieved. I didn't have some crazy POM files, but still too much XML to write (or copy/paste).
The Gradle build files were easier to read/understand with less lines of code.

Flexibility

Adding custom tasks with Groovy Code, without writing plugins unless you need too, this is really nice. If you need plugins there are couple of them out there.

While there are not as many plugins for Gradle as for Maven, I believe that Gradle is getting more  momentum. Many projects such as Hibernate already switched from Maven to Gradle.