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

老鐵們好,我是V,今天我們簡單聊聊怎么修改jar包中的類

背景

我們有時候需要修改jar中的某個class,有時候是因為需要修復(fù)某些bug,有時候是定制化開發(fā)

例如為了實現(xiàn)es的索引動態(tài)修改索引中的壓縮算法,我們需要修改lucene-core中的IndexWriter.class這個類

解決方案

方法一、解壓jar包將修改后的class放進(jìn)去重新壓縮

這個方法雖然可行,但是顯得很蠢

方法二、下載源碼自己編譯修改

從github上下載源碼后,自己修改源碼,重新編譯,這當(dāng)然是最徹底的解決方案。但是lucene-core 7.7.3是用ant編譯的,是我太菜了,我試了很多次,都沒編譯成功。

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

這也是本文重點(diǎn)介紹的方法

我們建好java項目后,將IndexWriter.java源碼復(fù)制出來,放到指定的package修改好后放到指定的package

image-001.png

對應(yīng)的插件設(shè)置也很簡單

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

執(zhí)行命令打包

mvn clean install -DskipTests

這樣得到的jar就可以直接用了

遇到的問題

你以為這就結(jié)束了嗎?雖然我們功能實現(xiàn)了,但是jar包中的其他的類的源碼無法查看了,雖然不影響使用,但是有些膈應(yīng)。

源碼無法查看

雖然通過上面的方式我們得到了定制化的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

麻了,這里面只有我們修改的類的源碼,雖然不影響使用,但是后續(xù)我們debug的時候會非常麻。

查了很久的資料,發(fā)現(xiàn)maven-source-plugin沒有辦法指定源碼的位置,于是就采用了另外一個不太優(yōu)雅的方法

打包源碼

image-003.png

首先我們在目錄下另外建一個lucene-core-7.7.3-sources

里面不需要任何內(nèi)容

方案

  • 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對應(yīng)目錄
    • 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>

執(zhí)行命令打包source.jar

這里的compile是為了觸發(fā)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>

我們會發(fā)現(xiàn)jar的版本和sources jar的版本不一致,導(dǎo)致在idea中無法匹配

所以需要一次性將jar和sources jar一起推送到maven倉庫才行

經(jīng)過一番查閱資料后發(fā)現(xiàn)可以用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/ 
```

結(jié)語

收工搞定,雖然這個方法還是不夠優(yōu)雅,但是好歹也不是太高頻的操作,解決了打包源碼的問題湊合用得了。

如果大佬們有更好的方法,請在評論區(qū)教教我,嘿嘿。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 所有項目的構(gòu)建都是有生命周期的,這個生命周期包括:項目清理、初始化、編譯、測試、打包、集成測試、驗證、部署、站點(diǎn)生...
    zlcook閱讀 2,997評論 0 21
  • 添加maven插件 添加Spring Cloud Contract BOM <dependencyManageme...
    咔啡閱讀 572評論 0 1
  • 修改 maven 的倉庫地址[root@node01 cloudera]# cat /usr/share/mave...
    lei_charles閱讀 1,318評論 0 0
  • POM 代表“Project Object Model”。它是 Maven 項目的 XML 表示形式,保存在名為 ...
    rosy_dawn閱讀 2,193評論 0 1
  • 首先說明,本人并不是第一次學(xué)習(xí)maven,也不是第二次學(xué)習(xí)maven,為什么還要來學(xué)習(xí)寫下這些東西?是因為之前一直...
    渭小粉閱讀 465評論 0 1

友情鏈接更多精彩內(nèi)容