TwelveMonkeys: ProgressListenerBase class not found when reading JPEG

1.2k Views Asked by At

Error description

When uploading a picture, our project needs to do some post-upload processing. However, running the code after upload a JPEG file

BufferedImage bImg = ImageIO.read(file);

triggers the exception:

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)

Everything works well when uploading a PNG file.

Project configuration

Our Java EE 7 project initially requires TwelvesMonkeys to handle CMYK-encoded JPG images. The EAR is composed of:

  • project-common (JAR)
  • project-ejb (EJB) => depends on project-common
  • project-web (WAR) => depends on project-common and project-ejb
  • project-rest (WAR) => depends on project-common and project-ejb

project-common has the TwelveMonkeys dependencies:

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

which are forwarded to the other components by transitivity. We only handled .jp(e)g and .png. We also use Thumbnailator along with TwelveMonkeys.

Troubleshooting

  1. Following the documentation and this SO question, I have added the listener in project-web:

    <listener>
        <display-name>ImageIO service provider loader/unloader</display-name>
        <listener-class>com.twelvemonkeys.servlet.image.IIOProviderContextListener</listener-class>
    </listener>
    

    Under Netbeans, the com/twelvemonkeys/imageio/util/ProgressListenerBase is present in project-ejb and project-web so I don't understand why the class is not found

  2. Regardless if the ImageIO.read(file) is called in project-ejb or project-web, the error is the same

  3. I tried adding ImageIO.scanForPlugins() before ImageIO.read(file), the error is the same

Workaround

Following

Another safe option, is to place the JAR files in the application server's shared or common lib folder.

I have manually put the dependencies

# 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

in {PAYARA_DIR}\glassfish\domains\{DOMAIN_NAME}\lib folder without removing the listener. I changed the dependencies scope to<scope>provided</scope> as it is not embedded in the application.

I put it as a workaround because I understand that adding the listener should have been enough so that manually adding the dependencies seems overkill. Moreover, even if we don't change our dependencies version that often, changing TwelveMonkeys dependencies means that theses dependencies need to be manually updated and replaced.

Question: is this workaround only solution or where did I messed up?

0

There are 0 best solutions below