Hi John, thank you for your answer. As I said before, I do understand the concept behind resolving lambda expressions at runtime to not represent "real classes". I do however still disagree with your assertion. On the opposite, I argue that the fact that nobody can expect a certain form of implementation for a lambda expression makes chaging this form a viable solution in the first place.
After the LambdaMetafactory is instrumented, I know that the returned class site that produces a lambda creates a "plain old Java class" and can be instrumented. I also know that I can redefine/retransform such classes without breaking anything. The only glitch in this substitution of the LambdaMetafactory is that I still need to use the Unsafe API and that such classes might no longer be retransformable after some VM update due to loading the class via Unsafe::defineAnonymousClass. Therefore, I suggest to make classes retransformable only if their constant pool is not patched, i.e. the third argument is set to null. This would suffice to allow for the described workarround that people already use. Finally, I want to stress that there is already a lot of code out there that uses instrumentation. Until Java 8, any class of a Java application could be transformed in a canonical manner. Having changed this behavior is a breaking change to a certain degree since people cannot longer update their applications without a change in behavior when lambda expressions are involved. And I do not argue that instrumenting lambdas is a good idea in the first place but existing code bases already implement a lot of bad ideas that people need to work with. Refactorings of existing code are always a consideration of cost and the harder instrumenting lambdas gets, the uglier the hacks will become and this is to nobody's benefit. This is why I hope that you can somehow support this functionality after all. Thank you for considering this! Best regards, Rafael 2016-01-27 0:38 GMT+01:00 John Rose <john.r.r...@oracle.com>: > VM anonymous classes are an implementation detail that is > opaque to system components except for the lowest layers of > the JDK runtime and the JVM itself. Transformers and other > instrumentation should not look inside them expecting to interpose > on their behavior. Ideally we should not make them visible at all, > but sometimes it helps (e.g., with single stepping through BCs). > > VM anonymous classes may be (and are) replaced or interchanged > unpredictably with similar mechanisms, such as JNI-based > reflection, or indirect invocation via MemberName tokens. > > You can't rely on any of this meaning what you think it means, > even if it appears to have a classfile structure. Even if you > were able to "transform" one of these classfiles, it wouldn't > necessary do what you think it should do, because its structure > is a private internal-only contract of the JDK and JVM. > > And, as you probably have already noticed, the number and > structure of these VMAC classfiles change over time. > We may (at some point) replace the classes with some > completely different internal representation, which, > even if it is visible somehow to instrumentation, cannot > meaningfully be parsed and re-implemented. > > Likewise, lambdas are translated into inner classes, but > this also can change at any time; the metafactory API > makes few or no promises as to the internal structure > of the invokedynamic binding. In fact, some JVMs use > special polymorphic nodes, instead of the standard > inner-class translation. Suddenly, some or all of these > classfiles may disappear, when the runtime begins to > optimize them differently. > > Please don't lead your users to rely on them. > > I second Vladimir's suggestion, that the only sane way > to interpose on lambdas is to transform the class that > defines the lambda (including perhaps the parameters > of the indy that create the lambda), and not dig into > system internals. System internals are nothing like > user code, and cannot be transformed like user code. > > Sorry to bear bad news, > > — John