Disable validation of identifiers in Byte Buddy

Viewed 215

I am working on a JVM-based programming language and I use Byte Buddy for the code generator. The language is somewhat similar to Java but typically uses annotations where Java would use keywords. Some example annotations are public, private, extends, override, singleton or inject.

Unlike the Java Language Specification, the Java Virtual Machine Specification imposes very few restrictions on class names, and names like extends or public are perfectly valid from JVM-perspective. However, when I try to generate annotation classes with a name that happens to be a Java keyword I get an IllegalStateException "Illegal type name" from Byte Buddy's InstrumentedType class.

How can I circumvent the validation that is specific to the Java language and use more lenient validation rules that follow the Java Virtual Machine Specification instead?

2 Answers

You can simply disable validation:

new ByteBuddy().with(TypeValidation.DISABLED);

After studying the Byte Buddy sources for a bit, I might have found a solution, but it's extremely hacky and hopefully someone knows a better way...

Luckily for me, the KEYWORDS field in net.bytebuddy.dynamic.scaffold.InstrumentedType.Default uses just a plain mutable HashSet instead of a Collections.unmodifiableSet, so with the following hack I was able to remove the validation of Java keywords:

val Field KEYWORDS = Default.getDeclaredField("KEYWORDS")
KEYWORDS.setAccessible(true)
val Set<String> keywords = KEYWORDS.get(null) as Set<String>
keywords.clear

(the code is written in Xtend syntax, but you get the idea)

That being said, I'm the first one to admit that using Java Reflection to poke around in final static fields of other libraries isn't exactly best practice. So, whereas my immediate blocker is removed I'm hoping that there is a more orthodox solution to this problem...

Related