'ClassCastException casting a class instance to its own class because it is in an "unnamed module" with gradel and tomcat

There are many similar issues, but none I could find have the class being cast to itself. We are using a dependency on the webp support from this project:

implementation "org.sejda.imageio:webp-imageio:0.1.6"

It works fine if we don't try to change the write params, but if we do like this:

Iterator imageWriters = ImageIO.getImageWritersByFormatName("webp");
ImageWriter writer = (ImageWriter) imageWriters.next();

WebPWriteParam writeParam = new WebPWriteParam(null);
writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
writeParam.setCompressionType(writeParam.getCompressionTypes([WebPWriteParam.LOSSY_COMPRESSION]);
writeParam.setCompressionQuality(0.75f);

baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
writer.setOutput(ios);
writer.write(null, new IIOImage(img, null, null), writeParam);

We get this strange exception

java.lang.ClassCastException: class com.luciad.imageio.webp.WebPWriteParam cannot be cast to class com.luciad.imageio.webp.WebPWriteParam (com.luciad.imageio.webp.WebPWriteParam is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @34282781; com.luciad.imageio.webp.WebPWriteParam is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @238ad8c) at com.luciad.imageio.webp.WebPWriter.write(WebPWriter.java:67) ~[webp-imageio-0.1.6.jar:?] at com.XXX.business.util.ImageServices$ImageSaver.run(ImageServices.java:874) [rcw-core.jar:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) [?:?] at java.lang.Thread.run(Thread.java:832) [?:?]

I understand class loaders very will, but don't understand how this module concept is not working here. Can you get me pointed in the right direction?



Solution 1:[1]

You have this class twice in the classpath. The error message tries to give you the two sources, but it's not very successful with that.

In general: an object of class A (from classloader/jar C1) is attempted to be typecast to an object of a class with the same name A, but loaded from classloader/jar C2.

Find C1 and C2 and eliminate one of them. Make the class available only once and the problem will go away

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Olaf Kock