Showing posts with label Groovy. Show all posts
Showing posts with label Groovy. Show all posts

Thursday, February 2, 2012

Base64 Decoding with Eclipse

There are very few things in software development that are equally annoying as localization topics, especially dealing with dates in different timezones and/or - and here is my all time favorite - encoding issues.

We have a lot of data and use a bunch of different technologies, languages, and platforms to process the data. With regard to encoding topics, this does not help much either. Someone in the company decided it could be a good idea to encode critical data, especially strings that are not under our direct control, with Base64 encoding. In this way, data exchange between different platforms and languages can be restricted to exchange (relatively simple) ASCII data.

And thus, we now have to deal a lot with Base64 encoded data. During creation of unit tests, debugging, or manual validation of productive data, there is a frequent need to decode Base64 literals. Most times I used one of the many free online tools for this purpose. Although these tools do what they promise, the associated workflow is kind of messy: step through a unit test in Eclipse, copy some Base64 string into clipboard, switch to the browser, find and open one of these conversion tools - if not already open, convert the string, copy the result, and take it back into Eclipse.

However, after a little preparation, leaving Eclipse is completely unnecessary. There is an Eclipse feature called External Tool Configurations which allows to execute arbitrary commands directly from Eclipse. On the other hand there is Groovy with its famous -e option to execute code in-line. Combining these two, it is possible to execute some Groovy helper code directly from Eclipse. With the help of meta programming Groovy extended Java's String class with several features, one of them a build-in Base64 decoding method. The remainder of this post describes how to configure a simple Base64 decoding tool in Eclipse.

  1. Open the External Tool Configuration dialog:
  2. Create a new configuration, give it a name, specify the path to the Groovy executable, and finally insert the code.
    The Arguments: text area contains the following code:
    -e "def input = '${string_prompt:Base64 decoding}';  
    println new String(input.decodeBase64())"
    
    The Eclipse variable ${string_prompt} makes a popup dialog appear which promts for an input value.
  3. Save the configuration

Base64 decoding can now be executed the following way:

  1. Select the newly created Tool
  2. Insert the string to convert and start conversion
  3. Read the result from the Console view

Thursday, September 8, 2011

Spock in a Gradle-Powered Groovy Project

Spock. Is. Great.
One can do wonderful things with Spock, at leat when it comes to testing software. One of the fun things is that one can use Spock both for Groovy and for Java and obviously for mixed projects as well. I'll write about usecases and examples in another post. This one is about setting up Spock for a Gradle-powered Groovy project.

Basic Build

Spock relies heavily on Groovy itself, so the desired Spock version has to match the Groovy dependency for the project.
I tried it with Groovy-1.8.1 and Spock-0.5-groovy-1.8.
Excerpt from the build.gradle file:
apply plugin: 'groovy'
apply plugin: 'eclipse'

repositories { 
  mavenCentral()
} 

dependencies {
  groovy 'org.codehaus.groovy:groovy-all:1.8.1'
  testCompile 'org.spockframework:spock-core:0.5-groovy-1.8'
}
However, the gradle eclipse fails with an unresolved dependency:
:eclipseClasspath
:: problems summary ::
:::: WARNINGS
		module not found: org.codehaus.groovy#groovy-all;1.8.0-beta-3-SNAPSHOT
[...]
FAILURE: Build failed with an exception.

* Where:
Build file '/home/thevis/spock-test/build.gradle'

* What went wrong:
Execution failed for task ':eclipseClasspath'.
Cause: Could not resolve all dependencies for configuration 'detachedConfiguration1':
    - unresolved dependency: org.codehaus.groovy#groovy-all;1.8.0-beta-3-SNAPSHOT: not found


* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 1.431 secs
What does this mean? gradle dependencies does not show any peculiarities. So I really don't know.
Fortunately, although kind of annoying, this is not really a problem for the project. Since the project is a Groovy project already, it is possible to exclude all the transitive Groovy dependency stuff introduced by Spock. One possibility is to change the Spock dependency in the build file to:
  testCompile ('org.spockframework:spock-core:0.5-groovy-1.8') {
    transitive = false
  }
Alternatively, one could also exclude just the single missing dependency explicitely:
  testCompile ('org.spockframework:spock-core:0.5-groovy-1.8') {
    exclude 'org.codehaus.groovy:groovy-all:1.8.0-beta-3-SNAPSHOT'
  }
Either way gradle eclipse will succeed.

Adding Optional Features

If you want to make use of Spock's mocking and stubbing support (and I'm sure you want) the basic configuration from above is kind of limited, since it allows only mocking of interfaces. Spock lets you also mock and stub classes and even bypass the standard object construction. For these purposes, Spock depends both on cglib-nodep and objenesis, but declares these dependencies as optional. Thus, we have to declare them ourselves:
  testCompile 'cglib:cglib-nodep:2.2'
  testCompile 'org.objenesis:objenesis:1.2'

Complete Build File

Finally, here is the build.gradle in its full glory providing full mock and stub support with Spock: Alternatively, one could also exclude just the single missing dependency explicitely:
apply plugin: 'groovy'
apply plugin: 'eclipse'

version = '0.1.0-SNAPSHOT'
sourceCompatibility = '1.6'

repositories { 
  mavenCentral()
} 

dependencies {
  groovy 'org.codehaus.groovy:groovy-all:1.8.1'

  testCompile ('org.spockframework:spock-core:0.5-groovy-1.8') {
    transitive = false
  }
  testCompile 'cglib:cglib-nodep:2.2'
  testCompile 'org.objenesis:objenesis:1.2'
  testCompile 'junit:junit:4.7'
}
Happy specifying!

Tuesday, August 30, 2011

Java + Clean Code = Groovy

Some months ago, I read Martin Fowler's Clean Code and discussed it every once a while with several professional Java developers working for different companies. Retrospectively, these discussions were twofold astonishing to me.
  1. A great deal of these developers seemed to know Clean Code or at least some cachy claims out of it. No one disagreed with Fowler.
  2. Most of them heard about Groovy, few of them know about Groovy and almost none of them does actually use Groovy.
Maybe I got it wrong, but in my understanding is the bottom line of Clean Code more or less: write code which is short, concise, self-documentary, and leaves no room for interpretation to the reader. You may guessed it by the title, but my understanding of Groovy is not too far away from that.
Recently, I had to provide a comma-separated list of IDs as a command line argument to an application. The IDs were a consecutive sequence of integer numbers. Too lazy to copy and paste the numbers I thought about the effort to generate the list. How would you do it in Java? In fact, you wouldn't, right? The time it takes to create a Java class with a main method, iterating integers, concatenate them with a StringBuilder, dealing with an redundant comma at the beginning or the end, and finally compiling this class only for a single execution won't pay off. Alternatives: copy and paste or learning bash (awk, python, perl, ... insert your scripting solution of choice).
Enter Groovy.
$ groovy -e 'println ((12345 .. 12355).join(","))'
12345,12346,12347,12348,12349,12350,12351,12352,12353,12354,12355
My assumption is, even if somebody had no idea what Groovy is all about, just by looking at the command, she'll guess the outcome of the command correctly. But what if the task was a bit more involved as only listing consecutive integers? What about filtering and transforming result entries? Suppose, out of curiosity you want to list all the numbers between 1 and 1000 dividable by 17 and containing a 9 as digit. The numbers should be listed line by line with proper line numbers (rather academic example, I know).
What about Java? The proper way to deal with collection filtering and decoration would be to use commons-collection or guava or something similar or providing own implementations of AbstractCollections with lots of anonymous inner classes even for this simple task. The not so clean Java solution could look like the following code.
class Dummy {
    public static void main (String[] args) {
        String result = "";
        int counter = 0;
        for (int i = 17; i <= 1000; i += 17) {
            if (("" + i).contains("9")) {
                result += (++counter) + ": " + i + "\n";
            }
        }
        System.out.print(result);
    }
}
It will work, but it is rather ugly. Moreover, one has to create a file (insert your editor of choice), compile it (javac), and run it (java) just for a single execution (and afterwards delete it). Many different tools and commands for a trival task. In contrast, the Groovy inline script solution is very short, concise, and self-documentary (and does not produce trash in the file system):
$ groovy -e 'counter = 0
> println ((1 .. 1000)                            /* iteration*/
>     .grep{it %17 == 0 && "${it}".contains("9")} /* filter */
>     .collect{"${++counter}: ${it}"}             /* decoration */
>     .join("\n"))'                               /* concatenation */
1: 119
2: 289
[...]
14: 969
15: 986
My biggest problem when working with Groovy is to become aware of lots and lots of wasted hours spent with developing clean code Java solutions which were given by Groovy as language features out of the box in a very concise manner. Don't get me wrong. I'm a big fan of the Java language and I like solutions with lovely design patterns. However, for some problems the full featured Java design patterns sledgehammer approach seems to be a little overkill, considering the opportunities Groovy might add to your default toolkit. Since integrating Groovy is merely a matter of adding jars to the classpath and tweak the IDE appropriately, I am astonished how few people do actually make use of Groovy's opportunities.
Bad marketing, new technology anxiety, other limitations I'm not aware of? I simply don't get it.