错误描述
在上传图片的时候,我们的项目需要做一些上传后的处理。但是,在上传 JPEG 文件后运行代码
BufferedImage bImg = ImageIO.read(file);
触发异常:
Caused by: java.lang.NoClassDefFoundError: com/twelvemonkeys/imageio/util/ProgressListenerBase
at com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReaderSpi.createReaderInstance(JPEGImageReaderSpi.java:126)
at javax.imageio.spi.ImageReaderSpi.createReaderInstance(ImageReaderSpi.java:320)
at javax.imageio.ImageIO$ImageReaderIterator.next(ImageIO.java:529)
at javax.imageio.ImageIO$ImageReaderIterator.next(ImageIO.java:513)
at javax.imageio.ImageIO.read(ImageIO.java:1443)
at javax.imageio.ImageIO.read(ImageIO.java:1308)
上传 PNG 文件时一切正常。
项目配置
我们的 Java EE 7 项目最初需要 TwelvesMonkeys 来处理 CMYK 编码的 JPG 图像。EAR 由以下部分组成:
- 项目通用 (JAR)
- project-ejb (EJB) => 依赖于 project-common
- project-web (WAR) => 依赖于 project-common 和 project-ejb
- project-rest (WAR) => 依赖于 project-common 和 project-ejb
project-common
具有 TwelveMonkeys 依赖项:
<!-- Image IO -->
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-jpeg</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-bmp</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.servlet</groupId>
<artifactId>servlet</artifactId>
<version>3.3.2</version>
</dependency>
通过传递性转发给其他组件。我们只处理.jp(e)g
和.png
。我们还使用Thumbnailator和 TwelveMonkeys。
故障排除
在文档和这个 SO question之后,我在以下位置添加了监听器
project-web
:<listener> <display-name>ImageIO service provider loader/unloader</display-name> <listener-class>com.twelvemonkeys.servlet.image.IIOProviderContextListener</listener-class> </listener>
在 Netbeans 下,
com/twelvemonkeys/imageio/util/ProgressListenerBase
存在于project-ejb
,project-web
所以我不明白为什么找不到该类无论是否
ImageIO.read(file)
调用project-ejb
orproject-web
,错误都是一样的ImageIO.scanForPlugins()
我之前尝试添加ImageIO.read(file)
,错误是一样的
解决方法
下列的
另一个安全的选择是将 JAR 文件放在应用程序服务器的共享或公共 lib 文件夹中。
我已经手动放置了依赖项
# common dependencies:
> common-image-3.3.2.jar
> common-io-3.3.2.jar
> common-lang-3.3.2.jar
# shared dependencies:
> imageio-core-3.3.2.jar
> imageio-metadata-3.3.2.jar
# TwelveMonkeys dependencies:
> imageio-jpeg-3.3.2.jar
> imageio-bmp-3.3.2.jar
# Servlet
> servlet-3.3.2.jar
在{PAYARA_DIR}\glassfish\domains\{DOMAIN_NAME}\lib
文件夹中而不删除侦听器。我将依赖项范围更改为,<scope>provided</scope>
因为它没有嵌入到应用程序中。
我把它作为一种解决方法,因为我知道添加侦听器应该已经足够了,以至于手动添加依赖项似乎有点过头了。此外,即使我们不经常更改依赖项版本,更改 TwelveMonkeys 依赖项也意味着需要手动更新和替换这些依赖项。
问题:这种解决方法是唯一的解决方案还是我在哪里搞砸了?