# Maven: Abhängigkeit im Jetty laden



## tm001 (1. Okt 2009)

Moin,
ich habe eine Anwendung bestehend aus Client und (Web-)Server und möchte nun mit JUnit den Client testen. Damit die Tests erfolgreich absolviert werden können, wird ein laufender Server benötigt. Für das Bauen, Testen und Deployment verwende ich Maven.

Daher verwende ich das Jetty-Maven-Plugin, welches vor den Tests gestartet, sowie anschließend beendet wird. Als Abhängigkeit habe ich das Webserver-Projekt angegeben. Allerdings versucht das Plugin, ein nicht-existierendes war-File meiner Client-Applikation zu laden.

Wie kann ich dem Plugin mitteilen, dass er das über die angegebene dependency geladene war-File im Jetty hochfahren soll? Nach dem was ich über google erfahren habe, konnte man in Maven1 die Property "jetty-bundle" auf "true" setzen. Das ist nun offenbar nicht mehr möglich?

Ich weiß, dass man über das Element <webApp> den Pfad zum war-File angeben kann. Jedoch legt Maven die Abhängigkeiten in irgendeinem Maven-spezifischen Verzeichnis ab, welcher auf verschiedenen Rechnern unterschiedlich aussieht. Kommt man dort vielleicht durch Maven-Variablen (sowas wie ${basedir}) ran? Hier den absoluten Pfad zu verwenden, ist ja auch nicht Sinn der Sache.

Hier übrigens der relevante Ausschnitt aus meiner POM:

```
<plugin>
	<groupId>org.mortbay.jetty</groupId>
	<artifactId>maven-jetty-plugin</artifactId>
	<version>6.1.18</version>
	<executions>
	<execution>
		<id>start-jetty</id>
		<phase>test-compile</phase>
		<goals>
			<goal>deploy-war</goal>
		</goals>
		<configuration>
			<daemon>true</daemon>
			<!--<webApp>path/to/servlets.war</webApp>-->
			<scanIntervalSeconds>0</scanIntervalSeconds>
			<connectors>
				<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
					<port>8080</port>
					<maxIdleTime>60000</maxIdleTime>
				</connector>
			</connectors>		                     
			<stopPort>9966</stopPort>
			<stopKey>foo</stopKey>
		</configuration>
	</execution>            
	</executions>
	<dependencies>
		<dependency>
			<groupId>application</groupId>
			<artifactId>server-project</artifactId>
			<version>1.1.1-SNAPSHOT</version>
			<type>war</type>
		</dependency>
	</dependencies>      
</plugin>
```

Danke schon mal!


----------



## maki (1. Okt 2009)

Kenne mich mit Jetty nicht aus, nutze Tomcat (mit dem Cargo Plugin für Integrationstests), versuche trotzdem mal was dazu zu sagen, auf die Gefahr hin, dass die Antwort die nicht helfen wird.



> ich habe eine Anwendung bestehend aus Client und (Web-)Server und möchte nun mit JUnit den Client testen. Damit die Tests erfolgreich absolviert werden können, wird ein laufender Server benötigt. Für das Bauen, Testen und Deployment verwende ich Maven.


Das hört sich wie ein Integrationstest an, dafür verwende ich das Cargo Plugin und ein eigenes Maven Modul(Projekt), letzteres ist aus mehreren Gründen empfehlenswert.



> Daher verwende ich das Jetty-Maven-Plugin, welches vor den Tests gestartet, sowie anschließend beendet wird. Als Abhängigkeit habe ich das Webserver-Projekt angegeben. Allerdings versucht das Plugin, ein nicht-existierendes war-File meiner Client-Applikation zu laden.


Hmm... in welcher pom steht denn die Jetty Konfiguration?
Der des Client? Das würde das verhalten erklären 
Mit einem eigenen Modul für die Integrationstest wäre das imho anders.

Wie gesagt, kenne das JEtty Plugin nicht, könnte mich auch irren.


----------



## tm001 (1. Okt 2009)

maki hat gesagt.:


> Kenne mich mit Jetty nicht aus, nutze Tomcat (mit dem Cargo Plugin für Integrationstests), versuche trotzdem mal was dazu zu sagen, auf die Gefahr hin, dass die Antwort die nicht helfen wird.
> 
> 
> Das hört sich wie ein Integrationstest an, dafür verwende ich das Cargo Plugin und ein eigenes Maven Modul(Projekt), letzteres ist aus mehreren Gründen empfehlenswert.


Naja, in bin jetzt nicht so der Experte, was beim Testen die "reine Lehre" angeht. Aber wenn ich das Verhalten von Methoden wie sendMessage() teste, dann ist das doch eher ein Unit-Test als ein Integrationstest, oder? Von daher denke ich, dass das nicht in ein Extra-Modul gehört.



maki hat gesagt.:


> Hmm... in welcher pom steht denn die Jetty Konfiguration?
> Der des Client? Das würde das verhalten erklären


Ja, die steht in der des Clients. Ich versteh das Verhalten schon, würde ihm aber trotzdem gerne sagen, dass er es anders machen soll... Prinzipiell sollte es möglich sein, man kann ja wie gesagt auch den Pfad des war-Files angeben.


----------



## maki (1. Okt 2009)

> Naja, in bin jetzt nicht so der Experte, was beim Testen die "reine Lehre" angeht. Aber wenn ich das Verhalten von Methoden wie sendMessage() teste, dann ist das doch eher ein Unit-Test als ein Integrationstest, oder? Von daher denke ich, dass das nicht in ein Extra-Modul gehört.


Was denn für eine "reine Lehre"? Maven2 hat einerseits so seine Probleme mit der Integrations test phase und anderer ist Maven2 dafür ausgerichtet (also üblich & empfohlen) die Integrationstest in ein eigenes Modul auszulagern.
Nutzt du Mock Objekte? Oder lässt du die "Komponenten" (zB. alle Schichten) in "echt" arbeiten?
Testen ohne Mockobjekte führt zwangsläufig zu Integrationstests.
Einen Server zu starten um seine Tests durchzuführen ist jedenfalls todsicher ein Integrationtest 



> Ja, die steht in der des Clients. Ich versteh das Verhalten schon, würde ihm aber trotzdem gerne sagen, dass er es anders machen soll...


Kann es sein dass das Jetty Plugin eben davon ausgeht in einem WAR pom aufgerufen zu werden? 
Sinn würde es ja machen.

Nachtrag: Ergänzt.


----------



## schalentier (1. Okt 2009)

Unit-Test = Test der Methoden einer Komponente (=eine Klasse + evtl. Interface), Abhaengigkeiten werden durch Mock-/Dummy-Objekte ersetzt und somit nicht mitgetestet
Integrationstest = Test mehrerer (aller) Klassen in ihrem Zusammenspiel, z.B. User-Story

Ich experimentiere grad ein bisschen mit OpenEJB 3.1 herum, da kann man einen kompletten Application-Container in seinen Tests starten... allerdings weiss ich grad nicht, ob das fuer dich relevant waere.


----------



## tm001 (7. Okt 2009)

Ok, mit dem Cargo Plugin funktioniert es, danke!


----------



## tm001 (7. Okt 2009)

oh, doch nicht, hab mich geirrt ...

wie kann man denn dem cargo-plugin sagen, dass er im eingebetteten jetty ein bestimmtes projekt laden soll?

so wie unten angeführt läuft es leider nicht.


```
<plugin>	 
			<groupId>org.codehaus.cargo</groupId>
			<artifactId>cargo-maven2-plugin</artifactId>
			<version>1.0</version>
			<executions>
			<execution>
				<id>start-container</id>
				<phase>test-compile</phase>
				<goals>
					<goal>start</goal>
				</goals>				
			</execution>			
			</executions>
			<configuration>
				<wait>false</wait>
				<container>
					<containerId>jetty6x</containerId>
					<type>embedded</type>
				</container>
			    	<properties>
					<cargo.servlet.port>8080</cargo.servlet.port>
					<cargo.logging>high</cargo.logging>			      
				</properties>
				<deployer>
					<type>remote</type>
					<deployables>
					<deployable>
						<groupId>acme</groupId>
						<artifactId>projectxyz</artifactId>						
						<type>war</type>			        
				        	<properties>
							<context>contextPath</context>
						</properties>
					</deployable>			          
	    			</deployables>
				</deployer>			
			    
			</configuration>
			
		</plugin>
```


----------



## maki (7. Okt 2009)

tm001 hat gesagt.:


> Ok, mit dem Cargo Plugin funktioniert es, danke!


Ja, Cargo ist 'ne geile Sache :toll:



> Ich experimentiere grad ein bisschen mit OpenEJB 3.1 herum, da kann man einen kompletten Application-Container in seinen Tests starten... allerdings weiss ich grad nicht, ob das fuer dich relevant waere.


Mit Cargo kann man verschiedene Server installieren, konfigurieren, starten & stoppen:


> Containers
> 
> * Geronimo 1.x
> * JBoss 3.x
> ...


----------



## maki (7. Okt 2009)

> wie kann man denn dem cargo-plugin sagen, dass er im eingebetteten jetty ein bestimmtes projekt laden soll?


Wenn ich mich nicht täusche, sollte doch dass hier ausreichen:
[xml]				<deployer>
					<type>remote</type>
					<deployables>
					<deployable>
						<groupId>acme</groupId>
						<artifactId>projectxyz</artifactId>						
						<type>war</type>			        
				        	<properties>
							<context>contextPath</context>
						</properties>
					</deployable>			          
	    			</deployables>
				</deployer>			
[/xml]
Was meldet denn Jetty bzw die logs und maven2?

Nebenbei, du *musst* das in eine eigenes Modul/Pom auslagern, wenn du wirklich diese Phase nutzen willst:
[xml]<phase>test-compile</phase>
[/xml]
.. denn zu dieser Phase ist das war weder erstellt noch im lok. Repo installiert.
Aber wozu denn überhaupt diese Phase  missbrauchen? Nicht umsonst hat Maven2 mehr als genug Phasen definiert, zB,. [c]pre-integration-test[/c]


----------



## tm001 (7. Okt 2009)

auch in phase "pre-integration-test" das gleiche spiel...
er startet den jetty mit dem standard-cargo-war-file:


```
[INFO] [cargo:start]
[INFO] [beddedLocalContainer] Jetty 6.x Embedded starting...
2009-10-07 18:55:27.886::INFO:  Logging to STDERR via org.mortbay.log.StdErrLog
2009-10-07 18:55:27.959::INFO:  jetty-6.1.1rc1
2009-10-07 18:55:28.310::INFO:  Extract jar:file:/path/to/project/target/jetty6x/cargocpc.war!/ to /tmp/Jetty_0_0_0_0_8080_cargocpc.war__cargocpc__xflgf3/webapp
log4j:WARN No appenders could be found for logger (org.apache.jasper.compiler.JspRuntimeContext).
log4j:WARN Please initialize the log4j system properly.
2009-10-07 18:55:29.043::INFO:  Started SelectChannelConnector @ 0.0.0.0:8080
[INFO] [beddedLocalContainer] Jetty 6.x Embedded started on port [8080]
```


----------



## maki (7. Okt 2009)

Wieso hast du eigentlich
[xml]<type>remote</type>
[/xml]
drinnstehen?


----------

