You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When injecting a field and a static initializer into a Java record class, Javassist generates invalid class files. I have seen this for several record classes and the error seems to vary. I have created a minimal example to reproduce this.
It works with normal classes and enums. I have provided both a normal class that pass enum classes share the property of being special classes in Java, but since the static initializer handling differs, I also added a normal class for reference.
File that is processed with Javassist
public record InvalidClassFile_Record(Object arg) {
public static void main(String[] args) {
InvalidClassFile_Record instance = new InvalidClassFile_Record(InvalidClassFile_Record.class.getName());
System.out.println(instance.arg());
}
}
Manipulating code
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get(className);
CtField f = new CtField(CtClass.booleanType, "f", cc);
int modifiers = Modifier.STATIC | Modifier.FINAL;
f.setModifiers(modifiers);
cc.addField(f);
String init = "{ " + className + ".f = true; }";
CtConstructor initializer = cc.getClassInitializer();
if (initializer == null) {
System.out.println("generating initializer");
initializer = cc.makeClassInitializer();
initializer.setBody(init);
} else {
System.out.println("modifying existing initializer");
initializer.insertBefore(init);
}
cc.writeFile();
ValidClassFile_Class demonstrates that the injection works for normal classes
ValidClassFile_Enum demonstrates that the injection works for enum classes
InvalidClassFile_Record demonstrates the error when using enum classes
Main contains the code that uses Javassist to manipulate the classes and write out the modified class files.
Make sure you have at least Java 17 and Maven installed (I did this on Java 21 but I think 17 should work)
extract the zip and change into the newly created folder
Run mvn compile to compile
Run mvn exec:java to write out the modified class files
Run java ValidClassFile_Class, java ValidClassFile_Enum, and java InvalidClassFile_Record. The first two output a line of text, the third one fails to run
Example output
% javassist_invalid_classfile % java ValidClassFile_Class
ValidClassFile_Class@1dbd16a6
% javassist_invalid_classfile % java ValidClassFile_Enum
A
% javassist_invalid_classfile % java InvalidClassFile_Record
Fehler: Beim Laden der Klasse InvalidClassFile_Record ist ein LinkageError aufgetreten
java.lang.ClassFormatError: Illegal field name "LInvalidClassFile_Record;" in class InvalidClassFile_Record
The text was updated successfully, but these errors were encountered:
Description of problem
When injecting a field and a static initializer into a Java record class, Javassist generates invalid class files. I have seen this for several record classes and the error seems to vary. I have created a minimal example to reproduce this.
It works with normal classes and enums. I have provided both a normal class that pass enum classes share the property of being special classes in Java, but since the static initializer handling differs, I also added a normal class for reference.
File that is processed with Javassist
Manipulating code
How to reprodcue
A minimal example is contained in the attached javassist_invalid_classfile.zip. It contains of four classes:
mvn compile
to compilemvn exec:java
to write out the modified class filesjava ValidClassFile_Class
,java ValidClassFile_Enum
, andjava InvalidClassFile_Record
. The first two output a line of text, the third one fails to runExample output
The text was updated successfully, but these errors were encountered: