Montag, 19. November 2012

Maven Release im Batchbetrieb meistern

  1. Setzen der Variable JavaHOME: export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_06.jdk/Contents/Home
  2. Einspielen aller Änderungen ins SVN: svn commit -m "test"
  3. Das Release vorbereiten: mvn release:prepare  --batch-mode -Darguments='-Dmaven.test.skip=true'
  4. Das Release durchführen: mvn release:perform  --batch-mode -Darguments='-Dmaven.test.skip=true'
Mit der Maven Option --batch-mode wird die Interaktivität von Maven abgeschaltet. Dieser Parameter ist z.B. auch im Jenkins oder Hudson hilfreich. Der seltsame Parameter -Darguments='-Dmaven.test.skip=true' führt zu deaktivieren der Tests, in der Regel ist dies nicht notwendig aber zum Testen oft hilfreich. Die Option -Dmaven.test.skip=true ist beim Release nicht wirksam.

Montag, 12. November 2012

Eclipse startet nicht mehr

Auf dem Mac gibt es folgendes Problem: The JVM shared library "/Library/Java/JavaVirtualMachines/openjdk ... " does not contain the JNI-CreateJavaVM symbol.
Scheinbar kollidieren OpenJDK 7 und Oracle JDK. Durch das löschen des OpenJDK kann das Problem gelöst werden:

sudo rm -rf /Library/Java/JavaVirtualMachines/openjdk-1.7-x86_64

Sonntag, 28. Oktober 2012

Grails Maven Integration

Es gibt verschieden Wege Grails in Maven zu integrieren, z.B. um den Nexus zu benutzen. Da wäre das Grails Plugin Maven Publisher (Link). Dieses ist für Grails 1.X geeignet, wird aber nicht mehr unterstützt. Damit fällt es aus. Ersetzt wurde das Grails Plugin Maven Publisher durch das Release Plugin (Link), welches für Grails 2.X verfügbar ist. Das funktioniert bei aktuellen Grails Projekten, leider wird das Passwort für den Nexus innerhalb des Projektes gespeichert (grails-app/conf/BuildConfig.groovy), das ist überhaupt nicht groovy, das ist fahrlässig. Damit fällt auch diese Lösung aus. Dritter Versuch, erstellen einer POM Datei aus Grails heraus. Das funktioniert nur leider kompiliert dann nichts mehr, unter Java 7 auf dem Mac (siehe Fehlerausgabe unten). Dies ist ein bekannter Bug (Link).

Fazit, drei Möglichkeiten, kein Treffer. Was macht eigentlich Ant?





[ERROR] Unresolveable build extension: Plugin org.grails:grails-maven-plugin:2.1.0 or one of its dependencies could not be resolved: Could not find artifact com.sun:tools:jar:1.6 at specified path /Library/Java/JavaVirtualMachines/jdk1.7.0_06.jdk/Contents/Home/jre/bundle/Classes/classes.jar @
[ERROR] Unknown packaging: grails-app @ line 8, column 16

at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:339)
at org.apache.maven.DefaultMaven.collectProjects(DefaultMaven.java:632)
at org.apache.maven.DefaultMaven.getProjectsForMavenReactor(DefaultMaven.java:581)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:233)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
[ERROR]  
[ERROR]   The project com.futuretv.userprofiledatasource:UserProfileDatasource:0.1 (/Users/mirkoebert/Documents/workspace-sts-2.9.0.RELEASE/UserProfileDatasource/pom.xml) has 2 errors
[ERROR]     Unresolveable build extension: Plugin org.grails:grails-maven-plugin:2.1.0 or one of its dependencies could not be resolved: Could not find artifact com.sun:tools:jar:1.6 at specified path /Library/Java/JavaVirtualMachines/jdk1.7.0_06.jdk/Contents/Home/jre/bundle/Classes/classes.jar -> [Help 2]
org.apache.maven.plugin.PluginResolutionException: Plugin org.grails:grails-maven-plugin:2.1.0 or one of its dependencies could not be resolved: Could not find artifact com.sun:tools:jar:1.6 at specified path /Library/Java/JavaVirtualMachines/jdk1.7.0_06.jdk/Contents/Home/jre/bundle/Classes/classes.jar
at org.apache.maven.plugin.internal.DefaultPluginDependenciesResolver.resolve(DefaultPluginDependenciesResolver.java:215)
at org.apache.maven.project.DefaultProjectBuildingHelper.resolveExtensionArtifacts(DefaultProjectBuildingHelper.java:377)
at org.apache.maven.project.DefaultProjectBuildingHelper.createProjectRealm(DefaultProjectBuildingHelper.java:237)

Samstag, 27. Oktober 2012

Jenkins vs Hudson

Wenn um den Einsatz eines Continuous Integration Servers geht, fallen immer zwei Namen: Hudson und Jenkins. Was man oft hört, ist eigentlich das selbe. Ja das stimmt, wenn ich einen neuen Server aufsetze, muss ich vorher für einen von beiden entscheiden. Ich habe von beiden den aktuellen Stand getestet und verglichen. Zum Einsatz kamen Hudson 3.0.0 RC und Jenkins 1.486 auf einem aktuelle Ubuntu. Prinzipiell funktionieren beide Ci Server gleich, die Arbeitsabläuft sind gleich und die Konfigrationsfenster teilweise auch. Der Hudson ist trotz seiner fortgeschrittenen Entwicklung nicht stabil genug, oft funktionieren Dinge nicht (Grails, Ant). Letzlich führten wir die Builds per Shell (grails war) aus. Insgesamt behinderte er die tägliche Arbeit stark. Jenkins dagegen arbeitet wie erwartet. Positiv fiel hier auf, dass man für viele Arbeiten weniger Clicks benötigt. Bezogen auf den aktuellen Entwicklungsstand macht der Jenkins eine deutlich bessere Figur. Es bleibt zu hoffen, das Hudson die Fehler verliert und wieder konkurrenzfähig wird. Zur Zeit fällt meine Empfehlung auf den Jenkins. Übrigens gibt zu beiden CI Servern eine App für iOS. Die Apps werden ich später einem Test unterziehen.

May the test with you...

Freitag, 26. Oktober 2012

Objektorientierung: Warum braucht man Getter und Setter.

Es lernt jeder, wenn man objektorientiert Programmiere, greifet man auf die Objekteigenschaften mit Hilfe von get (lesen) und set (schreiben) Methoden zu. Wenn ich mit Java programmiere kann ich mir diese Methoden automatisch erstellen lassen, wenn ich Eclipse nutze. Andere Sprachen (Groovy, PHP) bieten an dieser Stelle ein bisschen Magic an, dort braucht man diese Methoden gar nicht mehr selbst erstellen, sondern sie sind da, das ist noch bequemer. Doch einmal stellt mir ein anderer Entwickler die Frage, wozu brauchen wir Getter und Setter? Ich war sprachlos und dachte eine Weile darüber nach. Die Antwort ist, in der Regel braucht man sie nicht, weil sie keinerlei Logik enthalten. Viele Datenklassen (Domain Objekte) sind reine Datenkontainer, wozu brauch ich da noch Getter und Setter? Sie haben keinen Nutzen, sie sind überflüssig. Sie nur zu implementieren um einer Vorschrift zu genügen ist Unsinn. Ich habe jetzt aufmerksam in meinen Code geschaut und ich hatte einige wenige Getter und Setter. Sie enthielten irgend welche Logik, sonst waren meine Klassen durch den Konstruktor konfiguriert oder die Klasse war Zustandslos, als ein mehr ein Service. Fazit, ich brauche keine leeren Getter und Setter, sie bieten keinen Mehrwert, sie sind überflüssig und nutzlos. Ich werde sie auch nicht vermissen.

Donnerstag, 25. Oktober 2012

Nexus

Der Nexus ist ein Repostory für Java Bibliotheken und Artefakte. Es integriert sich perfekt in Maven. Es gibt neben der freien Version noch ein Professional Version. Ein Vorteil der Professional Version ist, dass man Maven Sites, also Projekt Sites und Reports die durch Maven erzeugt wurden, dort deployen kann. Zur Installation gibt es hier eine Anleitung. Wenn das TGZ zur Installation gewählt wurde ist dringend zu prüfen, ob der Eigentümer und die Gruppe richtig gesetzt sind (root). Dann noch schnell den Benutzer im File /etc/init.d/nexus auf root setzen. Schon läuft der Nexus unter: http://localhost:8081/nexus Benutzername: admin Passwort admin123 (bitte ändern). Jetzt einen Benutzer anlegen und ihm ausreichend Rechte geben. Dann noch Maven konfigurieren, folgende Einträge müssen ins POM:
<distributionManagement> 
    <snapshotRepository> 
        <id>snapshots</id> 
        <url>http://stage02:8081/nexus/content/repositories/snapshots</url> 
    </snapshotRepository> 
    <repository> 
        <id>release</id> 
        <url>http://stage02:8081/nexus/content/repositories/releases/</url> 
    </repository> 
</distributionManagement>
Danach muss noch die user.xml ergänzt werden:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 
                      http://maven.apache.org/xsd/settings-1.0.0.xsd"> 
  <localRepository/> 
  <interactiveMode/> 
  <usePluginRegistry/> 
  <offline/> 
  <pluginGroups/> 
      <servers> 
            <id>release</id> 
            <username>ebm</username> 
            <password>XXX</password> 
        </server> 
        <server> 
            <id>snapshots</id> 
            <username>ebm</username> 
            <password>XXX</password> 
        </server> 
    </servers> 
  <mirrors/> 
  <proxies/> 
  <profiles/> 
  <activeProfiles/> 
</settings>
Jetzt kann man alles testen: mvn deploy

Code Coverage mit Emma

Für die Berechnung der Testabdeckung des Codes gibt es eine Reihe von Werkzeugen, populär sind Cobertura als auch EclEmma. Cobertura wir gerne in Grails verwandt nur leider liefert Cobertura in Verbindung mit Java 7 keine Ergebnisse mehr. Also auf zu Emma. Emma lässt sich sehr einfach als Eclipse Plugin einsetzen, um Emma auch in Maven 3 nutzen zu können bedarf ein wenig Konfiguration.
    <build> 
        <plugins> 
            <plugin> 
                <artifactId>maven-compiler-plugin</artifactId> 
                <version>2.3.2</version> 
                <configuration> 
                    <source>1.7</source> 
                    <target>1.7</target> 
                </configuration>
            </plugin> 


            <plugin> 
                <groupId>org.jacoco</groupId> 
                <artifactId>jacoco-maven-plugin</artifactId> 
                <version>0.6.0.201210061924</version> 
                <executions> 
                    <execution> 
                        <goals> 
                            <goal>prepare-agent</goal> 
                        </goals> 
                    </execution> 
                    <execution> 
                        <id>report</id> 
                        <phase>prepare-package</phase> 
                        <goals> 
                            <goal>report</goal> 
                        </goals> 
                    </execution> 
                </executions> 
            </plugin>
EclEmma basiert auf der Bibliothek jacococ, dem entsprechend muss das Maven Plugin JACOCO benutzt werden. Mit dieser Maven Konfiguration erzeugt man dann zu Eclipse equivalente Reports.