webentwicklung-frage-antwort-db.com.de

Externalisierung der Tomcat-Webapp-Konfiguration aus der WAR-Datei

Ich habe Probleme mit der Konfiguration einer Webapp in Tomcat 7. In meiner WAR-Datei befindet sich eine Eigenschaftendatei myApp/WEB-INF/classes/myProps.props, die umgebungsspezifische Eigenschaften enthält. Ich versuche, diese Konfigurationsdatei auf dem Server zu überschreiben, damit dieselbe WAR-Datei in mehreren Umgebungen bereitgestellt wird.

Ich habe gehört, dass es eine Möglichkeit gibt, dies mit Ersatz-Konfigurationsdateien in Tomcat/conf/Catalina/myApp zu tun. Dies ist die Methode, bei der ich Probleme habe, herauszufinden.

Außerdem ist myApp.war einer von vielen, die auf demselben Tomcat-Server ausgeführt werden, und es wird nicht als localhost ausgeführt. Ich möchte dieses Problem für mehrere Webapps lösen können.

Server version: Apache Tomcat/7.0.23
Server built:   Nov 20 2011 07:36:25
Server number:  7.0.23.0
OS Name:        Linux
31
mfa

Ihr Tomcat/conf/Catalina/<Host> kann Kontextdeskriptoren enthalten, mit denen Sie viele Dinge konfigurieren können, einschließlich der Definition von "Umgebungseinträgen", auf die von Java aus über JNDI zugegriffen werden kann. Es gibt viele Möglichkeiten, es zu benutzen. Ich persönlich setze einen Umgebungseintrag, der den Dateisystempfad zu meiner Eigenschaftendatei darstellt. Meine App ist darauf ausgelegt, nach diesem Eintrag zu suchen. Wenn er nicht vorhanden ist, suchen Sie die Datei stattdessen im Klassenpfad. Auf diese Weise haben wir in dev die dev -Eigenschaften direkt im Klassenpfad, aber wenn wir sie erstellen und implementieren, verweisen wir auf eine externe Datei.

Es gibt eine gute Dokumentation zum Konfigurieren eines Kontexts auf der Tomcat-Website. Im Abschnitt Definieren eines Kontexts erfahren Sie, wie Sie die Datei erstellen und wo sie abgelegt wird.

Wenn Ihr Host beispielsweise myHost heißt und Ihre App eine War-Datei mit dem Namen myApp.war im Verzeichnis webapps ist, können Sie Tomcat/conf/Catalina/myHost/myApp.xml mit folgendem Inhalt erstellen:

<Context>
    <Environment name="configurationPath" value="/home/Tomcat/myApp.properties" type="Java.lang.String"/>
</Context>

Dann würden Sie in Ihrem Code eine JNDI-Suche nach Java:comp/env/configurationPath durchführen (hier 95% ige Sicherheit), um diesen String-Wert zu erhalten.

60
Ryan Stewart

Ich mag .properties-Dateien statt 

  • JNDI - warum komplexes Objekt während der Programmkonfiguration anstelle der Initialisierungszeit erstellen?
  • systemeigenschaften - Sie können nicht mehrere Instanzen derselben WAR in einem einzelnen Tomcat separat konfigurieren
  • kontextparameter - sie sind nur in javax.servlet.Filter, javax.servlet.ServletContextListener zugänglich, was unbequem sein kann

Tomcat 7 Context hold Loader Element. Gemäß docs Deployment-Deskriptor (was im <Context>-Tag enthalten ist) kann eingefügt werden:

  • $CATALINA_BASE/conf/server.xml - bad - Neustart des Servers erforderlich, um die Konfiguration erneut zu lesen
  • $CATALINA_BASE/conf/context.xml - bad - wird von allen Anwendungen gemeinsam genutzt
  • $CATALINA_BASE/work/$APP.war:/META-INF/context.xml - bad - Erfordert das Umpacken, um die Konfiguration zu ändern
  • $CATALINA_BASE/work/[enginename]/[hostname]/$APP/META-INF/context.xml - Nice, aber siehe letzte Option !!
  • $CATALINA_BASE/webapps/$APP/META-INF/context.xml - Nice, aber siehe letzte Option !!
  • $CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml - best - vollständig aus der Anwendung und automatisch auf Änderungen geprüft !!!

Context kann benutzerdefinierte Loaderorg.Apache.catalina.loader.VirtualWebappLoader (verfügbar in modernen Tomcat 7-Systemen) enthalten. Sie können own separaten Klassenpfad zu Ihrem .properties) und Parameter (Zugriff über FilterConfig.getServletContext().getInitParameter(name)) und Environment (Zugriff über new InitialContext().lookup("Java:comp/env").lookup("name")):

<Context docBase="${basedir}/src/main/webapp"
         reloadable="true">
    <!-- http://Tomcat.Apache.org/Tomcat-7.0-doc/config/context.html -->
    <Resources className="org.Apache.naming.resources.VirtualDirContext"
               extraResourcePaths="/WEB-INF/classes=${basedir}/target/classes,/WEB-INF/lib=${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
    <Loader className="org.Apache.catalina.loader.VirtualWebappLoader"
            virtualClasspath="${basedir}/target/classes;${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
    <JarScanner scanAllDirectories="true"/>

    <Parameter name="min" value="dev"/>
    <Environment name="app.devel.ldap" value="USER" type="Java.lang.String" override="true"/>
    <Environment name="app.devel.permitAll" value="true" type="Java.lang.String" override="true"/>
</Context>

Wenn Sie Spring und seine XML-Konfiguration verwenden:

<context:property-placeholder location="classpath:app.properties"/>

<bean id="dataSource" class="org.Apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="Oracle.jdbc.OracleDriver"/>
    <property name="url" value="jdbc:Oracle:thin:@${db.Host}:${db.port}:${db.user}"/>
    <property name="username" value="${db.user}"/>
    <property name="password" value="${db.pass}"/>
</bean>

Mit Spring Injizieren oben sind Eigenschaften in Bohnenfeldern einfach:

@Value("${db.user}") String defaultSchema;

statt JNDI:

@Inject ApplicationContext context;
Enviroment env = context.getEnvironment();
String defaultSchema = env.getProperty("db.user");

Beachten Sie auch, dass EL dies zulässt (Standardwerte und tiefe rekursive Substitution):

@Value('${db.user:testdb}') private String dbUserName;

<property name='username' value='${db.user.${env}}'/>

Siehe auch:

NOTE Durch die Erweiterung des Klassenpfads auf das Live-Verzeichnis durfte auch andere Konfigurationsdateien extern verwenden, beispielsweise logging, auth, atc. Ich ändere so logback.xml.

UPDATE _ ​​ Tomcat 8-Änderungssyntax für<Resources>- und <Loader>-Elemente. Der entsprechende Teil sieht jetzt folgendermaßen aus:

<Resources>
    <PostResources className="org.Apache.catalina.webresources.DirResourceSet"
                   webAppMount="/WEB-INF/classes" base="${basedir}/target/classes" />
    <PostResources className="org.Apache.catalina.webresources.DirResourceSet"
                   webAppMount="/WEB-INF/lib" base="${basedir}/target/${project.build.finalName}/WEB-INF/lib" />
</Resources>
43
gavenkoa

Sie können versuchen, Ihre Konfiguration (Eigenschaftendatei) in Apache Tomcat\lib in der JAR-Datei abzulegen und sie aus der Webanwendung zu entfernen. Wenn der Klassenlader des Tomcat Ihre Konfiguration nicht in webapp findet, versucht er, das Verzeichnis "lib" zu finden. Sie können Ihre Konfiguration also externisieren, indem Sie die Konfiguration in das globale Bibliotheksverzeichnis verschieben (es wird von anderen Webapps gemeinsam genutzt).

1
bmoc

Ich habe gerade ein setenv.bat- oder setenv.sh-Skript im bin-Ordner von Tomcat hinzugefügt. Stellen Sie die Variable classpath wie ein

set CLASSPATH=my-propery-folder
0
baliman