Dynamische Codeausführung mit Groovy
Groovy…
• is an agile and dynamic language for the Java Virtual Machine
• builds upon the strengths of Java but has additional power features inspired by languages like Python, Ruby and Smalltalk
• makes modern programming features available to Java developers with almost-zero learning curve
• provides the ability to statically type check and statically compile your code
• supports Domain-Specific Languages and other compact syntax so your code becomes easy to read and maintain
• makes writing shell and build scripts easy with its powerful processing primitives, OO abilities and an Ant DSL
• increases developer productivity by reducing scaffolding code when developing web, GUI, database or console applications
• simplifies testing by supporting unit testing and mocking out-of-the-box
• seamlessly integrates with all existing Java classes and libraries
• compiles straight to Java bytecode so you can use it anywhere you can use Java
Quelle: http://groovy.codehaus.org/
Mit dem oberen Abschnitt sind die wichtigsten Merkmale der Programmiersprache Groogy umrissen. Ein Merkmal auf das ich an dieser Stelle eingehen möchte, ist die dynamische Codekompilierung und -ausführung.
Was bedeutet das?
Das bedeutet dass ich zur Laufzeit Groovy – Code auf meiner JVM kompilieren und ausführen kann und die Ergebnisse nahtlos in meinem bisherigen vorkompilierten Code verwenden. Abgefahren…oder?
Welche Vorteile bietet diese Möglichkeit?
Ich kann beispielsweise während der Laufzeit meiner Anwendung bestimmte Routinen bzw. Algorithmen etc. einfach austauschen. Einfach austauschen bedeutet: Ich muss nicht mehr meine gesamten Anwendungen re-deployen. Die Konsequenz daraus: Geringe Deploymentkosten (Zeit, Personal) sowie erhöhte Flexibilität, da ich auf sich ändernde Gegebenheiten schneller reagieren kann.
Wie wird dies realisiert?
Am besten lässt sich dies anhand des folgenden Beispiels demonstrieren:
/* Der Groovy – Code der ausgeführt warden soll. Dies kann von einer */
/* beliebigen Datenquelle stammen: Eine Datei auf dem Dateisystem, aus */
/* einer Tabelle einer Datenbank oder aus einem Dokument in einem */
/* Content Management System (CMS). Die Möglichkeiten sind vielfältig. */
String groovyCode = <GroovyCode>;
/* Holen des Parent – Classloaders (Dies ist die Klasse in der der */
/* Groovy – Code ausgeführt wird. */
ClassLoader parent = getClass().getClassLoader();
/* Instanzierung des Groovy – Classloaders */
GroovyClassLoader loader = new GroovyClassLoader(parent);
/* Vorbereiten einer Variable vom Typ “Class”. */
Class clazz = null;
/* Die Magie beginnt… */
try
{
clazz = loader.parseClass(groovyCode);
}
catch(Exception ex)
{
ex.printStackTrace();
}
/* Ist die Klasse erfolgreich geladen, wird eine neue Instanz */
/* dieser Klasse gebildet. */
GroovyObject groovyObject = (GroovyObject) clazz.newInstance();
/* Vorbereitung eines Parameters. */
Object[] args = new Object[1];
args[0] = 15;
/* Hier wird eine Methode im Groovy – Code mit den zuvor */
/* vorbereiteten Parametern aufgerufen */
Object result = groovyObject.invokeMethod(“calculate”, args);
/* Das Ergebnis des Methodenaufrufes wird an ausgegeben */
System.out.println(“Ergebnis: ” + result);
/* Hier der Code der zuvor geladenen Groovy – Klasse */
class GroovyClass{
def calculate(value) {
// „return“ – Anweisung nicht notwendig; letzte Anweisung
// einer Methode ist impliziert Rückgabewert
“hello, world” + 5 * value
};
}
Groovy – Code kann ebenso wie Java – Code einem Unit – Test unterzogen. Für Details siehe http://groovy.codehaus.org/Unit+Testing.