You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache FOP打包为可执行Jar后无法加载SVG图片的问题问询

解决Apache FOP打包后SVG图片加载失败的问题

你的问题核心是Maven Assembly Plugin打包jar-with-dependencies时,会覆盖多个依赖Jar中同名的META-INF/services文件,而xmlgraphics-commons依赖Java SPI机制(扫描该目录下的配置文件)注册图片加载器,SVG相关的PreloaderSVG配置被覆盖后,自然无法识别SVG格式。

以下是三种可行的解决方案:

方案一:配置Assembly Plugin合并服务文件

修改Assembly插件的打包规则,让它合并而非覆盖META-INF/services下的同名文件:

  1. 创建或修改assembly描述文件(如src/main/assembly/assembly.xml),添加合并策略:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
    <id>jar-with-dependencies</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <unpack>true</unpack>
            <scope>runtime</scope>
            <unpackOptions>
                <mergeManifest>true</mergeManifest>
                <!-- 合并所有META-INF/services下的配置文件 -->
                <mergeStrategy>
                    <mergeStrategyKey>META-INF/services/**</mergeStrategyKey>
                    <mergeStrategyValue>merge</mergeStrategyValue>
                </mergeStrategy>
            </unpackOptions>
        </dependencySet>
    </dependencySets>
</assembly>
  1. 在pom.xml中引用该描述文件:
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.6.0</version>
    <configuration>
        <descriptor>src/main/assembly/assembly.xml</descriptor>
        <archive>
            <manifest>
                <mainClass>project.Mavenproject2</mainClass>
            </manifest>
        </archive>
    </configuration>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>

重新打包后,所有依赖的SPI配置会被合并,SVG加载器即可正常注册。

方案二:手动注册SVG加载器

绕开SPI机制,在代码中直接注册SVG预加载器:

import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.fop.image.loader.batik.PreloaderSVG;
import org.apache.fop.apps.FopFactory;

// 初始化FOP时添加注册逻辑
FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
ImageManager imageManager = fopFactory.getImageManager();
// 手动注册SVG预加载器
imageManager.getRegistry().registerPreloader(new PreloaderSVG());

这种方式不依赖打包时的SPI配置,无论用哪种打包方式都能生效。

方案三:更换为Maven Shade Plugin(推荐)

Shade插件专门针对可执行Jar打包设计,默认支持合并META-INF/services文件,配置更简洁:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.5.1</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>project.Mavenproject2</mainClass>
                    </transformer>
                    <!-- 显式指定合并services文件 -->
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

打包后执行java -cp target/xxx-1.0-SNAPSHOT.jar project.Mavenproject2即可正常加载SVG图片。

内容的提问来源于stack exchange,提问作者Peter Hull

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 22:13:22