Hacker Newsnew | past | comments | ask | show | jobs | submit | raphw's commentslogin

This is actually not a requirement anymore. Mockito 2 can mock final types and methods.


Byte Buddy does not generate source code, only byte code. Arguably, when creating such POJOs that are used within an application, most people would prefer source code.


Also, have a look at this presentation from JavaOne last year of you are interested in the gory details: https://www.parleys.com/talk/runtime-code-generation-jvm


Byte Buddy is quite efficient. It is more or less like implementing Java code per hand. Byte Buddy comes along with a benchmark where the results are listed here: http://bytebuddy.net/#/tutorial

This way, it even beats the use of MethodHandles for accessing fields which still have a slight overhead over "normal" field access: https://gist.github.com/raphw/881e1745996f9d314ab0

Of course, there might be a flaw in the benchmark, those are tricky. Si please challange it, I am always interested in such details. I also guess, that the advantage will decrease with future JVMs.


Afaik method handles need to be assigned to final fields (with -XX:+TrustFinalNonStaticFields) or final static fields for the JIT to be able to inline them.


You are right, it is stated here: https://wiki.openjdk.java.net/display/HotSpot/Deconstructing...

I will update and rerun the benchmark some time. Unfortunately, storing a value in a static final field allows the VM to pre-determine the entire method call and to erase the invocation altogether. This makes it hard to measure the impact of the method call. It is also questionable if this is the desired measurement as reflection is normally used to delay a call site determination to runtime which could not be done using a MethodHandle in a static final field.

But really good catch! I will hava a look at it some time soon.


The two biggest competitors to Byte Buddy today are javassist and cglib. Both of them work quite differently:

javassist takes strings containing Java code and compiles these strings at runtime. This makes it simple to use as every Java developer knows Java. Unfortunately, the javassist compiler lags a lot behind the actual javac compiler. For example, it does not support generics or even auto-boxing, not to speak of lambda expressions. Also, Strings are not type-safe what makes javassist code quite error prone. (It is the equivalent of concenating SQL strings together, with all the risks like foreign code injection.)

cglib allows you to register callbacks for an overridden class, similar to the JDK proxies. However, this requires that all class loaders know about cglib if they want to know these cglib-proxies as cglib-specific types are hard-coded into any generated class. Also, cglib only allows subclassing but not the rewrital of existing classes. Furthermore, the callbacks require any arguments to be boxed and registeres these boxed values into arrays. It turns out that cglib is not quite Just-In-Time-compiler friendly.

Byte Buddy works with annotations or its type-safe DSL and realizes its instrumentation mostly based on delegating to user code. This way, you can implement interceptors in any JVM language and you avoid dependencies on Byte Buddy within the generated classes (annotations are fortunately ignored by JVM class loaders if they cannot be resolved at load-time). This makes for example for better exception stack traces than when using "string code". Also, Byte Buddy avoids boxing by creating smarter objects for the interceptors and only creates those interceptors that are requested by annotated arguments, using dependency injection.

ASM or BCEL are rather byte code parser than code generation libraries. You need to have a clear concept of how byte code works in order to use them. Also, those libraries allow you to create "unverified code", i.e. you have to do a lot manually. Byte Buddy is itself built on top of ASM, you can even plug ASM code into Byte Buddy if you need to.


Another approach would be to translate the compiled output of javac into ASM method calls: https://github.com/int3/java2asm

It's fairly unpolished at the moment, though.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: