02Jun

Wer sich als Java-Entwickler bereits ein wenig mit der Sprache Groovy beschäftigt hat, wird während der Projektarbeit sicher schon einige Verwendungsmöglichkeiten für Groovy-Sprachkonstrukte gefunden haben. In den meisten Fällen betrifft dies eher relativ triviale Funktionen, wie Operationen im Dateisystem oder das Auswerten von Variablen eines Typs. Da aber gerade in der Erstellung von Prototypen die Evaluierung von Kernprozessen im Vordergrund steht, kann die ergänzende Verwendung von Skriptsprachen á la Groovy etwas mehr Geschwindigkeit und Flexibilität in die Entwicklung bringen.

Vorbereitungen

Um das eigene Projekt fit für den Groovy-Code zu machen, muss zunächst einmal die groovy-all-1.5.4.jar in den Build-Path aufgenommen werden. In der Regel findet sich diese Library im Verzeichnis der Groovy-Installation im Ordner \embeddable. Verwendet man Eclipse, so funktioniert das in etwa so ‘Project > Properties > Java Build Path > Libraries > Add External JARs…‘, wobei man es vorziehen sollte die Bibliothek in ein eigenes Projektverzeichnis zu kopieren (/lib) und von dort aus zu verlinken.

Theoretisch könnte es jetzt auch schon losgehen, aber ich denke die Wenigsten wollen beim Programmieren auf lieb gewonnene Features wie z.B Syntax Highlighting verzichten. Es gibt für die gängigsten IDE’s bereits Groovy-Plugins und ein paar Links dazu finden sich am Ende des Beitrages, wer mit Eclipse arbeitet kann mal einen Blick hierauf werfen. Die Plugins an sich sind zwar noch nicht 100% ausgereift und Autocompletion vermisst man stellenweise auch, aber hey - ich habe vor kurzem mit dem vi programmiert, auch das ging ;-)

Der erste Kontakt

Um einen schnellen Einstieg zu bekommen, soll ein kleines Beispielprojekt in Form eines Autohandels den Integrationsprozess veranschaulichen. Nachfolgend findet sich ein Listing zweier Interfaces die als Schnittstelle zur Groovy-Welt dienen.

package de.j2g.interfaces;

public interface ICar {
    public String getMake();
    public String getModel();
    public String getType();
    public double getPrice();
}

package de.j2g.interfaces;

import java.util.ArrayList;

public interface IGarage {
    public ArrayList<ICar> getCars();
}

Nachdem die Struktur steht, geht es an die Implementierung der Groovy-Klassen. In einem separaten Package wird die Klasse Car.groovy erzeugt, welche das Interface ICar implementiert:

package de.j2g.groovy

import de.j2g.interfaces.ICar;

class Car implements ICar {
    String make
    String model
    String type
    double price
}

Nein, hier wurde nicht vergessen die Methoden des Interfaces hinzuschreiben. Da Groovy die Getter- und Setter-Methoden zur bei Kompilierung selbst hinzufügt, müssen lediglich die Instanzvariablen definiert werden. Als Nächstes kommt die Implementierung der Garage.groovy:

package de.j2g.groovy

import de.j2g.interfaces.IGarage;
import de.j2g.interfaces.ICar;
import java.util.ArrayList;

class Garage implements IGarage {
    public ArrayList<ICar> getCars() {

    def cars = new ArrayList<ICar>()

    def car1 = new Car()
    car1.make = “Ford”
    car1.model = “SHELBY GT500″
    car1.type = “Sports Car”
    car1.price = 89000.00

    def car2 = new Car()
    car2.make = “Ford”
    car2.model = “Taurus”
    car2.type = “Full-Size”
    car2.price = 21000.00

    cars.add(car1)
    cars.add(car2)

    return cars
    }
}

Der Groovy-Teil steht, jetzt fehlt noch der Aufruf aus der Java-Welt. In der Main-Klasse werden als erstes die benötigten Groovy-Klassen über den mitgelieferten GroovyClassLoader geladen. Da nur die Methode getCars() der Garage.groovy angesprochen wird, muss auch nur diese Klasse explizit geladen werden. Alle abhängigen Klassen, in diesem Fall nur die Car.groovy, werden automatisch mitkompiliert und geladen. Ist die Klasse geladen, erzeugt man davon eine neue Instanz und castet diese auf das zuvor angelegte Interface IGarage.

package de.j2g.main;

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;

import java.util.ArrayList;

import org.codehaus.groovy.control.CompilationFailedException;

import de.j2g.interfaces.ICar;
import de.j2g.interfaces.IGarage;

public class CarDealer {

    public static void main(String[] args) {
        System.out.print(”Loading groovy classes… “);
        ClassLoader parent = CarDealer.class.getClassLoader();
        GroovyClassLoader loader = new GroovyClassLoader(parent);

        Class gGarage = null;

        try {
            gGarage = loader.loadClass(”de.j2g.groovy.Garage”);
        } catch (CompilationFailedException e) {
            …
        } catch (ClassNotFoundException e) {
            …
        }

        GroovyObject goGarage = null;
        try {
            goGarage = (GroovyObject) gGarage.newInstance();
        } catch (Exception e) {
            …
        }

        System.out.println(” done!”);

        IGarage garage = (IGarage) goGarage;
        ArrayList<ICar> cars = garage.getCars();

        for (ICar car : cars) {
            System.out.print(”\n” + car.getMake() + ” “);
            System.out.println(car.getModel());
            System.out.println(car.getPrice() + ” €”);
            System.out.println(car.getType());
        }
    }
}

Das Ausführen der Main-Class sollte folgende Ausgabe auf die Konsole bringen:

    Loading groovy classes... done!     

    Ford SHELBY GT500
    89000.0 €
    Sports Car
    

    Ford Taurus
    21000.0 €
    Full-Size

The Power of Groovy

Die Funktionen im oberen Beispiel hätte man sicher auch ebenso schnell in Java umsetzen können. Etwas Programmieraufwand konnte aber schon bei der Car.groovy gespart werden - es war nicht nötig die Getter- und Setter zu definieren. Um nun die Effizienz der Skriptsprache noch etwas deutlicher zu machen, wird im Folgenden die Klasse Garage.groovy um einen FileReader erweitert:

cars.txt

    Toyota;Camry;34000;Full-Size
    VW;Golf;25000;Economy

Garage.groovy

public ArrayList<ICar> getCars() {
    def cars = new ArrayList<ICar>()
    def carFile = new File(’D:/cars.txt’)

    carFile.eachLine {
        line ->
            def carArray = line.split(’;')
            def car = new Car()
            car.make = carArray[0]
            car.model = carArray[1]
            car.price = Integer.parseInt(carArray[2])
            car.type = carArray[3]
            cars.add(car)
    }
    return cars;
}

Fazit

Einfacher geht es kaum noch, wenig Code zur Funktionsimplementierung und optionales Exception-Handling machen Groovy zum idealen Begleiter für die Agile Entwicklung!

Groovy IDE Plugins: Eclipse IntelliJ JEdit Netbeans


Diesen Artikel kommentieren

E-Mail-Benachrichtigung ohne vorherige Kommentierung

Hier haben Sie die Möglichkeit, alle zukünftigen Kommentare zu diesem Artikel zu abonnieren - auch ohne selbst kommentiert zu haben.