IcePDF打包后运行报NoClassDefFoundError错误求助
问题:Maven打包后Java应用运行时缺失IcePDF类
我使用IcePDF在Java应用中实现PDF文件查看功能,在NetBeans中运行一切正常,但执行mvn clean build后将应用移至本地磁盘运行时,抛出如下错误:
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/icepdf/ri/common/views/Controller
...
Caused by: java.lang.ClassNotFoundException: org.icepdf.ri.common.views.Controller
环境信息:Mac OSX 10.15.7 Catalina、JDK 17、Netbeans 16、Maven 4.0.0,已将IcePDF添加为本地仓库依赖。
我的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>com.rasweeny</groupId> <artifactId>Recipes</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>15</maven.compiler.source> <maven.compiler.target>15</maven.compiler.target> <exec.mainClass>com.rasweeny.recipes.Recipes</exec.mainClass> </properties> <dependencies> <dependency> <groupId>com.github.pcorless.icepdf</groupId> <artifactId>icepdf-core</artifactId> <version>7.0.1</version> <type>jar</type> </dependency> <dependency> <groupId>com.github.pcorless.icepdf</groupId> <artifactId>icepdf-viewer</artifactId> <version>7.0.1</version> <type>jar</type> </dependency> </dependencies> <reporting> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <configuration> <configLocation>config/sun_checks.xml</configLocation> </configuration> </plugin> </plugins> </reporting> <build> <plugins> <plugin> <!-- Build an executable JAR --> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.1.0</version> <configuration> <archive> <manifest> <mainClass>com.rasweeny.recipes.Launcher</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> <resources> <resource> <directory>[Users/rasweeny/jarfiles/icepdf-7.0.1/]</directory> <includes> <include>[icepdf-core-7.0.1.jar]</include> <include>[icepdf-viewer-7.0.1.jar]</include> <include>[fontbox-2.0.27.jar]</include> <include>[resource file #n]</include> </includes> </resource> </resources> </build> </project>
导入语句
import org.icepdf.ri.common.ComponentKeyBinding; import org.icepdf.ri.common.SwingController; import org.icepdf.ri.common.SwingViewBuilder;
核心代码
if (exten.equals("pdf")) { String filePath = file; SwingController controller = new SwingController(); SwingViewBuilder factory = new SwingViewBuilder(controller); SPanel viewerComponentPanel = (SPanel) factory.buildViewerPanel(); ComponentKeyBinding.install(controller, viewerComponentPanel); controller.getDocumentViewController().setAnnotationCallback( new org.icepdf.ri.common.MyAnnotationCallback( controller.getDocumentViewController())); // Create a JFrame to display the panel in JFrame window = new JFrame(fileName); Dimension pdfSize = new Dimension(640,800); window.setMinimumSize(pdfSize); window.setMaximumSize(pdfSize); window.setPreferredSize(pdfSize); window.add(viewerComponentPanel); window.pack(); window.setLocation((Toolkit.getDefaultToolkit().getScreenSize().width) / 2 - 600 / 2, (Toolkit.getDefaultToolkit().getScreenSize().height) / 2 - 800 / 2); window.setVisible(true); controller.openDocument(filePath); }
问题原因及解决方法
根本原因
- Maven打包未包含依赖库:当前使用的
maven-jar-plugin仅打包项目自身代码,不会将IcePDF等第三方依赖库纳入最终的jar文件,运行时JVM找不到这些类。 - 错误的resources配置:pom中的
<resources>块把jar文件当成普通资源处理,且路径和文件名中的[]是无效格式,Maven无法识别,这部分配置完全错误,毫无作用。
解决方案
方案一:构建可执行胖包(推荐)
使用maven-shade-plugin将所有依赖和项目代码打包成一个独立的可执行jar,无需额外依赖文件:
<build> <plugins> <!-- 移除原maven-jar-plugin,替换为shade插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.rasweeny.recipes.Launcher</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>
执行mvn clean package后,在target目录下找到带-shaded后缀的jar文件,直接运行即可。
方案二:分离式打包,配置依赖路径
如果不想打胖包,可将依赖复制到指定目录,并在jar的Manifest中配置类路径:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.1.0</version> <configuration> <archive> <manifest> <mainClass>com.rasweeny.recipes.Launcher</mainClass> <classpathPrefix>lib/</classpathPrefix> <addClasspath>true</addClasspath> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>
打包后,将target目录下的jar文件和lib文件夹一起移动到目标位置,运行jar即可。
额外优化建议
- 删除pom中错误的
<resources>配置,Maven会自动管理依赖,无需手动添加jar作为资源。 - 统一JDK版本:pom中
maven.compiler.source和target配置为15,但实际使用JDK17,建议修改为17避免版本兼容问题:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <exec.mainClass>com.rasweeny.recipes.Recipes</exec.mainClass> </properties>
内容的提问来源于stack exchange,提问作者rasweeny
相关产品推荐
相关产品推荐

