HNHacker News
TopNewBestAskShowJobs

raphw

77 karma · joined March 4, 2015

software consultant in Oslo
submissionscomments
raphw··on I analyzed 17.3M Maven artifacts to map the Java module ecosystem
A large scale analysis of Java module adoption, module naming, dependency history, ownership collisions, automatic modules, and publication trends across Maven Central.
raphw··on Jenesis – A modern Java build tool
A modern Java build tool: Java-native config, plugin-free, with module-info.java treated as a feature, not an afterthought.
raphw··on Mockito 2.1.0
This is actually not a requirement anymore. Mockito 2 can mock final types and methods.
raphw··on Byte Buddy – runtime code generation for the JVM
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.
raphw··on Byte Buddy – runtime code generation for the JVM
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.

raphw··on Byte Buddy – runtime code generation for the JVM
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
raphw··on Byte Buddy – runtime code generation for the 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.

raphw··on Byte Buddy – runtime code generation for the JVM
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.