maven-shade-plugin打包 -- 资源转换类

321 阅读1分钟

最近在给一个Java项目打包的时候,使用了maven-shade-plugin插件,不过打包之后执行的时候,一直报错: 找不到onnxruntime-engine。通过查找资料发现,是因为我的项目中同时引入了pytorch-engine和onnxruntime-engine类库,这两个类库的 META-INF/services中都有名为ai.djl.engine.EngineProvider的文件。
ai.djl.engine.EngineProvider文件是在Java SPI机制下,通过与接口同名的文件来记录具体的实现类。当有多个同名文件时,说明该接口有多个实现类,没有配置资源转换类的情况下,这些接口的实现类会相互覆盖,最终导致有的实现类找不到。

image.png

maven-shade-plugin插件在给项目打包的时候,可以通过在pom.xml中配置如下资源转换类来避免实现类的相互覆盖:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.1</version>
    <executions>
        <execution>
            <!-- 绑定 Maven 生命周期的 package 阶段 -->
            <phase>package</phase>
            <goals>
                <!-- package 阶段执行时,让其调用插件的 repackage 目标 -->
                <goal>shade</goal>
            </goals>
        </execution>
    </executions>
    <!-- 设置插件属性 -->
    <configuration>
        <transformers>
            <!-- 设置 Java SPI 追加而非覆盖 -->
            <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
        </transformers>
    </configuration>
</plugin>

按照此配置打包的jar中,解压之后会发现 META-INF/services的ai.djl.engine.EngineProvider文件中有两个实现类。

另外,在用maven-shade-plugin打包的时候,只会打包classpath路径中的资源,项目根目录下的其他资源文件不会打包到jar中,这时需要通过IncludeResourceTransformer资源转换类来将非classpath路径中的资源中的文件打包进jar中,配置如下

<transformer
        implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
    <!-- 文件在jar包中的路径及文件名 -->
    <resource>models/ch_PP-OCRv4_det_infer/inference.onnx</resource>
    <!-- 要打包文件在项目中的相对路径 -->
    <file>models/ch_PP-OCRv4_det_infer/inference.onnx</file>
</transformer>
<transformer
        implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
    <resource>models/ch_PP-OCRv4_rec_infer/inference.onnx</resource>
    <file>models/ch_PP-OCRv4_rec_infer/inference.onnx</file>
</transformer>
<transformer
        implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
    <resource>models/ch_PP-OCRv4_rec_infer/dict.txt</resource>
    <file>models/ch_PP-OCRv4_rec_infer/dict.txt</file>
</transformer>