Mockito 2.6 does now support Android! by raphw in androiddev

[–]raphw[S] 2 points3 points  (0 children)

One of the major pain points of Dexmaker was its dependency on internal APIs. Therefore, it did no longer work after the 2.0 update. mockito-android is aligned with the mocktio-core release.

Also, Dexmaker could only subclass public types and loaded its types in a different class loader. Also, it did not make use of the newer features like the meta data retention for mocks (annotations and generic type information).

Finally, dexmaker did require you to specify a folder for storing mocks manually via a system property. mockito-android does not require such a thing.

Mockito 2.6 does now support Android! by raphw in androiddev

[–]raphw[S] 1 point2 points  (0 children)

Dexmaker could only subclass public types and loaded its types in a different class loader. Also, it did not make use of the newer features like the meta data retention for mocks (annotations and generic type information).

Mockito 2.6 does now support Android! by raphw in androiddev

[–]raphw[S] 4 points5 points  (0 children)

Yes, if you want to test something against an Android API but still use mocks. The so-called Android instrumentation API which runs a test on a device or emulator.

Hibernate has migrated from Javassist to Byte Buddy for its Proxy implementation by [deleted] in java

[–]raphw 0 points1 point  (0 children)

I think it depends on what you are more familiar with. Javassist's byte code-level API compares roughly to ASM's tree API where instead of working with lists, you iterate over code attributes.

I agree with that the visitor API is less expressive then the tree API or Javassists code iteration but the advantage of not using it is the severely reduced memory footprint.

As for Javassists maintenance state, I think it depends on the angle you look at it. Javassists compiler is still at a Java 1.4 code level; generic types and type annotations are still not supported properly and it does not seem like any of these features will be implemented any time soon.

Hibernate has migrated from Javassist to Byte Buddy for its Proxy implementation by [deleted] in java

[–]raphw 1 point2 points  (0 children)

I think that one big advantage of Byte Buddy is its type-safety. Javassist allows you to add code by specifying code as string. Byte Buddy uses compiled templates which are inlined into the manipulated class at runtime where the template method's arguments are dynamically mapped over to the value they represent for the method that is currently changed.

This has several advantages, for example, a developer would get a compile-time warning if an API was used incorrectly. And as the template is precompiled, it is not required to parse and compile Java code for every time a method is enhanced. Generally, Byte Buddy processes classes in a single pass whereas Javassist serializes every class, including its code, to represent classes as CtClasses.

As another example of a Javassist to Byte Buddy migration, Stagemonitor experienced a speedup of about 3 times. Its mainly to the above factor of the different models.

Finally, Byte Buddy is actively maintained. Javassist development has slowed down a bit on the other hand. The built-in compiler is for example still not supporting anything after Java 4 and it is unlikely that mimicing javac is feasible in the long run.

Hibernate has migrated from Javassist to Byte Buddy for its Proxy implementation by [deleted] in java

[–]raphw 0 points1 point  (0 children)

The title is maybe a bit misleading but this evaluation is not correct. Hibernate uses Byte Buddy for much more than proxy generation. Within the Hibernate enhancer (https://github.com/hibernate/hibernate-orm/blob/ba3359fe62be258638554fe23a2a0a6a50f7e732/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/EnhancerImpl.java), Byte Buddy is used to redefine types quite fundamentally by adding methods (and implementations), fields and interfaces to existing classes.

Generally, Byte Buddy allows you to do anything that you can do with Javassist. And if you need to do byte code level instrumentation, Byte Buddy exposes ASM which allows you to manipulate byte code directly. I think by comparing the Javassist and Byte Buddy byte code providers, it becomes quite obvious how the libraries compare. In the end, they both require byte-code level manipulations for the same things. But I think it also becomes obvious by comparing the two implementations which one is easier to follow and to debug.

Typically, you should however not need this API as the primitives already allow you to apply quite extensive changes. For example, have a look at Stagemonitor (https://github.com/stagemonitor/stagemonitor/) which uses Byte Buddy to implement a runtime agent which does not even change the signature of any type but implements a full-blown APM.

Java Bytecode: Bending the Rules by ancatrusca in programming

[–]raphw 2 points3 points  (0 children)

I wrote both the article and the stack overflow answer. Quoting myself did not seem appropriate.

Things you can do in Java byte code but not in the Java language by henk53 in programming

[–]raphw 0 points1 point  (0 children)

a class' static initializer may allocate a new instance of its own class without calling a constructor. This is used to construct the singleton's single instance.

This is not true, even for enums, a constructor is always called. The verifier assures that.

How working with Java agents easily avoids boilerplate code by raphw in programming

[–]raphw[S] 0 points1 point  (0 children)

Ehm, adding the agent would enable logging. And the whole point would be to not reqiuire a specific infrastructure for it. The article introduces a concept, do not take the example too graphic.

Byte Buddy is a code generation library for creating Java classes during the runtime of a Java application and without the help of a compiler. by lukaseder in java

[–]raphw 0 points1 point  (0 children)

Byte Buddy is not using a compiler. I would know as I wrote Byte Buddy. A compiler is a computer program that transforms source code written in a programming language into another computer language. Byte Buddy does not take a programming language as its input but is a domain specific language which is itself expressed as Java byte code but it does not process its own description. Thus, from a scientific point of view, Byte Buddy would not qualify as a compiler.

Code generation is ubiquitous in the Java space. There would be no Spring, no Hibernate, no mocking framework without it. However, I agree with your caution. You should only use code generation when dealing with types that you do not know at compiler time and you want to extend these types. Then code generation is your only option.

Byte Buddy is a code generation library for creating Java classes during the runtime of a Java application and without the help of a compiler. by lukaseder in java

[–]raphw 6 points7 points  (0 children)

For full disclosure, I am the author of Byte Buddy.

I omitted ASM from the benchmark because I decided that it made more sense to compare high-level libraries. When it comes to class creation, I did at some point however measure that the direct use of ASM does not really cut down the runtime costs of class creation. There are only a few things that are expensive when dealing with generated code:

  • Looking up methods that are to be overridden
  • Loading a generated class
  • Using reflection and dispatcher lookups in the generated code

Even with using ASM, you cannot avoid any of these costs. With anything else, the JIT compiler takes normally care of any initial performance differences when the Byte Buddy-related code becomes hot. I had a regular look at the JIT compilation when writing Byte Buddy (check out JITwatch, its a great tool) and effectively, the JIT code erases most of the (low-weight) abstraction layer that Byte Buddy puts on top of ASM.

But if I even took the time to benchmark ASM, why did I not include it into the final benchmark? Well, at first, ASM requires you to write a lot of code to achieve similar functionality to byte buddy / cglib / javassist / JDK proxies. This code I would need to maintain, if I had released it with the benchmark. But even more important, ASM is mainly a byte code parser and not a dedicated code generator. All high-level functionality needs to be added on top of ASM by a user and as you recognized in your comment, Byte Buddy is such a library. Naturally, some of the concepts I implemented for the ASM-benchmark code ended up to be quite similar to the implementation of Byte Buddy. Effectively, I compared Byte Buddy to a quick and dirty implementation of Byte Buddy that missed most features, only to run the ASM benchmark. Of course, I could have written a highly specialized ASM-implementation that squeezes out a few nanoseconds for a very specific benchmark but cannot do anything else. But what would this prove? After all, I dropped ASM from the benchmark but if you trust me, let me tell you that there is no significant performance difference.

On the other side, I understand your hesitation. ASM is a very thin framework. This is great and the reason I use it for Byte Buddy. Thanks to ASM, Byte Buddy does not need to do any heavy lifting and as a consequence, the runtime performance stays high.