iText / BouncyCastle throws "java.lang.VerifyError: class overrides final method equals"

m00hk00h picture m00hk00h · Jun 20, 2013 · Viewed 15.6k times · Source

We have an application that creates PDFs unsing jasperreports.
It also manipulates said PDFs using iText after they have been created.

We recently started using encryption on some PDF. That means before the app can handle the PDF after its creation, it has to be decrypted. While attempting to do so using iText's PdfReader(String path, byte[] password) I get the following exception:

java.lang.VerifyError: class org.bouncycastle.asn1.ASN1Primitive overrides final method equals.(Ljava/lang/Object;)Z
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(Unknown Source)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at com.simontuffs.onejar.JarClassLoader.defineClass(JarClassLoader.java:561)
    at com.simontuffs.onejar.JarClassLoader.findClass(JarClassLoader.java:475)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at com.itextpdf.text.pdf.PdfEncryption.<init>(PdfEncryption.java:148)
    at com.itextpdf.text.pdf.PdfReader.readDecryptedDocObj(PdfReader.java:914)
    at com.itextpdf.text.pdf.PdfReader.readDocObj(PdfReader.java:1294)
    at com.itextpdf.text.pdf.PdfReader.readPdf(PdfReader.java:643)
    at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:187)
    at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:212)
    at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:202)

The project is built as a runnable .jar using Maven and uses the following dependencies:
iText 5.4.2
bouncycastle 1.48

I should mention that jasperreports has its own dependency of iText and bouncycastle:
iText 2.1.7
bouncycastle 1.38

I can't figure out what's going on on and need help.

Answer

Marko Topolnik picture Marko Topolnik · Jun 20, 2013

My best guess is that you have ended up with two different versions of Bouncy Castle on your classpath, and it happened so that the classloader has loaded the superclass from one version and is now trying to load the subclass from the other. The versions are different in that one of them defines a final equals method.