Will you look at that. BCEL's verifier actually checks for this (Pass3aVerifier.java):
public void visitLDC(final LDC ldc) { indexValid(ldc, ldc.getIndex()); final Constant c = constantPoolGen.getConstant(ldc.getIndex()); if (c instanceof ConstantClass) { addMessage("Operand of LDC or LDC_W is CONSTANT_Class '"+c+"' - this is only supported in JDK 1.5 and higher."); } else{ if (! ( c instanceof ConstantInteger || c instanceof ConstantFloat || c instanceof ConstantString ) ) { constraintViolated(ldc, "Operand of LDC or LDC_W must be one of CONSTANT_Integer, CONSTANT_Float or CONSTANT_String, but is '"+c+"'."); } } } It generates just a warning though, not an actual error. I quickly checked out LDC.java to see if I can submit a PR, but I think I don't know enough about BCEL to actually do it. I'll leave it to the experts. Greetings On Fri, 4 Feb 2022 at 15:37, Stefan Reich < stefan.reich.maker.of....@googlemail.com> wrote: > Update: They changed it in Java 5. ClassGen.setMajor(49) + > ClassGen.setMinor(0) works. > > On Fri, 4 Feb 2022 at 15:26, Stefan Reich < > stefan.reich.maker.of....@googlemail.com> wrote: > >> Mystery solved, ladies and gentlemen... >> >> It was... >> >> the byte code version. BCEL outputs version 45.3 by default (JDK 1.1). >> There were multiple changes to the class file format spec since then. >> >> Specifically, they must have allowed ldc to load .class objects directly >> at some point after JDK 1.1. In fact, I distinctly remember the >> Class.forName shenanigans that javac produced back then instead of the >> direct ldc. >> >> Apparently the Java verifier is so strict it judges the class file >> according to its version number and disallows the new version of ldc in a >> class file written for JDK 1.1. >> >> BCEL doesn't check for this though and outputs a broken class file. >> Changing this might be a good idea. >> >> Unfortunately I couldn't find documentation on when the byte code spec >> change happened. Does anyone know? >> >> Neither did I find anything in the HotSpot verifier sources >> <https://github.com/openjdk/jdk/blob/master/src/hotspot/share/classfile/verifier.cpp> >> which is odd to me. No mention of a JDK version there. Only in >> clasfileparser.cpp >> <https://github.com/openjdk/jdk/blob/master/src/hotspot/share/classfile/classFileParser.cpp> >> but didn't find the issue in question there either. I'm by no means an >> expert in the JDK C++ source though. >> >> Cheers >> Stefan >> >> On Thu, 3 Feb 2022 at 08:32, Romain Manni-Bucau <rmannibu...@gmail.com> >> wrote: >> >>> Hi, >>> >>> Maybe a bit ot of topic but did you check with asm (using classreader for >>> ex) if it is readable for it? Javap in verbose mode is hard to read >>> humanly >>> (and not verbosel does not mean much) so an issue can still be hidden. >>> >>> Romain Manni-Bucau >>> @rmannibucau <https://twitter.com/rmannibucau> | Blog >>> <https://rmannibucau.metawerx.net/> | Old Blog >>> <http://rmannibucau.wordpress.com> | Github < >>> https://github.com/rmannibucau> | >>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book >>> < >>> https://www.packtpub.com/application-development/java-ee-8-high-performance >>> > >>> >>> >>> Le jeu. 3 févr. 2022 à 01:42, Stefan Reich >>> <stefan.reich.maker.of....@googlemail.com.invalid> a écrit : >>> >>> > I'm mainly curious how it's possible that everything looks completely >>> > normal in javap (checked a dozen times), but the class verifier >>> complains >>> > anyway? Something has to be different. Is there a way to dig deeper >>> into a >>> > class file? >>> > >>> > Greetings >>> > >>> > On Wed, 2 Feb 2022 at 23:14, Stefan Reich < >>> > stefan.reich.maker.of....@googlemail.com> wrote: >>> > >>> > > Hmm, no change with latest version. >>> > > >>> > > I did "git clone https://github.com/apache/commons-bcel.git" and >>> "mvn >>> > > package". >>> > > >>> > > stefan@lenovo-ThinkPad-X220:~/dev/classreftest$ javac -cp >>> > > bcel-6.6.0-SNAPSHOT.jar MakeBadClassFile.java >>> > > stefan@lenovo-ThinkPad-X220:~/dev/classreftest$ java -cp >>> > > bcel-6.6.0-SNAPSHOT.jar:. MakeBadClassFile >>> > > Now please try: java BadClassFile >>> > > stefan@lenovo-ThinkPad-X220:~/dev/classreftest$ java BadClassFile >>> > > Error: Unable to initialize main class BadClassFile >>> > > Caused by: java.lang.VerifyError: (class: BadClassFile, method: main >>> > > signature: ([Ljava/lang/String;)V) Illegal type in constant pool >>> > > stefan@lenovo-ThinkPad-X220:~/dev/classreftest$ >>> > > >>> > > On Wed, 2 Feb 2022 at 22:59, Gary Gregory <garydgreg...@gmail.com> >>> > wrote: >>> > > >>> > >> You should try the latest from git master. >>> > >> >>> > >> Gary >>> > >> >>> > >> On Wed, Feb 2, 2022, 15:41 Stefan Reich >>> > >> <stefan.reich.maker.of....@googlemail.com.invalid> wrote: >>> > >> >>> > >> > Hi again, >>> > >> > >>> > >> > actual problem this time... >>> > >> > >>> > >> > I think I am doing everything right... Decompilation in javap -v >>> looks >>> > >> > just like it should. But I get a VerifyError... I'm using JDK 17. >>> Full >>> > >> > program attached. Please advice, thank you :) >>> > >> > >>> > >> > # javac -cp bcel-6.5.0.jar MakeBadClassFile.java >>> > >> > # java -cp bcel-6.5.0.jar:. MakeBadClassFile >>> > >> > # java BadClassFile >>> > >> > Error: Unable to initialize main class BadClassFile >>> > >> > Caused by: java.lang.VerifyError: (class: BadClassFile, method: >>> main >>> > >> > signature: ([Ljava/lang/String;)V) Illegal type in constant pool >>> > >> > >>> > >> > >>> > >> > >>> --------------------------------------------------------------------- >>> > >> > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org >>> > >> > For additional commands, e-mail: dev-h...@commons.apache.org >>> > >> >>> > > >>> > > >>> > >> >> >