Maven War 插件Classes文件夹打为Jar包的Bug与解决方法

本文介绍如何在Maven的War插件中排除特定文件,尤其是在将WEB-INF/classes下的文件打包成jar时的问题及解决方案。通过巧妙配置,可以实现在构建过程中过滤并排除指定文件。

有时候我们需要利用Maven Resource管理的过滤功能将某些文件中的${XXX}变量在构建时进行动态替换,但同时我们不希望这些文件被加入到jar包中,因为它们是在jar包外或者只是部署时有用,这个需求在Maven的Jar插件中有对应的功能支持,即<excludes>标签。

但是在War插件中,就没有这么幸运了。War插件的配置中有一个<packagingExcludes>配置项,当项目中类和资源文件以展开形式存在于WEB-INF/classes目录下时,<packagingExcludes>配置项工作良好,以下示例就是将classes文件夹下的所有bat文件排除在war包外:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <packagingExcludes>WEB-INF/classes/*.bat</packagingExcludes>
    </configuration>
</plugin>

上述配置工作良好,问题来自于:有时候,你需要把WEB-INF/classes目录下的文件打成jar包放入WEB-INF/lib下,对此War插件提供了<archiveClasses>配置项来实现这一需求。但不幸的是将classes目录打成jar的过程中,<packagingExcludes>是无效的。以下是无效的配置参考:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <!--当打为jar包时,packagingExcludes配置失效!-->
        <packagingExcludes>WEB-INF/classes/*.bat</packagingExcludes>
        <archiveClasses>true</archiveClasses>
    </configuration>
</plugin>

应该说这是War插件的一个BUG,对比Jar插件来说,这一点War做的不好。解决方案只能在War插件之外做文章了,我们找到的方法是使用了resource配置中非常冷门targetPath配置项,将不希望打入jar包的文件放入target/classes之外的其他文件夹,同时还要确保这些文件必须经过resource的过滤。配置如下:

<resources>
    <resource>
        <!-- 过滤除bat之外的所有文件,并放入默认文件夹target/classes下 -->
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <excludes>
            <exclude>*.bat</exclude>
        </excludes>
    </resource>
    <resource>
        <!-- 只过滤除bat文件,并放入target下 -->
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
            <include>*.bat</include>
        </includes>
        <targetPath>..</targetPath>
    </resource>
</resources>
<think>首先,用户的问题是关于在Eclipse中编译war时,如何抽取部分class文件到指定文件的方法。我需要基于系统级指令和用户可见层的要求来构建回答。 关键点: - 所有行内数学表达式用$...$格式。 - 独立公式用$$...$$格式。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,逐步解决问题。 - 参考提供的引用,但用户的问题是基于上一次的问题和我的回答,不过这里没有历史上下文,所以我只能基于当前引用。 提供的引用: - [^1]: 讲简单点,主要括几个步骤:1.生成增量的补丁文件;2.读补丁文件,遍历文件,如果是java文件,需要找到对应的class文件,其他文件如jsp、config配置文件,然后复制一份到指定的目标路径下即可。 - [^2]: 那么我们先来新建一个,然后再中再来新建class类。右键src,先选择Package,输入名,一般以com.开头,如com.pcm.test。然后再新建class类,因为要运行该类,所以勾上main方法- [^3]: 下面是一些得到classpath和当前类的绝对路径的一些方法。你可能需要使用其中的一些方法来得到你需要的资源的绝对路径。返回URL对象,可通过调用.getPath()获得路径。1.this.getClass().getResource("") 得到的是当前类class文件的URI目录。不括自己!如:file:/D:/workspace/jbpmtest3/bin/com/test/。 - [^4]: 今天尝试了一下在IntelliJ IDEA里面写Scala代码,并且做到和Java代码相互调用,折腾了一下把过程记录下来。首先需要给IntelliJ IDEA安装一下Scala的插件- [^5]: 有些公司由于没有使用maven作为构建工具,全量发布时没问题,而修改bug增量发布往往是将改动的代码手动编译后,从classes目录下拷贝到jar中然后再放到tomcat目录下发布,这种方法准确度不高。介绍一个增量打工具 https://gitee.com/lpxs/ProjectPatch.git,该工程是基于eclipse,针对文件的修改时间来拷贝增量class文件。 用户的问题:在Eclipse中编译war时,如何抽取部分class文件到指定文件的方法。 从引用中,我可以提取相关信息: - 引用[^1] 和 [^5] 提到了增量发布和补丁文件的概念,涉及抽取部分文件。 - 引用[^5] 介绍了一个工具ProjectPatch,它是基于Eclipse的,用于拷贝增量class文件。 - 引用[^3] 讨论了获取classpath和路径的方法,这可能对定位class文件有用。 回答步骤: 1. **理解问题**:用户想在编译war时,只抽取特定的class文件到另一个位置,而不是整个war。这可能用于增量部署或部分更新。 2. **基本方法**:在Eclipse中,war是通过导出项目为WAR文件生成的。默认情况下,它会含所有编译后的class文件。要抽取部分class文件,需要在编译或导出过程中添加自定义步骤。 3. **解决方案**: - **手动方法**:在导出war之前,手动复制所需的class文件到指定目录。但这不是自动化的。 - **使用构建工具**:如果项目使用Maven或Gradle,可以配置构建脚本(如pom.xml)来排除或含特定文件。但用户提到没有使用Maven(根据引用[^5])。 - **自定义脚本**:使用Ant脚本或Eclipse插件来实现。 - **基于引用的方法**:引用[^5]提到了一个工具ProjectPatch,专为Eclipse设计,用于增量打。它可以配置时间范围和输出目录来拷贝修改过的class文件。 4. **详细步骤**: - 基于引用[^5],推荐使用ProjectPatch工具。 - 步骤: - 下载和设置ProjectPatch。 - 配置XML文件指定要抽取的文件路径、输出目录等。 - 运行工具来自动拷贝增量class文件。 - 如果没有工具,可以写一个Java程序或脚本,使用类似引用[^3]的方法来获取class文件路径。 5. **添加引用**:在回答中自然地引用相关部分。例如,当提到工具时,添加[^5]。 6. **结构清晰**: - 介绍问题。 - 提供解决方案。 - 分步解释。 - 总结。 7. **生成相关问题**:在最后,添加“相关问题”部分,类似于示例。 相关问题示例: 1. 如何配置Eclipse的war导出选项? 2. 什么是增量部署在Java Web应用中的最佳实践? 3. 如何自动化war的部分更新? 确保中文回答。 最终回答结构: - 开头解释问题。 - 主体:方法步骤。 - 结尾:相关问题。</think>### 在Eclipse中编译war时抽取部分class文件到指定文件的方法 在Eclipse中编译war时,抽取部分class文件到指定文件,通常用于增量部署或部分更新场景(例如修复bug时只替换修改过的class文件)。默认的war导出功能会将所有class文件打,但通过自定义配置或工具,可以实现部分抽取。以下方法基于Eclipse原生功能和扩展工具,逐步解释。核心思路是:在编译后、导出war前,筛选目标class文件并复制到指定位置。参考引用内容,我将结合手动方法和自动化工具进行说明。 #### 方法1: 手动复制(适合少量文件) 如果只需抽取少量class文件,可以通过Eclipse项目结构直接操作。步骤如下: 1. **编译项目**:确保项目已编译(Eclipse自动编译,或手动点击“Project” > “Build Project”),class文件生成在`bin`目录或指定输出路径。 2. **定位class文件**:在“Package Explorer”视图中,展开`bin`目录(或类似输出文件夹),找到目标class文件。例如,要抽取`com.example.MyClass.class`,路径可能为`bin/com/example/MyClass.class`。 3. **复制到指定文件**: - 右键点击目标class文件,选择“Copy”。 - 在文件系统中创建指定目录(如`D:\patch\classes`),然后粘贴文件。 - 完成后,这些class文件即可用于增量部署[^1]。 此方法简单,但效率低,不适合大量文件或自动化。引用[^5]指出,手动方法在文件较多时准确度不高。 #### 方法2: 使用增量打工具(推荐,适合自动化) 引用[^5]提到一个开源工具 **ProjectPatch**(基于Eclipse),它能自动扫描修改过的class文件并复制到指定目录。工具链接:https://gitee.com/lpxs/ProjectPatch.git。以下是配置步骤: 1. **下载和导入工具**: - 克隆或下载ProjectPatch项目到本地。 - 在Eclipse中,选择“File” > “Import” > “General” > “Existing Projects into Workspace”,导入ProjectPatch。 2. **配置XML文件**: - 在ProjectPatch项目中,编辑`patch.xml`文件(或类似配置文件),指定: - `classpath`:class文件源路径(通常为项目`bin`目录)。 - 输出目录(`defaultdirpath`):指定文件的目标位置,如`D:\patch`。 - 文件过滤规则:例如,设置`patchhour`为24,表示只抽取最近24小时内修改的文件;或通过`path`元素指定具体名(如`com.example.*`)。 - 示例配置(基于引用[^5]): ```xml <patch> <webpath> <jsppath> <warname>prm_admin.war</warname> <path>E:\workspace\PRM\DF\jsp\admin</path> </jsppath> </webpath> <configpath>E:\workspace\PRM\DF\iodd\config</configpath> <dbscriptpath>E:\workspace\PRM\DM\dbscript</dbscriptpath> <patchhour>24</patchhour> <!-- 时间范围,单位小时 --> <serverwarname>server.war</serverwarname> <defaultdirpath>D:\patch</defaultdirpath> <!-- 输出目录 --> </patch> ``` - 此配置会抽取所有在指定时间内修改的class文件到`D:\patch`,同时支持jsp和配置文件[^5]。 3. **运行工具**: - 在Eclipse中,右键点击ProjectPatch项目,选择“Run As” > “Java Application”。 - 工具会自动遍历源路径,根据修改时间复制增量class文件到输出目录。 4. **集成到war编译过程**: - 在导出war前运行此工具:先编译项目,再运行ProjectPatch,最后导出war(此时war可忽略这些class文件,或直接使用抽取后的文件)。 - 输出目录中的文件可直接用于Tomcat部署(如复制到`WEB-INF/classes`)。 此方法高效且可自动化,尤其适合非Maven项目(引用[^5]强调其在无构建工具环境中的优势)。工具通过文件修改时间过滤,确保准确性。 #### 方法3: 自定义脚本(Ant或Java程序) 如果不想使用第三方工具,可以编写Ant脚本或Java程序: - **Ant脚本**: 1. 在Eclipse中安装Ant插件(已内置)。 2. 创建`build.xml`文件,定义任务: ```xml <project name="ExtractClasses" default="extract"> <target name="extract"> <copy todir="D:\patch"> <fileset dir="bin"> <!-- 源路径 --> <include name="com/example/*.class"/> <!-- 指定或文件 --> <modified/> <!-- 可选:基于修改时间 --> </fileset> </copy> </target> </project> ``` 3. 运行脚本:右键`build.xml`,选择“Run As” > “Ant Build”。 - **Java程序**: - 使用引用[^3]的方法获取class文件路径,例如`this.getClass().getResource("").getPath()`定位当前类目录。 - 编写程序遍历`bin`目录,筛选文件并复制(需处理IO操作)。 #### 注意事项 - **路径问题**:确保Eclipse项目输出路径正确(Window > Preferences > Java > Build Path)。引用[^3]提醒,路径获取方法如`getResource("")`可能返回URI格式,需转换为文件路径。 - **性能**:增量工具优于手动方法,避免遗漏文件[^1][^5]。 - **适用场景**:此方法适用于测试或生产环境的热修复,但全量发布时建议使用标准war导出。 通过以上方法,您可以在Eclipse中高效抽取部分class文件。推荐ProjectPatch工具,它专为Eclipse设计,支持灵活配置[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Laurence 

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值