使用maven插件修改jar包中的class并推送源码

背景

我们有时候需要修改jar中的某个class,有时候是因为需要修复某些bug,有时候是定制化开发

例如为了实现es的索引动态修改索引中的压缩算法,我们需要修改lucene-core中的IndexWriter.class这个类

解决方案

方法一、解压jar包将修改后的class放进去重新压缩

这个方法虽然可行,但是显得很蠢

方法二、下载源码自己编译修改

从github上下载源码后,自己修改源码,重新编译,这当然是最彻底的解决方案。但是lucene-core 7.7.3是用ant编译的,是我太菜了,我试了很多次,都没编译成功。

方法三、maven-dependency-plugin插件替换class打包

这也是本文重点介绍的方法

我们建好java项目后,将IndexWriter.java源码复制出来,放到指定的package修改好后放到指定的package

 对应的插件设置也很简单

 

xml

代码解读

复制代码

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>${maven-dependency-plugin.version}</version> <executions> <execution> <id>replace-custom-class</id> <phase>generate-sources</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <overWrite>false</overWrite> <outputDirectory>${project.build.directory}/classes</outputDirectory> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin>

这样插件就会将lucene-core的class解压,然后将我们自定义的IndexWriter编译后覆盖原生的IndexWriter.class

完整pom.xml

 

xml

代码解读

复制代码

<?xml version="1.0" encoding="UTF-8"?> <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>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <version>${lucene-core.version}-0.0.1-SNAPSHOT</version> <properties> <java.version>8</java.version> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version> <maven-compiler-plugin.encoding>UTF-8</maven-compiler-plugin.encoding> <maven-dependency-plugin.version>3.6.0</maven-dependency-plugin.version> <maven-source-plugin.version>3.3.0</maven-source-plugin.version> <lucene-core.version>7.7.3</lucene-core.version> </properties> <dependencies> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <version>${lucene-core.version}</version> </dependency> </dependencies> <distributionManagement> <snapshotRepository> <id>xxx-snapshots</id> <name>Nexus Snapshot Repository</name> <url>http://xxx.com/nexus/content/repositories/snapshots/</url> </snapshotRepository> <repository> <id>xxx-releases</id> <name>Nexus Release Repository</name> <url>http://xxx.com/nexus/content/repositories/releases/</url> </repository> </distributionManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven-compiler-plugin.version}</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <encoding>${maven-compiler-plugin.encoding}</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>${maven-dependency-plugin.version}</version> <executions> <execution> <id>replace-custom-class</id> <phase>generate-sources</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <overWrite>false</overWrite> <outputDirectory>${project.build.directory}/classes</outputDirectory> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>

执行命令打包

 

代码解读

复制代码

mvn clean install -DskipTests

这样得到的jar就可以直接用了

遇到的问题

你以为这就结束了吗?虽然我们功能实现了,但是jar包中的其他的类的源码无法查看了,虽然不影响使用,但是有些膈应。

源码无法查看

虽然通过上面的方式我们得到了定制化的jar lucene-core-7.7.3-0.0.1-SNAPSHOT.jar 但是没有源码

于是我们添加

 

xml

代码解读

复制代码

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>3.2.1</version> <executions> <execution> <id>attach-sources</id> <phase>package</phase> <goals> <goal>jar</goal> </goals> <configuration> <attach>true</attach> </configuration> </execution> </executions> </plugin>

我们看看下源码

麻了,这里面只有我们修改的类的源码,虽然不影响使用,但是后续我们debug的时候会非常麻。

查了很久的资料,发现maven-source-plugin没有办法指定源码的位置,于是就采用了另外一个不太优雅的方法

打包源码

首先我们在目录下另外建一个lucene-core-7.7.3-sources

里面不需要任何内容

方案

  • generate-sources阶段使用maven-dependency-plugin解压lucene-core-sources.jar到lucene-core-7.7.3-sources/src/main/java文件夹

     

    xml

    代码解读

    复制代码

    <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>${maven-dependency-plugin.version}</version> <executions> <execution> <id>source-unpack</id> <phase>generate-sources</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <overWrite>false</overWrite> <classifier>sources</classifier> <outputDirectory>${project.basedir}/src/main/java</outputDirectory> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin>
  • 使用exec-maven-plugin拷贝lucene-core-7.7.3中的源码到lucene-core-7.7.3-sources/src/main/java目录下

    这个插件主要作用

    • clean阶段清理lucene-core-7.7.3-sources/src/main文件夹
    • generate-sources阶段拷贝lucene-core-7.7.3/src/main/java/org/apache/lucene/index/IndexWriter.java到lucene-core-7.7.3-sources对应目录
    • compile阶段清理lucene-core-7.7.3-sources/src/main/java目录

    这边整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

     需要全套面试笔记的【点击此处即可】免费获取

    xml

    代码解读

    复制代码

    <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.2.0</version> <executions> <!-- source.jar生成之前,clean阶段清理main/java文件夹 --> <execution> <id>clean-sources</id> <phase>clean</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>bash</executable> <arguments> <argument>-c</argument> <argument>rm -rf ${project.basedir}/src/main/</argument> </arguments> </configuration> </execution> <!-- 从lucene-core-7.7.3中拷贝源码到main/java文件夹 --> <execution> <id>copy-custom-sources</id> <phase>generate-sources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>bash</executable> <arguments> <argument>-c</argument> <argument>cp -r ${project.basedir}/../lucene-core-${lucene-core.version}/src/main/java ${project.basedir}/src/main/</argument> </arguments> </configuration> </execution> <!-- compile阶段清理main/java文件夹 --> <execution> <id>clean-sources-after-compile</id> <phase>compile</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>bash</executable> <arguments> <argument>-c</argument> <argument>rm -rf ${project.basedir}/src/main/</argument> </arguments> </configuration> </execution> </executions> </plugin>
  • 使用maven-source-plugin打包源码

    这个大家都熟悉,就懒得贴了

完整pom.xml如下

 

xml

代码解读

复制代码

<?xml version="1.0" encoding="UTF-8"?> <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>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <version>${lucene-core.version}-0.0.1-SNAPSHOT</version> <properties> <java.version>8</java.version> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version> <maven-compiler-plugin.encoding>UTF-8</maven-compiler-plugin.encoding> <maven-dependency-plugin.version>3.6.0</maven-dependency-plugin.version> <maven-source-plugin.version>3.3.0</maven-source-plugin.version> <lucene-core.version>7.7.3</lucene-core.version> </properties> <dependencies> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <version>${lucene-core.version}</version> </dependency> </dependencies> <distributionManagement> <snapshotRepository> <id>xxx-snapshots</id> <name>Nexus Snapshot Repository</name> <url>http://xxx.com/nexus/content/repositories/snapshots/</url> </snapshotRepository> <repository> <id>xxx-releases</id> <name>Nexus Release Repository</name> <url>http://xxx.com/nexus/content/repositories/releases/</url> </repository> </distributionManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven-compiler-plugin.version}</version> <configuration> <skip>true</skip> <source>${java.version}</source> <target>${java.version}</target> <encoding>${maven-compiler-plugin.encoding}</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>3.2.1</version> <executions> <execution> <id>attach-sources</id> <phase>package</phase> <goals> <goal>jar</goal> </goals> <configuration> <attach>true</attach> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>${maven-dependency-plugin.version}</version> <executions> <execution> <id>source-unpack</id> <phase>generate-sources</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <overWrite>false</overWrite> <classifier>sources</classifier> <outputDirectory>${project.basedir}/src/main/java</outputDirectory> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.2.0</version> <executions> <!-- source.jar生成之前,clean阶段清理main/java文件夹 --> <execution> <id>clean-sources</id> <phase>clean</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>bash</executable> <arguments> <argument>-c</argument> <argument>rm -rf ${project.basedir}/src/main/</argument> </arguments> </configuration> </execution> <!-- 从lucene-core-7.7.3中拷贝源码到main/java文件夹 --> <execution> <id>copy-custom-sources</id> <phase>generate-sources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>bash</executable> <arguments> <argument>-c</argument> <argument>cp -r ${project.basedir}/../lucene-core-${lucene-core.version}/src/main/java ${project.basedir}/src/main/</argument> </arguments> </configuration> </execution> <!-- source.jar生成完毕,compile阶段清理main/java文件夹 --> <execution> <id>clean-sources-after-compile</id> <phase>compile</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>bash</executable> <arguments> <argument>-c</argument> <argument>rm -rf ${project.basedir}/src/main/</argument> </arguments> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>

执行命令打包source.jar

这里的compile是为了触发clean-sources-after-compile

 

bash

代码解读

复制代码

mvn clean source:jar compile

我看下打包好的sources jar

舒服了

推送源码

但是问题又来了

这样本来一个项目被我们分成了两个,这时候推送分两次使用mvn clean deploy -DskipTests推送jar包,特别是snapshot的jar会有maven-metadata.xml

 

xml

代码解读

复制代码

<metadata modelVersion="1.1.0"> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <version>7.7.3-0.0.1-SNAPSHOT</version> <versioning> <snapshot> <timestamp>20240811.061414</timestamp> <buildNumber>17</buildNumber> </snapshot> <lastUpdated>20240811061414</lastUpdated> <snapshotVersions> <snapshotVersion> <extension>jar</extension> <value>7.7.3-0.0.1-20240811.061414-17</value> <updated>20240811061414</updated> </snapshotVersion> <snapshotVersion> <extension>pom</extension> <value>7.7.3-0.0.1-20240811.061414-17</value> <updated>20240811061414</updated> </snapshotVersion> <snapshotVersion> <classifier>sources</classifier> <extension>jar</extension> <value>7.7.3-0.0.1-20240811.061532-17</value> <updated>20240811061532</updated> </snapshotVersion> </snapshotVersions> </versioning> </metadata>

我们会发现jar的版本和sources jar的版本不一致,导致在idea中无法匹配

所以需要一次性将jar和sources jar一起推送到maven仓库才行

经过一番查阅资料后发现可以用mvn命令可以解决问题

安装sources jar到本地
 

ini

代码解读

复制代码

mvn install:install-file \ -Dfile=$PWD/lucene-core-7.7.3-sources/target/lucene-core-7.7.3-0.0.1-SNAPSHOT-sources.jar \ -DgroupId=org.apache.lucene \ -DartifactId=lucene-core \ -Dversion=7.7.3-0.0.1-SNAPSHOT \ -Dpackaging=jar \ -Dclassifier=sources

同时推送jar和source.jar

好了,注意看,这行命令就是这篇文章最有价值的地方了

使用-Dfile指定jar的路径

使用-Dfiles指定source jar的路径,使用-Dtypes指定source jar的后缀

 

ini

代码解读

复制代码

```bash mvn deploy:deploy-file \ -DgroupId=org.apache.lucene \ -DartifactId=lucene-core \ -Dversion=7.7.3-0.0.1-SNAPSHOT \ -Dpackaging=jar \ -Dfile=$PWD/lucene-core-7.7.3/target/lucene-core-7.7.3-0.0.1-SNAPSHOT.jar \ -Dclassifiers=sources \ -Dtypes=jar \ -Dfiles=$PWD/lucene-core-7.7.3-sources/target/lucene-core-7.7.3-0.0.1-SNAPSHOT-sources.jar \ -DrepositoryId=xxx-snapshots \ -Durl=http://xxx.com/nexus/content/repositories/snapshots/ ```

结语

收工搞定,虽然这个方法还是不够优雅,但是好歹也不是太高频的操作,解决了打包源码的问题凑合用得了。

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值