# Tomcat 6.x - context path wird nicht richtig gesetzt durch MAven2 Plugin



## pocketom (21. Jul 2009)

Hi,

ich habe mein Maven2 Plugin wie folgt konfiguriert:


```
<properties>
	<warfile>MyService</warfile>
</properties>

<plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>tomcat-maven-plugin</artifactId>
		<configuration>
			<warFile>target/${warfile}.war</warFile>
			<path>/cxf/${warfile}</path>				
		</configuration>
</plugin>
```

Der Aufruf des ganzen ist im Prinzip fast so wie ichs haben will: http://localhost:8080/cxf/Myservice/Myservice (Um den Servicenamen nicht immer doppelt angeben zu müssen habe ich es hiermit versucht, ohne Erfolg -> context root howto)

Im webapp Verzeichnis siehts dagegen garnicht gut aus:
_
cxf#MyService
cxf#MyService.war
_

Logischerweise will ich all meine CXF Services im Unterordner cxf verwalten.

Dashalb habe ich unter conf/server.xml folgendes hinzugefügt


```
</Host>
	...
	...
	...
	<Context path="" docBase="cxf" debug="0" reloadable="true"></Context>
</Host>
```

Ist aber leider auch wirkungslos.


Wie kann ich 

a) effektiv das Doppeltschreiben des Servicenamen abstellen
b) meine CXF Services im Unterordner webapps/cxf verwalten

???


----------



## maki (21. Jul 2009)

Sieh dir mal die Doku zum tomcat-maven-plugin an 

Das hier:

```
<Context path="" docBase="cxf" debug="0" reloadable="true"></Context>
```
Ist IME nicht gut, denn der Tomcat hat meist schon einen Rootcontext, das beisst sich.

Den ServiceNamen schreibst du doch gar nicht doppelt, ist doch dein Context und dein Service 

Die Datei context.xml und was man damit machen kann ist dir bekannt?


----------



## pocketom (22. Jul 2009)

Hi,

das hier


```
<Context path="/cxf" docBase="cxf" debug="0" reloadable="true"></Context>
```

habe ich natürlich nicht für das Maven Plugin konfguriert, sondern in tomcat6.0/conf/server.xml. Dort liegt ja auch die context.xml, dort habe ich es auch schon mal rein. Ich krieg es einfach nicht hin das Maven in webapps/cxf deployed. Wenn ich wie in der Doku zum tomcat-maven-plugin ein <path> Element configuriere, dann legt es mir im Ordner tomcat6/webapps eine WAR namens cxf.war an, und dazu einen Ordner cxf in dem WEB-INF, etc. zu diesem einen WAR file liegen. Wenn es den Folder cxf schon gibt meldet Maven einen Error.

Ich möchte einfach nur das alle zukünftigen CXF Services im Folder tomcat6/webapps/cxf abgelegt werden. Das kann doch nicht so schwer sein oder? Ich tu jetzt schon Stunden damit rum, aber es klappt nicht. Das es da offensichtlich Probleme gibt steht ja auch hier -> http://benhutchison.wordpress.com/2008/07/30/how-to-configure-tomcat-root-context. 

Es ist einfach wichtig das der Service auch unter der Service URL erreichbar ist die ich im WSDL definiert habe, sonst können meine Kunden da kaum was mit anfangen.... Dazu darf auch der Context einfach nicht gleich heissen wie der Service (das eines der Context, das andere der Service ist ist mir klar!)!

Neben den offiziellen Dokus habe ich auch gegoogelt wie ein Blöder *VERZWEIFEL*


----------



## maki (22. Jul 2009)

Einfache Lösung: [c]finalName[/c] richtig setzen, zB. auf [c]cxf[/c], wird auch in der Doku beschrieben: Maven Tomcat Plugin - Maven 2 Tomcat Plugin

Die [c]context.xml[/c] ist Teil deiner WebApp und wird von Tomcat ausgewertet solange du den Tomcatmanager benutzt um die Webapp zu deployen, ein einfaches kopieren nach [c]webapps[/c] reicht nicht um die [c]context.xml[/c] auszuwerten, in ihr kann man Serversettings wie zB. Realms, Datasources aber auch den Contextpath etc. konfigurieren, ohne dies am Server manuell machen zu müssen. Details stehen in der Tomcat Doku.

Vom Root Context kann ich nur abraten, mache das selbst nur wenn es sich um schlecht geschriebene Legacyanwendungen handelt, ansosnten ist das imho sehr daneben und unflexibel.


----------



## pocketom (22. Jul 2009)

D.h. in die context.xml von Tomcat selbst (unter /conf liegt doch auch eine!) soll ich garnichts reinschreiben sondern jedes Mal eine eigene context.xml in mein WEB-INF dir meiner Applikation tun (Anmwerkung: Ich kam noch niemals auf den Gedanken eine context.xml einfach in das webapp Verzeichnis zu legen, wieso auch...) ?

Um es wirklich absolut deutlich zu machen:



			
				http://tomcat.apache.org/tomcat-6.0-doc/config/context.html hat gesagt.:
			
		

> Context elements may be explicitly defined:
> 
> * In the $CATALINA_BASE/conf/context.xml file: *the Context element information will be loaded by all webapps.*
> ...
> ...



Exakt das habe ich getan. Einmal configurieren, für alle Webapps. Richtig oder falsch und wieso steht das da? Wenn die Quelle nicht die richtige ist dann sage mir bitte wo die richtige Quelle ist.





> Einfache Lösung: finalName richtig setzen, zB. auf cxf, wird auch in der Doku beschrieben: Maven Tomcat Plugin - Maven 2 Tomcat Plugin



Habe ich gesetzt, auf ${warfile}. Wenn ich es auf cxf setzen würde wäre das Resultat ein cxf.war.


*pom.xml*

```
<build>
		<finalName>${warfile}</finalName>
		...
		...
		...
		
		<plugin>
			<groupId>org.codehaus.mojo</groupId>
			<artifactId>tomcat-maven-plugin</artifactId>
			<configuration>
					<warFile>target/${warfile}.war</warFile>
					<path>/cxf</path>				
			</configuration>
		</plugin>
</build>
```


*context.xml - <!-- The contents of this file will be loaded for each web application -->*

```
<?xml version='1.0' encoding='utf-8'?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!-- The contents of this file will be loaded for each web application -->
<Context>
  
	<path>/cxf</path>
	<docBase>/cxf</docBase>
	<reloadable>true<reloadable/>
	<debug>1<debug/>
  
    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
	
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->

    <!-- Uncomment this to enable Comet connection tacking (provides events
         on session expiration as well as webapp lifecycle) -->
    <!--
    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
    -->
</Context>
```


----------



## maki (22. Jul 2009)

Bei deinem Zitat aus der Tomcat DOku fehlt das wichtigste:


> - in individual files (with a ".xml" extension) in the $CATALINA_HOME/conf/[enginename]/[hostname]/ directory. The name of the file (less the .xml) extension will be used as the context path. Multi-level context paths may be defined using #, e.g. context#path.xml. The default web application may be defined by using a file called ROOT.xml.
> - if the previous file was not found for this application, in an individual file at /META-INF/context.xml inside the application files


Ausserdem noch:


> The locations for Context Descriptors are;
> 
> 1. $CATALINA_HOME/conf/[enginename]/[hostname]/context.xml
> 2. $CATALINA_HOME/webapps/[webappname]/META-INF/context.xml
> ...


Ich spreche von der [c]context.xml[/c] unter  [c]META-INF[/c] in deiner WebApp.

Vergiss die context.xml erstmal, aber wenn du unbedingt und ohne Alternative den Contextroot nutzen musst, machst du das am besten mit der Context.xml.

Wen du möchtest dass dein Context [c]cxf[/c] heisst und dein Service unter [c]http://serverort/cxf/MyService[/c] erreichbar sein soll, dann setze einfach den [c]finalName[/c] (und damit das War file und damit dann auch den Context) auf [c]cxf[/c] und lass eine eigene context.xml weg und stelle die Originaleinstellungen der Serverweiten context.xml zurück.


----------



## pocketom (22. Jul 2009)

> Wen du möchtest dass dein Context cxf heisst und dein Service unter http://server:port/cxf/MyService erreichbar ist, dann setze einfach den finalName (und damit das War file und damit dann auch den Context) auf cxf und lass eine eigene context.xml weg und stelle die Originaleinstellungen der Serverweiten context.xml zurück.



Aber das kanns doch nicht sein oder? Ich meine, ist doch logisch, natürlich will ich nicht das das WAR file cxf.war heisst. Das ist doch noch längst nicht der einzige Service den ich entwickeln will


Finales Ziel:

http://server:port/cxf/MyService1
http://server:port/cxf/MyService2
http://server:port/cxf/MyService3
...

Und die WARs sollen bitte alle in diesem einen cxf Verzeichnis liegen, sie sollen MyService1.war,  MyService2.war, MyService3.war heissen. Genauso wie meine Axis2 Services auch alle brav und ordentlich im axis2 Verzeichnis liegen...


Bin ich jetzt echt total bescheuert? Brauch ich evtl. Urlaub? Ich kapiers ned


----------



## maki (22. Jul 2009)

> Bin ich jetzt echt total bescheuert? Brauch ich evtl. Urlaub? Ich kapiers ned


Grundlagen zu Webapps:
Url = http://server:port/cxf/MyService1
Kontext = cxf
Warfile = cxf.war

Ein Context gilt nur für eine WebApp, 2 Webapps können sich nicht denselben Context Teilen.



> Finales Ziel:
> 
> http://server:port/cxf/MyService1
> http://server:port/cxf/MyService2
> http://server:port/cxf/MyService3


Das geht nicht so wie du dir das vorstellst 

Das wäre ein Context, deswegen eine Webapp und damit ein Warfile. 

Alternative: 
1. Mehrere Services in eine WebApp packen, und damit in ein Warfile und einen Context.
2. Apache vor den Tomcat schalten (AJP Connector, mod_jk oder ähnlich), und mit dem URL rewrite Modul arbeiten, umständlich imho, manchmal die einzige Alternative.

Vielleicht ist es jetzt klarer geworden


----------



## pocketom (22. Jul 2009)

Da liegt wohl der Hase im Pfeffer! Na, dann verzichte ich am besten ganz auf den Context oder?

Anmerkung: Das ist schon ziemlich crap oder? Ein Informatiker sollte doch an der Stelle den Drang danach verspüren die Dinge einheitlich und logisch zu strukturieren ;-)


----------



## pocketom (22. Jul 2009)

Hast du schonmal probiert das alle Services den RootContext nutzen?

So dass der Kontext generell entfällt: 

http://server:port/MyService1
http://server:port/MyService2
http://server:port/MyService3


Manche machen es ja so dass sie immer als ROOT.war deployed und danach von Hand umbenennen. Eine absolut grausame Methode bei der sich bei mir alle Nackenhaare aufstellen.

Der andere Ansatz ist wohl unter $CATALINA_HOME/conf/[enginename]/[hostname]/ eine ROOT.xml anzulegen.

Ich habe das also gemacht:
*ROOT.xml*

```
<?xml version='1.0' encoding='utf-8'?>
<Context docBase="" path="">
</Context>
```

Muss aber immer jeden Service mit Server/Context(=warfilename)/ServiceName aufrufen. Hast du einen Plan ob das wirklich geht und wie ich es anstellen muss?


----------



## maki (22. Jul 2009)

pocketom hat gesagt.:


> Da liegt wohl der Hase im Pfeffer! Na, dann verzichte ich am besten ganz auf den Context oder?
> 
> Anmerkung: Das ist schon ziemlich crap oder? Ein Informatiker sollte doch an der Stelle den Drang danach verspüren die Dinge einheitlich und logisch zu strukturieren ;-)


Die Dinge sind "einheitlich und logisch strukturiert", sogar in Form einer Sepozifikation (Servlet Spek.), du musst dich halt an die Struktur halten, eine Einstellung wie "Hoppla, jetzt komm ich" hilft dir auf Dauer nicht 



> ast du schonmal probiert das alle Services den RootContext nutzen?


Du scheinst immer noch nicht zu verstehen: Eine Webapp, ein Context, zwei Webapps können nicht einen Context teilen. 

Wenn du das verstanden hast, können wir wiedr über alternativen (oben bereits vorgesschlagen) diskutieren.

Das Hauptproblem ist imho aber, dass du zu wenig über Java Webapps im allgemeinen weisst, nicht falsch verstehen, aber du solltest dich doch etwas tiefer mit der Matierie befassen bevor du daran gehst zu sagen "Das muss so und so aussehen"


----------



## pocketom (22. Jul 2009)

Ich werds versuchen. Das Problem hierbei ist, der Chef sitzt mir natürlich im Nacken. Und der will eine "saubere" Lösung, nein mehr eine einheitliche Vorgehensweise fü zukünftige Projekte. Im Moment kann ich Ihm da nur anbieten: Wir können uns für jeden Service einen beliebigen Kontext aussuchen, aber jeder kann nur einmal für eine App verwendet werden. Das hab ich soweit schon kapiert. Die Frage ist eher ob der das so akzeptiert. So wie ich den kenne eher nicht ("ist sicher alles nur eine Konfigurationssache...").

Was würdest du vorschlagen?


----------



## maki (22. Jul 2009)

> Was würdest du vorschlagen?


Sehe da nur 2 Möglichkeiten wenn  die URL nicht flexibel ist:


> Alternative:
> 1. Mehrere Services in eine WebApp packen, und damit in ein Warfile und einen Context.
> 2. Apache vor den Tomcat schalten (AJP Connector, mod_jk oder ähnlich), und mit dem URL rewrite Modul arbeiten, umständlich imho, manchmal die einzige Alternative.


----------



## Noctarius (22. Jul 2009)

pocketom hat gesagt.:


> Wir können uns für jeden Service einen beliebigen Kontext aussuchen, aber jeder kann nur einmal für eine App verwendet werden.



Natürlich kann man das, sinnvoll wäre es vielleicht die Webapp-Contexts sinnvoll zu benennen. Z.B.:
http://www.foo.bar/management/Service
http://www.foo.bar/billing/Service
http://www.foo.bar/page/Service
http://www.foo.bar/foo/Service
http://www.foo.bar/bar/Service

Oder gleich auf eine REST Architektur umsteigen.


----------



## pocketom (22. Jul 2009)

Danke für Eure Antworten.

Ich denke da auch mehr an Variante 2 - sinnvolle Nomenclatur ausdenken. Mehr technologischen Aufwand dürfen wir im Moment leider nicht betreiben, ein weiterer Umstieg kommt auch nicht mehr in Frage.


http://www.foo.bar/management/Service
http://www.foo.bar/billing/Service
http://www.foo.bar/page/Service
http://www.foo.bar/foo/Service
http://www.foo.bar/bar/Service

gefällt mir schon ganz gut,


oder 

http://www.foo.bar/1/BillingService
http://www.foo.bar/2/InvoivingService
http://www.foo.bar/3/BlaBlubbService


usw...

Ich hab das Thema mal als Hausaufgabe an meinen Chef bzw. die Fachbereiche zurückdelegiert. "Wie hätten ses denn gerne?"


----------



## Noctarius (22. Jul 2009)

Also das durch zu nummerieren finde ich persönlich schon wieder pfui. Aber jedem das seine.


----------



## pocketom (23. Jul 2009)

War nicht meine Idee. Aber Fazit ist: Irgendwas sinnvolles wird man schon finden was man da reinschreiben kann. Ich habe das jetzt an unseren Fachbereich delegiert, bis der mit was konstruktivem zurück kommt hab ich wenigstens erstmal meine Ruhe


----------

