Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tomcat deploys older version of webapp

This might be a duplicate, cause I can't image that we're the first to encounter this, but I can't seem to find it.

So, we are deploying WAR files to a tomcat 8.5 server with gitlab ci using maven. Issue is that tomcat messes up the versions when we moved from 0.2.9 to 0.2.10. Apparendly the server deploys the WARs in alphabetical order and 0.2.10 lies between 0.2.1 and 0.2.2 and the running version is still 0.2.9 even while 0.2.10 was correctly deployed to the server.

Full webapp name looks like: WebappName##0.2.10-SNAPSHOT_201901010000.war

We thought about renaming our versions to 0.2.009 and 0.2.010 but that seems like a rather dirty work-around. Of cause older versions will be deleted from time to time so it's not a permanent problem, but it's just somewhat annoying and any hints on how to solve this would be great.

From the pom.xml

<version>0.2.10-SNAPSHOT</version>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.install.skip>true</maven.install.skip>
    <timestamp>${maven.build.timestamp}</timestamp>
    <maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
</properties>
[..]
<profile>
    <id>deploy-stage</id>
    <activation>
        <activeByDefault>false</activeByDefault>
    </activation>
    <properties>
        <war.name>WebappName##${project.version}_${timestamp}</war.name>
        <tomcat.url>http://[..]/manager/text</tomcat.url>
        <tomcat.server>[..]</tomcat.server>
        <tomcat.webpath>/${war.name}</tomcat.webpath>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <id>default-war</id>
                        <goals>
                            <goal>manifest</goal>
                            <goal>war</goal>
                        </goals>
                        <phase>package</phase>
                    </execution>
                </executions>
                <configuration>
                        <warName>${war.name}</warName>
                    <failOnMissingWebXml>true</failOnMissingWebXml>
                    <archive>
                        <addMavenDescriptor>true</addMavenDescriptor>
                        <forced>true</forced>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <packageName>true</packageName>
                            <useUniqueVersions>true</useUniqueVersions>
                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                        </manifest>
                        <manifestEntries>
                            <Build-Time>${maven.build.timestamp}</Build-Time>
                            <Archetype>${archetypeArtifactId}</Archetype>
                            <Archetype-Version>${archetypeVersion}</Archetype-Version>
                        </manifestEntries>
                    </archive>
                    <webResources>
                        <resource>
                            <filtering>true</filtering>
                            <directory>src/main/webapp</directory>
                            <includes>
                                <include>**/web.xml</include>
                            </includes>
                        </resource>
                    </webResources>
                    <warSourceDirectory>src/main/webapp</warSourceDirectory>
                    <webXml>src/main/webapp/WEB-INF/web.xml</webXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <warFile>${project.build.directory}/${war.name}.war</warFile>
                    <url>${tomcat.url}</url>
                    <server>${tomcat.server}</server>
                    <path>${tomcat.webpath}</path>
                </configuration>
                <executions>
                    <execution>
                        <phase>deploy</phase>
                        <goals>
                            <goal>deploy</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</profile>

From gitlab-ci.yml

variables:
  MAVEN_OPTS: "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
  MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"

# Cache downloaded dependencies and plugins between builds.
cache:
  paths:
    - /root/.m2/repository/

stages:
  - build
  - deploy

# Run deploy 
deploy:staging:
  stage: deploy
  script:
    - 'mvn $MAVEN_CLI_OPTS -Dsonar.branch=$CI_BUILD_REF_NAME deploy -am -P deploy-stage'
  only:
    - staging
  image: maven:3.3.9-jdk-8
like image 978
Fussel Avatar asked Jan 18 '19 10:01

Fussel


People also ask

Which folder of Tomcat do you have to put your web application?

Simply put, web applications are placed under $CATALINA_HOME\webapps, where $CATALINA_HOME is the Tomcat's installation directory. The context path refers to the location relative to the server's address which represents the name of the web application.

How do I change the deployment path in Tomcat?

1- Custom Deploy Directory Follow the steps below to change the default deploy directory of Tomcat in Eclipse. Select “use custom location” radio button in the “Server Locations” section and set your custom deploy path.


1 Answers

As the Apache Tomcat documentation says:

String comparisons are used to determine version order.

This is simply not the same as comparison of Maven artifact versions. A version of 2.0.2 is always larger by String comparison than 2.0.10 or even 2.0.15000 etc.

I guess you have something like this in your pom.xml:

<properties>
  <buildTimestamp>${maven.build.timestamp}</buildTimestamp>
  <maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
</properties>
<build>
  <finalName>${project.artifactId}##${project.version}_${maven.build.timestamp}</finalName>
</build>

You can change that to:

<finalName>${project.artifactId}##${maven.build.timestamp}_${project.version}</finalName>

which yields a file name like WebappName##201901010000_0.2.10-SNAPSHOT.war.

This way the most current build by timestamp will be deployed as currently active application version.

Alternatively you can keep your version schema of the .war file name and instead have your app deployed using a versioned file name for your context.xml:

apache-tomcat/conf/Catalina/localhost/WebappName##201901010000.xml with the content:

<Context docBase="/path/to/WebappName##0.2.10-SNAPSHOT_201901010000.war" path="/WebappName"/>

In Apache Tomcat Manager this will show up as version 201901010000 in application version column. Again the most current build by timestamp will be deployed as currently active application version independent of the Maven artifact version as the deployment version String is taken from the .xml file name instead of the .war file name.

like image 93
Selaron Avatar answered Sep 19 '22 02:09

Selaron