This blog has moved to
http://blog.matthias-reining.com

Die bestehenden Artikel bleiben vorerst alle bei blogspot. Neue Artikel veröffentliche ich allerdings nur noch auf http://blog.matthias-reining.com

Donnerstag, 7. Juli 2011

Maven, WTP und der ClassPath

Verwendet man das m2eclipse Plugin bei der Webentwicklung in eclipse (WTP – Web Tools Platform), tritt leider ein unerwünschtes Verhalten auf…

Eclipse kennt nur einen ClassPath.
Schlimm genug.
Leider werden die, in Maven als provided gekennzeichnet Libraries, auch vom WTP Plugin in das WEB-INF\lib Verzeichnis kopiert/deployed (siehe http://jira.codehaus.org/browse/MNGECLIPSE-714).

Bei vielen Libraries ist dies nicht weiter schlimm. Bei einigen anderen verhindert dies dagegen die korrekte Funktionsweise des Tomcats.

In meinem Beispiel habe ich in dem kompletten Tomcat einen Transaktionsmanager „gegeben“ (BTM). Dieser hängt sich unter anderem in die Datasoure Definition aus der server.xml.

Als common-lib wird hier bspw. jta-1.1.jar benötigt (liegt unter <CATALINA_HOME>\lib.
Ist diese Library dann nochmal in der eigentlichen Webapplikation unter WEB-INF\lib funktioniert BTM nicht mehr korrekt und die Applikation kann auf keine DB Resourcen zugreifen.

Folgender „Hack“ verschafft Abhilfe:

pom.xml:
       <profiles>
             <profile>
                    <!-- Da eclipse keine Unterscheidung beim Classpath kennt und das m2eclipse
                           hier auch keine Unterstützung bietet (http://jira.codehaus.org/browse/MNGECLIPSE-714
                           -Timestamp:06.07.2011), werden Libraries die provided sind per WTP innerhalb
                           von eclipse immer in das WEB-INF\lib Verzeichnis kopiert. Mit Hilfe des Profiles
                           wird in im Normalfall (profile: default) die provided Libraries von maven
                           richtig gehandelt. Falls man sich in der eclipse Umgebung befindet kommen
                           diese nicht in den Web-App Classpath. Die kann über ein Property sichergestellt
                           werden. Das einzigste Property das in Eclipse beim Start gesetzt wird, ist
                           in den aktuellen eclipse Versionen osgi.requiredJavaVersion. Anhand von diesem
                           wird daher das Profile gewählt -->
                    <id>eclipse-env</id>
                    <activation>
                           <property>
                                  <name>osgi.requiredJavaVersion</name>
                                  <value>1.5</value>
                           </property>

                    </activation>
             </profile>
             <profile>
                    <id>default</id>
                    <activation>
                           <activeByDefault>true</activeByDefault>
                    </activation>
                    <dependencies>
                           <dependency>
                                  <groupId>org.apache.tomcat</groupId>
                                  <artifactId>tomcat-servlet-api</artifactId>
                                  <version>7.0.16</version>
                                  <scope>provided</scope>
                           </dependency>

                           <dependency>
                                  <groupId>org.codehaus.btm</groupId>
                                  <artifactId>btm</artifactId>
                                  <version>2.1.1</version>
                                  <scope>provided</scope>
                           </dependency>
                           <dependency>
                                  <groupId>javax.transaction</groupId>
                                  <artifactId>jta</artifactId>
                                  <version>1.1</version>
                                  <scope>provided</scope>
                           </dependency>
                    </dependencies>
             </profile>
       </profiles>

Mit Hilfe des neuen Maven Profiles „default“ werden die provided Libraries per Default geladen (activatedByDefault=true).
Innerhalb von eclipse greift aber das Profile „eclipse-dev“. Das Ganze wird anhand des java Paramters osgi.requiredJavaVersion ermittelt. Dieser Paramter wird beim Start von eclipse mitgegeben und ist daher bei der direkten Verwendung von Maven innerhalb von eclipse immer vorhanden.

So einen Parameter setzt ein „normaler“ Web-Entwicklung normalerweise ja nicht, so dass es hier zu keinerlei Konflikten kommen sollte ;-)

Mit diesem „Hack“ tauchen die provided Libraries nicht mehr im eclipse Class-Path auf und werden somit auch nicht nach WEB-INF\lib deployed.

J

Kommentare:

  1. Hallo,

    vielen Dank für den Tipp, das erleichtert einiges. Ich habe das bisher über das dependency-plugin gelöst und damit die libs in ein Verzeichnis kopiert dass ich daraufhin per Deployment Assembly in WEB-INF\lib deployed habe. Das ist natürlich viel umständlicher.

    AntwortenLöschen
  2. Unter Properties/Maven kann man die aktiven Profile auswählen, die Maven innerhalb Eclipse verwenden soll. Dann braucht man den netten Hack nicht ;-)

    AntwortenLöschen