[JAVA] Create environment-independent war file using Maven profiles and maven-war-plugin

Introduction

In a multi-module project, I created a war file that does not depend on the environment by separating the web module and the environment setting module, and tried to execute it with Tomcat.

Target

  1. Separate the environment setting file in the web module into another module
  2. Create a configuration file for each DB connection destination and create a jar using profile
  3. Pass the path of the environment setting file to the Web module
  4. Deploy the web module to tomcat

Operating environment

1. Separate the environment setting file in the web module into another module

To confirm that it works even if the environment setting file webapp / WEB-INF / applicationContext.xml is moved to src / main / resources / META-INF, the struts-config.xml plug-in "org. When I changed /WEB-INF/applicationContext.xml specified in the parameter of the configuration file of" springframework.web.struts.ContextLoaderPlugIn "to classpath *: /META-INF/applicationContext.xml, it works without any problem. did.

Therefore, under the multi-module project, create the module xxx-env for environment setting, move applicationContext.xml to src / main / resources / META-INF, and add xxx-env.jar to the dependency on the web module side. I confirmed the operation.

This allowed us to separate the environment-dependent parts of the application into separate modules.

2. Create a configuration file for each DB connection destination and create a jar using profile

In the xxx-env module, we created 3 local (development) / staging (verification) / prod (production) and prepared applicationContext.xml that defines different DB connection destinations.

I have defined the following profiles in pom.xml of the xxx-env module.

pom.xml(env)


・ ・ ・
<build>
  <finalName>${buildFinalName}</finalName>
  <resources>
    <resource>
      <directory>${resource.directory}</directory>
    </resource>
  </resources>
</build>
<profiles>
  <profile>
    <id>local</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
      <resource.directory>src/main/resources</resource.directory>
      <buildFinalName>${project.artifactId}-${project.version}-dev</buildFinalName>
    </properties>
  </profile>
  <profile>
    <id>staging</id>
    <properties>
      <resource.directory>${basedir}/configs/staging/resources</resource.directory>
      <buildFinalName>${project.artifactId}-${project.version}-staging</buildFinalName>
    </properties>
  </profile>
  <profile>
    <id>prod</id>
    <properties>
      <resource.directory>${basedir}/configs/prod/resources</resource.directory>
      <buildFinalName>${project.artifactId}-${project.version}</buildFinalName>
    </properties>
    </profile>
</profiles>
・ ・ ・

If you specify the profile ID with the -P option when executing the Package or Install phase with the mvn command, a jar file will be created with the target resource. In the case of the above settings, -P prod is xxx-env.jar for production environment, -P staging is xxx-env-staging.jar for verification environment, and nothing is specified (default) is for development. Xxx-env-dev.jar will be executed.

3. Pass the path of the environment setting file to the Web module

Place xxx-env.jar in the Tomcat 7 directory ʻopt / environment / app` so that it can be referenced from the webapps module. This time, set VirtualWebappLoader in src / main / webapp / META-INF / context.xml of Web module, and include xxx-env.jar in Classpath of Web module.

src/main/webapp/META-INF/context.xml


<?xml version='1.0' encoding='utf-8'?>
<Context>
  <Loader className="org.apache.catalina.loader.VirtualWebappLoader" virtualClasspath="/opt/environment/logtime/prod/*.jar"/>
  <JarScanner scanAllDirectories="true"/>
</Context>

Run maven-war-plugin to set context.xml to be included in the WAR file.

pom.xml(web)


・ ・ ・
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-war-plugin</artifactId>
  <version>2.5</version>
  <configuration>
    <containerConfigXML>src/main/webapp/META-INF/context.xml</containerConfigXML>
  </configuration>
</plugin>
・ ・ ・

4. Deploy the web module to tomcat

Create a WAR file with the preferences removed and deploy it to Tomcat. Remove xxxx-env from dependency and set profiles so that xxxx-env is not included when creating a WAR.

pom.xml(Web)


・ ・ ・
<profiles>
  <profile>
    <id>local</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <dependencies>
      <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>xxxx-env</artifactId>
	<version>0.0.1-SNAPSHOT</version>
      </dependency>
    </dependencies>
  </profile>
  <profile>
    <id>warpack</id>
  </profile>
</profiles>
・ ・ ・

From the above, the dependency is removed from xxx-env only when'-P warpack'is specified. In other words, mvn -P warpack clean package will create a WAR that does not contain xxx-env.jar.

Deploy the created WAR to Tomcat's webapps.

Operation check and summary

When I started Tomcat and accessed the Web application, I was able to confirm that I was accessing the DB for the production environment. ʻReplace the jar in opt / environment / appwith xxx-env-staging.jar for the verification environment created by-P staging`, restart Tomcat, and this time you can access the DB for the verification environment. confirmed.

By doing this, for example, the WAR file is used for verification and production, so the identity of the module can be guaranteed and release errors can be reduced.

reference

Terasoluna 3.5. Build Development Project Set context-specific information in the War file Apache Maven WAR Plugin [Maven] How to add Apache Tomcat context.xml to WAR with Maven2 Location of context information

Recommended Posts

Create environment-independent war file using Maven profiles and maven-war-plugin
Save files and folders using File Manager
Create a Java Servlet and JSP WAR file to deploy to Apache Tomcat 9 in Gradle