Donnerstag, 11. Oktober 2012

Grails WAR mit Maven auf einen entfernten Tomcat deployen

Zum kompilieren einer Grails Applikation wird das Grails Plugin verwendet. Das produzierte Artefakt kann dann durch Verwendung des Cargo Maven Plugins auf einen entfernten Tomcat Server, in meinem Fall einem Tomcat 6, deployed werden.

Tomcat Einstellungen

Ich verwende Tomcat aus dem stable Repository von Debian Squeeze. Um später das Remote-Deployment durchführen zu können muss zusätzlich zum Package tomcat6 das Package tomcat6-admin installiert sein.

Mit root Berechtigung reicht die Ausführung des Kommandos:

    apt-get install tomcat6 tomcat6-admin

um  alles notwendige zu installieren.

Anschließend muss ein Tomcat-Benutzer  eingerichtet werden. Die Datei /var/lib/tomcat6/conf/tomcat-users.xml muss um die folgenden Einträge erweitert werden:

    <role rolename="manager-gui"/>
    <role rolename="manager-script"/>
    <role rolename="manager-jmx"/>
    <role rolename="manager-status"/>
    <user username="me" password="secret

          roles="manager-gui,manager-script,manager-jmx,manager-status"/>
Diese Erweiterung sorgt dafür, dass der Benutzer "me" mit dem Passwort "secret" Zugriff auf die Managementfunktionen des Tomcat bekommt.

Beim Deployment von Grails Applikationen kommt es häufig zu einem "out of PermGenSpace" Fehler. Um diesen zu vermeiden sollte die JAVA_OPTS Zeile in der Datei  /etc/default/tomcat6 um die Option -XX:MaxPermSize=256m erweitert werden. Dadurch wird der PermGenSpace auf 256 MByte vergrößert und reicht in den meisten Fällen aus.

Die JAVA_OPTS Zeile in /etc/default/tomcat6 sollte dann so aussehen:


    ...
    JAVA_OPTS="-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC
             -XX:MaxPermSize=256m"
    ...

Damit sind alle für Tomcat notwendigen Einstellungen vorgenommen und Tomcat muss mit:

    /etc/init.d/tomcat6 restart

neu gestartet werden, damit alle durchgeführten Änderungen wirksam werden.

MAVEN Einstellungen

In der pom.xml der Grails-Applikation wird das Cargo Plugin hinzugefügt. In der Plugin Konfiguration werden alle relevanten Daten wie der Server auf dem Deployed werden soll, sowie die oben festgelegten Zugangsdaten konfiguriert.
Beispiel:

        <plugin>
        <groupId>org.codehaus.cargo</groupId>
        <artifactId>cargo-maven2-plugin</artifactId>
        <version>1.0.6</version>
        <configuration>
            <container>
            <containerId>tomcat6x</containerId>
            <type>remote</type>
            </container>
            <configuration>
            <type>runtime</type>
            <properties>
                <cargo.tomcat.manager.url>

                    http://myserver:8080/manager
                </cargo.tomcat.manager.url>
                <cargo.remote.username>me</cargo.remote.username>
                <cargo.remote.password>secret</cargo.remote.password>
            </properties>
            </configuration>
            <deployer>
            <type>remote</type>
            <deployables>
                <deployable>
                <location>target/${artifactId}-${version}.war</location>
                <groupId>${groupId}</groupId>
                <artifactId>${artifactId}</artifactId>
                <type>war</type>
                <properties>
                    <context>${artifactId}</context>
                </properties>
                </deployable>
            </deployables>
            </deployer>
        </configuration>
        </plugin>


Das <location> Tag sorgt dafür, dass das gerade erstellte Artefakt über das Filesystem und nicht aus dem Build selbst heraus deployed wird.
Da das Grails Plugin den Packaging-Type grails-app benötigt, das Cargo Plugin aber nur Standard Packaging Types wie war, ear usw. verarbeitet, würde es sonst zu folgendem Fehler kommen:

    [INFO] [cargo:redeploy {execution: default-cli}]
    [WARNING] The defined deployable has the same groupId and artifactId 

    as your project's main artifact but the type is different. You've 
    defined a [war] type whereas the project's packaging is 
    [grails-app]. This is possibly an error and as a consequence the 
    plugin will try to find this deployable in the project's 
    dependencies.
    [INFO] ----------------------------------------------------------------------
    [ERROR] BUILD ERROR


Wenn der POM angepasst wurde und alles korrekt konfiguriert worden ist, kann mit dem Kommando:

    mvn -Dmaven.test.skip=true clean install cargo:redeploy

das Artefakt gebaut und deployed werden.