First go to the parent folder in Git Bash and add a git subtree:
git subtree add -P dir-name git-repo revision
dir-name:name of the module git-repo:The git-url from the project you want to move. In Bitbucket you find this in repository settings. example: https://git.mycompany.com/git/scm/clients/mycompany-webservice-client.git revision: for me this was always HEAD
This adds the project to the parent project.
Next steps: - in the module pom set the parent and delete the own version and maybe SCM tag - in the parent add the module as module (and maybe as dependency with the project.version version, if you want to use the parent as bom (bill of materials))
Sometimes updating SNAPSHOT dependencies in big projects just does not work. When something is changed in one workspace and a maven clean install is done, it can be hard to get this in another workspace as updated dependency, at least in my experience.
What worked for me was the Maven Helper Plugin, where you get a "Dependency Analyzer" Tab for the pom file. There is a button "Reimport", which works fine to get the wanted updates for the SNAPSHOT dependencies.
Generiert man sich aus einem wsdl mit Maven über jaxws-maven-plugin den Client bastelt er einen einen schönen Konstruktor für den Aufruf des Services, der auch funktioniert, wenn man ihn an Ort und Stelle ausprobiert.
Deployed man das dann jedoch auf einen Server geht nichts mehr:
ERROR MyServiceImpl - Service method 'public abstract MyClass myMethod()' threw an unexpected exception: javax.xml.ws.WebServiceException: The following WSDL exception occurred: WSDLException: faultCode=WSDL4JWrapper : : javax.wsdl.WSDLException: WSDLException: faultCode=WSDL4JWrapper : : java.io.FileNotFoundException: unsinnigerPfadzurWSDL (A file or directory in the path name does not exist.)
Der Pfad wird irgendwie unsinnig zusammengesetzt, weil man den default Konsturktor des Services verwendet hat, es gibt aber noch einen zweiten:
MyWebService(URL wsdlLocation, QName serviceName)
Hier kann man sich den Pfad nun selber zusammenbasteln:
MyWebService svc = new MyWebService (WebServiceUtil.class.getClassLoader().getResource("wsdl/MyWSDL.wsdl"), new QName(diesen Teil aus dem default Konstruktor einfach kopieren));
Auf diese Weise wird das wsdl File immer gefunden, egal wo man das Projekt deployed.
Bei einem mehrmoduligen GWT/Maven Projekts ist das Model oft in einem anderen Modul als im eigentlichen GWT Modul (web Modul). Für das gwt-maven-plugin werden auf der Homepage 2 Möglichkeiten vorgeschlagen das zu lösen:
Erster Vorschlag das Goal gwt:resources hinzuzufügen funktioniert ausgezeichnet, allerdings möchte man das Problem manchmal nicht über zusätzliche Commandline Befehle lösen sondern über die pom Konfiguration. Hier wird vorgeschlagen das ganze über das Attribut compileSourcesArtifacts zu lösen, das funktioniert aus mir nicht ganz erklärlichen Gründen nicht.
Meine Lösung war dann genau wie vorgeschlagen das zusätzliche gwt.xml im Submodul anzulegen:
und dieses im gwt.xml des GWT Moduls zu mit "inherits" einzubinden.
Damit funktioniert das Ganze leider noch nicht, im pom.xml des Moduls, wovon das Model eingebunden werden soll muß man noch folgendes eintragen:
Ecplise: Indigo Service Release 2
Maven 3.0.3
Google Plugin 3.1.0
GWT SDK 2.4.0
m2e Plugin 1.0.200
Wer GWT mit Maven und Eclipse verwenden möchte braucht manchmal ein dickes Fell.
[INFO] Compiling module myCompany.client.Frontend
[INFO] Finding entry point classes
[INFO] [ERROR] Unable to find type ' myCompany.client.Frontend '
[INFO] [ERROR] Hint: Previous compiler errors may have made this type unavailable
[INFO] [ERROR] Hint: Check the inheritance chain from your module; it may not be inheriting a required module or a module may not be adding its source path entries properly
Die Klasse existiert aber und es tritt auch kein Compile Fehler auf. Des Rätsels Lösung war der Ablageort des Frontend.gwt.xml. Wie bei Maven üblich wurde es in src/main/resources untergebracht und dort unter myCompany/client. Das mag aber nun das gwt-maven-plugin gar nicht und wirft den obigen Fehler aus. Verschiebt man das gwt.xml nun einen Folder runter in den Folder myCompany geht plötzlich der Build durch.
Maven 3.0.3
Eclipse Java EE IDE for Web Developers Indigo Service Release 2 20120216-1857
gwt-maven-plugin 2.4.0
build-helper-plugin 1.7
m2e - Maven Integration for Eclipse 1.0.200.20111228-1245
Google Plugin for Eclipse 3.7 2.6.1v20205091048-rel-r37
Will man mit dem org.codehaus.mojo.gwt-maven-plugin Archetype ein Skeleton GWT Projekt erzeugen kann das ein ziemlicher Task sein. Irgendwie hab ich das trotzdem hinbekommen, es gibt sicher andere und wahrscheinlich auch bessere Wege, aber ich beschreibe mal wie ich vorgegangen bin.
Zuallererst: Das m2eclipse Plugin von Sonatype muß deaktiviert oder deinstalliert werden, es ist meiner Meinung nach einer der Hauptgründe warum es so schwierig ist das Ganze hinzubekommen.
Dann ein neues Maven Projekt anlegen und den Archetype gwt-maven-plugin verwenden:
Danach füge ich im pom.xml mit dem build-helper-maven-plugin den zu generierenden Code zum Sourcepath hinzu (m2eclipse ignoriert das einfach, einer der Gründe, warum es raus mußte). Beim Probelauf für diesen Blogeintrag hatte das Projekt danach trotz deaktivierten m2e eine Maven Nature (am hinzugefügten M erkenntbar). Diese habe ich einfach deaktiviert, dann muckste m2e auch wirklich nicht mehr auf (Rechter Mausklick aufs Projekt -> Maven -> Disable Maven Nature).
Dann baue ich mir einen Launcher für das externe Maven und lasse das Ganze mal mit dem Goal install laufen:
Der Lauf geht inklusive Tests durch, auch die generierten Sourcen sind eingebunden, sieht einmal sauber aus.
Nun probiere ich das Ganze auch mal mit den Mavengoals clean gwt:run laufen zu lassen und siehe da, es funkt:
Auch im Browser sieht das sauber aus:
Im Prinzip nicht viel zu tun, es hat allerdings schon seine Zeit gebraucht bis ich mich durchgerungen habe das an sich tolle m2eclipse Plugin zu deaktivieren.
Am Ende noch der Projektbaum, wie er aussieht wenn alles gut gegangen ist:
Händisches kopieren von Ressourcen aus einem allgemeinen Projekt in ein spezifisches Projekt kann sehr nervig werden, darum hab ich das mal automatisiert. Erster Task ist, das im Repository nur das jar rumliegt, das muß man sich holen und entpacken. Das kann das maven-dependency-plugin für einen erledigen:
Zu beachten ist dann noch, das die kopierten Ressourcen wahrscheinlich ins SCM reinrutschen sollen. Will man um alles wirklich sauber zu machen am Beginn des Builds die alten kopierten Files noch löschen macht man das so: Beitrag zum Löschen von Files in der clean Phase des Maven Builds
Commons Ressourcen lasse ich mir im Laufe des Mavenbuilds reinkopieren, allerdings sollte vorher ausgemistet werden, falls nämlich Ressourcen umbenannt wurden kommt es zu Doppelgleisigkeiten, die besonders bei Javascript Ressourcen sauber weh tun können.
Leider treiben sich zwischen meinen Commons auch applikationsspezifische Ressourcen herum, darum kann nicht alles einfach weggeworfen werden. Dazu zählen im besonderen auch die .cvsignore Files, die verhindern das mir meine Commons, die ja eh bei jedem Build aus dem Commons-Projekt umkopiert werden, ins CVS rutschen.
Beim Beispielprojekt handelt es sich um einen Source Code Generator, der aus einem File, das Text in einer Domain Specific Language enthält, Java Code generiert.
Soweit so gut, nun soll beim Build aus einigen Test DSL Files der Source Code erzeugt werden und gegen einige JUnit Tests gefahren werden, um zu sehen ob der generierte Code den Erwartungen entspricht.
Das Ganze war entgegen meinen ersten Befürchtungen dann dank Maven einfach, dafür gibts das exec-maven-plugin.
Hier wird die Main Methode der angegebenen Klasse ausgeführt, in meinen Fall Test Source an der richtigen Stelle erzeugt (Das ist in der Klasse festgelegt, wird hier eigentlich nur dadurch bedacht das testSourceRoot angegeben wurde, damit Maven auch sicher mitkriegt das dieser Code vor dem Test auch brav kompiliert wird). Einfacher gehts eigentlich nimmer.
Damit vom generierten Code nicht irgendwann störende Restbestände herumliegen lösche ich diese bevor neuer generiert wird mithilfe des maven-clean-plugin:
maven-clean-pluginsrc/test/java/genfalse
Das wars eigentlich.
Was etwas irritieren kann ist, daß vor dem Build immer unkompilierbarer Code herumliegt, damit die JUnit Tests kompilieren muß erst der Test Source generiert werden.
Hierbei hilfreich hat sich der Parameter maven.test.failure.ignore erwiesen, einfach auf true setzen und schon läuft der Build auch bei Test Failures zu Ende und schließt sogar mit Success ab, wenn sonst nix Störendes passiert.
IBM RAD 8.0.1 (Eclipse 3.6)
Maven 3.0.3
maven-jetty-plugin 6.1.26
selenium-maven-plugin 2.2
maven-surefire-plugin
Ich erstelle mir Integrationstests mit dem Seleniumplugin des Firefox (export TestCase as JUnit 4 (Webdriver)), bearbeite diese nach und lasse sie mit dem maven-jetty-plugin, selenium-maven-plugin und maven-surefire-plugin laufen.
Manchmal möchte man dann doch in seine Tests und in die zu testende Webapp reindebuggen, allerdings werden die Breakpoints ignoriert.
Abhilfe kann man schaffen, indem man im surefire-plugin den forkMode konfiguriert:
Obwohl Maven nicht embedded in der IDE läuft sondern über das m2eclipse Plugin eine externe Version gewählt wurde kann man sich nun kreuz und quer durch den Code debuggen.
Das Problem:
Im Parent pom war eine alte Version vom maven-site-plugin festgelegt und sollte im Projekt pom überschrieben werden, irgendwie war es aber nicht möglich das mit den normalen Mechanismen hinzukriegen.
Die Lösung fand ich dann in einem Sonatype Blog Eintrag.
Man überschreibt die Version einfach dadurch indem man dem Plugin eine Dependency hinzufügt, die seine eigene Version hochschraubt.
Eine praktische Option der Selenium IDE ist daß man JUnit Tests aus einem aufgenommen Testfall generieren kann. Leider funktioniert das mit Drop Down Listen nicht so einfach, generiert man bekommt man für diese Fälle im JUnit Test folgendes:
Liest man nach gibt es die Klasse Select, mit der man das händisch nachtragen kann, allerdings befand sich diese bei mir nicht im Klassenpfad, Problem war das ich nur den HtmlUnit Driver inkludiert hatte, das support Package ist dort nicht inkludiert.
Gibt man Maven die Anweisung das selenium-java Projekt zu inkludieren findet er auch die Select Klasse.
org.seleniumhq.seleniumselenium-java2.11.0test
Nun kann man die Select Klasse supereinfach zum Auswählen der entsprechenden Option verwenden:
Select select = new Select(driver.findElement(By.id("aktEntry.risiko.value")));
select.selectByVisibleText("American Football");
Das pluginManagement über parents zu handlen ist eine tolle Sache, man trägt dort gewünschte die Konfiguration ein und in den Kindprojekten gibt man einfach nur das Plugin an und es zieht dort. Hat bis jetzt gut funktioniert. Nun habe ich das mit dem maven-resources-plugin versucht und leider zog das Teil in allen Projekten die diesen parent hatten, egal ob es nun im pom eingetragen war oder nicht. Es blieb nichts anderes übrig als die Config im parent zu löschen und in jedem Projekt einzeln hinzuzufügen.
Erkärt habe ich es mir so: Da das maven-resources-plugin vom ganz normalen Lifecyle verwendet wird, ist es irgendwie in jedem pom implizit vorhanden und meine Config im parent zieht somit in jedem Projekt.
Eine andere Lösung als das Plugin in jedem Projekt einzeln zu konfigurieren ist noch nicht gekommen, aber vielleicht weiß ja ein geneigter Leser mehr.
Add the parameter -Dmaven.test.skip=true or -DskipTests=true in the command line, depending on whether you want to skip test compilation and execution or only execution.
Wenn beim automatisierten Testen der Pfad zur Testdatenbank nicht hardcodiert angegeben werden kann steht man vor dem Problem, wie man nun den verflixten Pfad in die im jmx File definierten Requests reinbekommt. Die Lösung ist das Anlegen eines jmeterUserProperties im pom File: