byte-buddy icon indicating copy to clipboard operation
byte-buddy copied to clipboard

Use bytebuddy in a Javac Compiler plugin

Open Auties00 opened this issue 1 year ago • 8 comments

Hello, I'm trying to make ByteBuddy work within a Javac Compiler plugin(com.sun.source.util.Plugin). In short, I've managed to locate and read the compiled .class files, but I can't find a way to load them without a ClassLoader. Is it possible to load the raw bytecode directly? If it isn't, I could load the compiled .class into a custom URLClassLoader alongside the classpath, but then I might have an issue if, for example, class A and B depend on each other. Is there a way to prevent ByteBuddy from loading types within the ByteCode that are not loaded in the ClassLoader at that time? (I need to define new methods, that's why I'm not using ByteBuddy#decorate) Thanks in advance!

Auties00 avatar Jul 12 '23 20:07 Auties00

There's ByteArrayClassLoader. Wouldn't that work for you?

raphw avatar Jul 12 '23 20:07 raphw

There's ByteArrayClassLoader. Wouldn't that work for you?

I saw that class, but as far as I can tell, it needs an instance of TypeDescription which can only be obtained from a Class>. Maybe I'm missing something though. Also, if I load it this way, is there a way for me to ignore types that might not be known at that moment? Or maybe that happens directly when loading bytecode from a byte array instead of a Class> ?

Auties00 avatar Jul 12 '23 20:07 Auties00

There's a constructor that takes strings instead of type descriptions.

raphw avatar Jul 13 '23 10:07 raphw

There's a constructor that takes strings instead of type descriptions.

Do you mind sending a javadoc reference? I can't seem to find it

Auties00 avatar Jul 13 '23 14:07 Auties00

https://javadoc.io/doc/net.bytebuddy/byte-buddy/1.10.2/net/bytebuddy/dynamic/loading/ByteArrayClassLoader.html#ByteArrayClassLoader-java.lang.ClassLoader-boolean-java.util.Map-

raphw avatar Jul 15 '23 21:07 raphw

https://javadoc.io/doc/net.bytebuddy/byte-buddy/1.10.2/net/bytebuddy/dynamic/loading/ByteArrayClassLoader.html#ByteArrayClassLoader-java.lang.ClassLoader-boolean-java.util.Map-

Thanks, but this still involves loading a Class<?>. This means that all types referenced by that Class need to be known by the class loader. Take this example:

class First {
  static {
     Second.someMethod();
  }
  
  static void someMethod() {
     // Do something
  }
}
class Second {
  static {
     First.someMethod();
  }
  
  static void someMethod() {
     // Do something
  }
}

Either First or Second is going to be compiled first, so if I try to do my instrumentation without the other class a NoClassDefError will be thrown. Is there any way to simply ignore unknown types?

Auties00 avatar Jul 19 '23 13:07 Auties00

If there is a large number of NoClassDefError visually, it will cause a double free error of 1.8. I hope this can also be paid attention to. Thank you to the author JDK-8178870, you can veto some destruction schemes given in the code

1057105012 avatar Jul 22 '23 06:07 1057105012

It seems to be backported to 8.

raphw avatar Jul 23 '23 06:07 raphw