如何防止Maven打包WAR文件时修改文件时间戳?
问题描述
我有一个包含大量JSP文件的TomCat应用,最近从Gradle切换到Maven进行构建。现在遇到一个明显问题:Maven构建会把所有JSP文件的时间戳设为构建时间,这带来两个麻烦:
- 已解压的JSP文件会被不必要地传输到服务器,因为时间戳显示文件已修改但实际内容并没有变动
- 测试/调试阶段我会在TomCat服务器上编辑JSP文件,需要时间戳准确显示最后修改日期
我曾看到提示称这可能是Maven转换行结尾格式导致的,我也不希望出现这种转换,尝试在POM文件多处添加<lineEnding>KEEP</lineEnding>配置但无效果,不确定这是否为问题根源。以下是完整POM文件供参考:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany.app</groupId> <artifactId>my-app</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.purplehillsbooks.purple/purple --> <dependency> <groupId>com.purplehillsbooks.purple</groupId> <artifactId>purple</artifactId> <version>3.1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup --> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.17.1</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-catalina --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina</artifactId> <version>11.0.0-M15</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.11</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.14</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>8</source> <target>8</target> <lineEnding>KEEP</lineEnding> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <configuration> <lineEnding>keep</lineEnding> <attachClasses>true</attachClasses> <webXml>src/main/webapp/WEB-INF/web.xml</webXml> <webResources> <resource> <directory>src/main/webapp</directory> <filtering>true</filtering> </resource> </webResources> </configuration> </plugin> </plugins> </build> </project>
解决方案
你的核心问题出在maven-war-plugin的全局资源过滤配置,以及lineEnding参数的正确配置位置,具体调整步骤如下:
1. 关闭JSP文件的不必要过滤
你当前对src/main/webapp开启了<filtering>true</filtering>,这会让Maven对所有web资源(包括JSP)进行变量替换处理,哪怕文件里没有可替换的变量,处理后的文件也会生成新的时间戳。如果你的JSP不需要Maven变量替换,直接关闭全局过滤:
<plugin> <artifactId>maven-war-plugin</artifactId> <version>3.3.2</version> <!-- 建议升级到稳定新版本 --> <configuration> <attachClasses>true</attachClasses> <webXml>src/main/webapp/WEB-INF/web.xml</webXml> <webResources> <resource> <directory>src/main/webapp</directory> <!-- 关闭全局过滤,避免处理所有JSP --> <filtering>false</filtering> <!-- 如果确实需要过滤特定文件(比如web.xml),单独指定 --> <!-- <includes> <include>WEB-INF/web.xml</include> </includes> --> </resource> </webResources> </configuration> </plugin>
如果必须对部分文件做过滤,不要全局开启,而是通过<includes>指定具体文件,避免影响JSP。
2. 正确配置行结尾保持
lineEnding的配置应该放在maven-resources-plugin中,而不是maven-compiler-plugin或maven-war-plugin的根节点。添加该插件来控制资源文件的行结尾和过滤规则:
<plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.3.1</version> <configuration> <lineEnding>KEEP</lineEnding> <!-- 标记JSP为无需过滤的文件,彻底避免被处理 --> <nonFilteredFileExtensions> <nonFilteredFileExtension>jsp</nonFilteredFileExtension> <nonFilteredFileExtension>jspx</nonFilteredFileExtension> </nonFilteredFileExtensions> </configuration> </plugin>
这个配置会让Maven完全保留原始文件的行结尾,同时排除JSP文件的过滤处理,从根源上避免时间戳被修改。
3. 验证调整效果
执行mvn clean package后,查看target目录下的JSP文件,其时间戳应该和源文件的最后修改时间一致,而不是构建时间。
内容的提问来源于stack exchange,提问作者AgilePro

