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

老铁们好,我是V,今天我们简单聊聊怎么修改jar包中的类

背景

我们有时候需要修改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

image-001.png

对应的插件设置也很简单

 <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 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 但是没有源码

于是我们添加

 <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>

我们看看下源码

image-002.png

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

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

打包源码

image-003.png

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

里面不需要任何内容

方案

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

     <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目录
     <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 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

mvn clean source:jar compile

我看下打包好的sources jar

image-004.png

舒服了

推送源码

但是问题又来了

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

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的后缀


```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/ 
```

结语

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

如果大佬们有更好的方法,请在评论区教教我,嘿嘿。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容