Re: ClassFileTransformer does not apply to anonymous classes

2016-01-27 Thread Rafael Winterhalter
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 :
> 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


Re: ClassFileTransformer does not apply to anonymous classes

2016-01-26 Thread John Rose
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

Re: ClassFileTransformer does not apply to anonymous classes

2016-01-26 Thread Rafael Winterhalter
aller. After that you are free to decide how to wrap the
> method handle to the lambda body.
>
> 2. At the same time, there is no standardized way to receive all
>> ClassFileTransformers that are currently registered on the VM. this
>> also requires calls into internal APIs that are not necessarily
>> supported on other platforms.
>>
>> I fully understand the hesitation to support this from a technical
>> point of view but in reality, people are already dependant on this
>> feature and disallowing the instrumentation of lambda classes will
>> only inspire work-arrounds that reduce the stability of software using
>> this APIs that does currently work without problems for non-lambda
>> classes.
>>
> As your experience demonstrates, instrumentation support of VM anonymous
> classes is far from production quality. If anybody heavily relies on it,
> then they should face the same problems. But you are the first who stumbled
> upon and reported them. So, it seems we are lucky and can decide what is
> the correct behavior (and not just stick with how it works now).
>
> Best regards, Rafael
>>
>> PS: While implementing my solution, I found that the LambdaMetafactory
>> of the Open JDK creates private, final methods for the serialization
>> bits. The methods should however not be final as they are already
>> private.
>>
> There's no such thing as too much safety, right? ;-)
>
> Best regards,
> Vladimir Ivanov
>
> [1] public class LambdaMetafactory {
>
> public static CallSite metafactory(
>   MethodHandles.Lookup caller,
>   String invokedName,
>   MethodType invokedType,
>   MethodType samMethodType,
>   MethodHandle implMethod,
>   MethodType instantiatedMethodType)
>
>
>>
>> 2016-01-23 13:55 GMT+01:00 Remi Forax :
>>
>>> I agree with Vladimir,
>>>
>>> You should not be able to transform/redefine a VM anonymous class
>>> because the transformer will certainly mess up with the order of the
>>> constant pool entries.
>>>
>>> Slightly off-topic, about ASM, when you create a ClassWriter [1], you
>>> can pass a ClassReader of an existing class, in that case ASM copy the
>>> constant pool from the class reader to the class writer so the constant
>>> pool is preserved.
>>>
>>> Rémi
>>>
>>> [1]
>>> http://asm.ow2.org/asm50/javadoc/user/org/objectweb/asm/ClassWriter.html#ClassWriter%28org.objectweb.asm.ClassReader,%20int%29
>>>
>>> - Mail original -
>>>
>>>> De: "Vladimir Ivanov" 
>>>> À: "Rafael Winterhalter" 
>>>> Cc: "Coleen Phillimore" ,
>>>> core-libs-dev@openjdk.java.net, "serguei.spit...@oracle.com
>>>> Spitsyn" , "Daniel Daugherty" <
>>>> daniel.daughe...@oracle.com>
>>>> Envoyé: Vendredi 22 Janvier 2016 18:47:31
>>>> Objet: Re: ClassFileTransformer does not apply to anonymous classes
>>>>
>>>> Rafael,
>>>>
>>>> First of all, I'd like to agree on the terminology. There's some
>>>> confusion there. Anonymous term is ambiguous in Java. There are
>>>> anonymous classes on language level and there's
>>>> Unsafe.defineAnonymousClass() which produce anonymous-in-VM-sense
>>>> classes. I prefer to call them VM anonymous classes to avoid confusion.
>>>>
>>>> I assume that whenever you use anonymous you assume "VM anonymous".
>>>>
>>>> thank you for your response. While I completely understand your view
>>>>> from a VM implementor's point of view, as a practicioner I would
>>>>> recommend against it. Not being able to instrument lambda expressions
>>>>> puts a severe limitation onto using the instrumentation API
>>>>> alltogether. For example, a monitoring application that promises to
>>>>> record all invocations of a method of a certain interface that only
>>>>> works 95% of the time is not 5% less usefull but might no longer be
>>>>> useful at all. People have build large applications based on the
>>>>> assumption that all user application code can be instrumented and such
>>>>> a regression would hurt them. For example, until today, over 30 people
>>>>> that use my code generation framework reached out to me and reported
>>>>> the reported behavior as a bug in my library and people are only
>>>>> starting to migrate their applications to Java 8. The outcome 

Re: ClassFileTransformer does not apply to anonymous classes

2016-01-26 Thread Rafael Winterhalter
Hi Remi,

this is what I am doing. At least using Byte Buddy, you turn a switch
such that Byte Buddy redefines the LambdaMetafactory to spin custom
classes where Byte Buddy also applies a ClassFileTransformer.
Currently this results in the (almost) exact class file as if the
default LambdaMetafactory had applied this transformation. Therefore,
I do not understand why it would be more harmful as a solution if this
was standard behavior.

As mentioned, one problem that I see with my solution is that I have
to code against the Unsafe API what I would like to avoid. The class
is surely being removed at some point and then I would already need to
implement a version sensitive instrumentation what, in the long run,
might result in unstable behavior. At the same time, I could not fall
back to public API class loading as it is impossible to regularly load
a class that invokes the private method containing the lambda
expression's method body.

Also, spinning your own LambdaMetafactory is quite an effort if other
people would want to do it without the help of Byte Buddy. Especially
exception handling is difficult to get right (and to test) and
supporting lambda serialization is another bigger task to get done
correctly. In my view, it would therefore be desireable if the JVM
could natively handle instrumentation (as I would also expect it from
the contract of the Instrumentation API that does not even mention
this).

Best regards, Rafael



2016-01-26 13:03 GMT+01:00  :
> Hi Rafael,
> why not providing a LambdaInterceptor as asked ?
>
> My point is that a lambda should be considered as a feature by itself instead 
> as a way to create a class that implement an interface at runtime.
> If you do that, your code will still work when future release (maybe a point 
> release), the implementation of the lambda proxy class will change.
>
> BTW, i maybe wrong, but as far as remember, the first release of Java 8 was 
> not using vm anonymous classes for lambdas.
>
> regards,
> Rémi
>
> - Mail original -
>> De: "Rafael Winterhalter" 
>> À: "Rémi Forax" 
>> Cc: "Vladimir Ivanov" , "Coleen Phillimore" 
>> ,
>> core-libs-dev@openjdk.java.net, "serguei.spit...@oracle.com Spitsyn" 
>> , "Daniel
>> Daugherty" 
>> Envoyé: Mardi 26 Janvier 2016 10:30:54
>> Objet: Re: ClassFileTransformer does not apply to anonymous classes
>>
>> Maybe this is a more graphic example of a problem that end-users
>> currently face:
>> http://stackoverflow.com/questions/33912026/intercepting-calls-to-java-8-lambda-expressions-using-byte-buddy
>>
>> 2016-01-26 10:02 GMT+01:00  :
>> > Hello,
>> >
>> > - Mail original -
>> >> De: "Rafael Winterhalter" 
>> >> À: "Remi Forax" 
>> >> Cc: "Vladimir Ivanov" , "Coleen Phillimore"
>> >> ,
>> >> core-libs-dev@openjdk.java.net, "serguei.spit...@oracle.com Spitsyn"
>> >> , "Daniel
>> >> Daugherty" 
>> >> Envoyé: Lundi 25 Janvier 2016 20:24:01
>> >> Objet: Re: ClassFileTransformer does not apply to anonymous classes
>> >>
>> >> Hi Vladmir, hello Remi,
>> >>
>> >> what bothers me about instrumenting a lambda expression's target
>> >> method is the difficulty of locating the method that contains the code
>> >> and setting it into context. This is a lot of work to do since one
>> >> needs to first locate any invokedynamic call sites and interpret the
>> >> connection via the LambdaMetafactory. This is difficult to instrument
>> >> without greater efforts and does not feel like a clean solution.
>> >>
>> >> Many real life instrumentations are based on the assumption of being
>> >> able to instrument any class of a given subtype or other any other
>> >> class property. For example, one would want to instrument any class
>> >> that implements InputStream to discover a resource leak. If the
>> >> interface is however functional and implemented as a lambda
>> >> expression, a tool that manipulating all class files of this type
>> >> stops working. At the same time, end users do not really understand
>> >> the difference of their former anonymous class that is now expressed a
>> >> lambda expression and perceive the beaviour as a regression.
>> >
>> > The lambda body is analyzed because the body is translated to a static
>> > method (which can be non static BTW) which is part of the class that uses
>> > the lambda.
>> > The lambda proxy is a run

Re: ClassFileTransformer does not apply to anonymous classes

2016-01-26 Thread Vladimir Ivanov
avadoc/user/org/objectweb/asm/ClassWriter.html#ClassWriter%28org.objectweb.asm.ClassReader,%20int%29

- Mail original -

De: "Vladimir Ivanov" 
À: "Rafael Winterhalter" 
Cc: "Coleen Phillimore" , 
core-libs-dev@openjdk.java.net, "serguei.spit...@oracle.com
Spitsyn" , "Daniel Daugherty" 

Envoyé: Vendredi 22 Janvier 2016 18:47:31
Objet: Re: ClassFileTransformer does not apply to anonymous classes

Rafael,

First of all, I'd like to agree on the terminology. There's some
confusion there. Anonymous term is ambiguous in Java. There are
anonymous classes on language level and there's
Unsafe.defineAnonymousClass() which produce anonymous-in-VM-sense
classes. I prefer to call them VM anonymous classes to avoid confusion.

I assume that whenever you use anonymous you assume "VM anonymous".


thank you for your response. While I completely understand your view
from a VM implementor's point of view, as a practicioner I would
recommend against it. Not being able to instrument lambda expressions
puts a severe limitation onto using the instrumentation API
alltogether. For example, a monitoring application that promises to
record all invocations of a method of a certain interface that only
works 95% of the time is not 5% less usefull but might no longer be
useful at all. People have build large applications based on the
assumption that all user application code can be instrumented and such
a regression would hurt them. For example, until today, over 30 people
that use my code generation framework reached out to me and reported
the reported behavior as a bug in my library and people are only
starting to migrate their applications to Java 8. The outcome is
simply not intuitive as using a lambda expression over an anonyous
inner class should not change an application's behavior.

Can you elaborate on that point, please?

I don't see any problems with instrumenting user code. Javac represents
lambda expression body as a private static method of the enclosing
class, which can be instrumented. VM anonymous classes are used only as
a mechanism to glue functional interfaces and lambda expressions
together at runtime.

For example:
 static void f(Runnable r) { r.run(); }
 f(() -> {});

Test::f (7 bytes)
@ 1   Test$$Lambda$1/791452441::run (4 bytes)   inline (hot)
  @ 0   Test::lambda$main$0 (1 bytes)   inline (hot)

Why do you need to instrument Test$$Lambda$1/... and not
Test::lambda$main$0?


The currently used workaround that people use is to instrument the
LambdaMetaFactory class itself to apply the transformer manually when
it is being created. This solution is spreading as a standard approach
and I am sure that forbidding a redefinition alltogether would only
inspire to other workarrounds for being able to migrate running code
to the next Java version.

It doesn't sound like a workaround, but as a solution for a different
problem.

If there's a need to gather profile for every lambda expression
instantiation site (indy call), then redefining bootstrap method is the
right way to go IMO. It allows to intercept and customize indy call site
binding.

What does sound as a workaround is an attempt to instrument classes
produced by LambdaMetaFactory. Right now, it generates a fresh VM
anonymous class on every request, but it is an implementation detail and
not a requirement.

For example, LambdaMetaFactory can reuse wrappers on per-functional
interface basis. It would provide significant footprint savings for
lambda expression-rich code bases (usually, there are much more
instantiations than functional interface flavors).


Furthermore, I do not think that not being able to patch constant pool
indices in the generated code introduces any problems in practice.
Most real-world instrumentation only appends new constant pool entries
without interfering with the existant pool. Rather, I would like to
see an exception being raised if one attempts to change the original
constant pool without me being able to consider this from a technical
perspective. I think this would serve to be sufficient for most
people.

If you care only about lambda expressions, then constant pool patching
shouldn't be a problem (AFAIR it isn't used for lambda expressions). But
in a more generic case (even for java.lang.invoke purposes), the
coupling between class file and CP patches is very tight and can be
easily broken with benign class file transformations. Considering ASM
library, I'm not sure that even simple instrumentations preserve
original constant pool structure.

Probably, VM can do some structural checks on CP to forbid any
modifications except appends, but there are still aliasing problems -
sharing doesn't work (even for string constants), so new code shouldn't
use original CP entries.

I'd prefer to avoid such increase in complexity in VM implementation.


I really hope that there is a way to allo

Re: ClassFileTransformer does not apply to anonymous classes

2016-01-26 Thread forax
Hi Rafael,
why not providing a LambdaInterceptor as asked ?

My point is that a lambda should be considered as a feature by itself instead 
as a way to create a class that implement an interface at runtime.  
If you do that, your code will still work when future release (maybe a point 
release), the implementation of the lambda proxy class will change.  

BTW, i maybe wrong, but as far as remember, the first release of Java 8 was not 
using vm anonymous classes for lambdas.

regards,
Rémi

- Mail original -
> De: "Rafael Winterhalter" 
> À: "Rémi Forax" 
> Cc: "Vladimir Ivanov" , "Coleen Phillimore" 
> ,
> core-libs-dev@openjdk.java.net, "serguei.spit...@oracle.com Spitsyn" 
> , "Daniel
> Daugherty" 
> Envoyé: Mardi 26 Janvier 2016 10:30:54
> Objet: Re: ClassFileTransformer does not apply to anonymous classes
> 
> Maybe this is a more graphic example of a problem that end-users
> currently face:
> http://stackoverflow.com/questions/33912026/intercepting-calls-to-java-8-lambda-expressions-using-byte-buddy
> 
> 2016-01-26 10:02 GMT+01:00  :
> > Hello,
> >
> > - Mail original -
> >> De: "Rafael Winterhalter" 
> >> À: "Remi Forax" 
> >> Cc: "Vladimir Ivanov" , "Coleen Phillimore"
> >> ,
> >> core-libs-dev@openjdk.java.net, "serguei.spit...@oracle.com Spitsyn"
> >> , "Daniel
> >> Daugherty" 
> >> Envoyé: Lundi 25 Janvier 2016 20:24:01
> >> Objet: Re: ClassFileTransformer does not apply to anonymous classes
> >>
> >> Hi Vladmir, hello Remi,
> >>
> >> what bothers me about instrumenting a lambda expression's target
> >> method is the difficulty of locating the method that contains the code
> >> and setting it into context. This is a lot of work to do since one
> >> needs to first locate any invokedynamic call sites and interpret the
> >> connection via the LambdaMetafactory. This is difficult to instrument
> >> without greater efforts and does not feel like a clean solution.
> >>
> >> Many real life instrumentations are based on the assumption of being
> >> able to instrument any class of a given subtype or other any other
> >> class property. For example, one would want to instrument any class
> >> that implements InputStream to discover a resource leak. If the
> >> interface is however functional and implemented as a lambda
> >> expression, a tool that manipulating all class files of this type
> >> stops working. At the same time, end users do not really understand
> >> the difference of their former anonymous class that is now expressed a
> >> lambda expression and perceive the beaviour as a regression.
> >
> > The lambda body is analyzed because the body is translated to a static
> > method (which can be non static BTW) which is part of the class that uses
> > the lambda.
> > The lambda proxy is a runtime artifact and the way it is currently
> > implemented will likely to change in the future, using a vm anonymous
> > class is a workaround of the fact that there is currently no way to load a
> > function/method without a class. You should not try to analyze the lambda
> > proxy, it doesn't contain codes but it's a straw glue between the
> > interface and the body of the lambda.
> >
> >>
> >> I have myself implemented a custom solution for my code generation
> >> library that instruments the LambdaMetafactory to apply class file
> >> transformers to these classes manually. This does however show two
> >> disadvantages:
> >>
> >> 1. javac creates the target method of a lambda expression as a private
> >> method. The only way to implement a lambda expression legally in byte
> >> code is by loading the generated implementation anonymously what
> >> requires non-public API. While it is possible to call
> >> Unsafe::defineAnonymousClass from the instrumented LambdaMetafactory,
> >> it is again required to use non-standardized APIs which might fail on
> >> differing implementations of the JVM.
> >
> > The invokedynamic corresponding to a lambda creation contains a link to the
> > private method, it's i believe all you need, but i'm not sure because what
> > you're doing exactly is fuzy for me.
> >
> >>
> >> 2. At the same time, there is no standardized way to receive all
> >> ClassFileTransformers that are currently registered on the VM. this
> >> also requires calls into internal APIs that are not 

Re: ClassFileTransformer does not apply to anonymous classes

2016-01-26 Thread Rafael Winterhalter
Maybe this is a more graphic example of a problem that end-users
currently face:
http://stackoverflow.com/questions/33912026/intercepting-calls-to-java-8-lambda-expressions-using-byte-buddy

2016-01-26 10:02 GMT+01:00  :
> Hello,
>
> - Mail original -
>> De: "Rafael Winterhalter" 
>> À: "Remi Forax" 
>> Cc: "Vladimir Ivanov" , "Coleen Phillimore" 
>> ,
>> core-libs-dev@openjdk.java.net, "serguei.spit...@oracle.com Spitsyn" 
>> , "Daniel
>> Daugherty" 
>> Envoyé: Lundi 25 Janvier 2016 20:24:01
>> Objet: Re: ClassFileTransformer does not apply to anonymous classes
>>
>> Hi Vladmir, hello Remi,
>>
>> what bothers me about instrumenting a lambda expression's target
>> method is the difficulty of locating the method that contains the code
>> and setting it into context. This is a lot of work to do since one
>> needs to first locate any invokedynamic call sites and interpret the
>> connection via the LambdaMetafactory. This is difficult to instrument
>> without greater efforts and does not feel like a clean solution.
>>
>> Many real life instrumentations are based on the assumption of being
>> able to instrument any class of a given subtype or other any other
>> class property. For example, one would want to instrument any class
>> that implements InputStream to discover a resource leak. If the
>> interface is however functional and implemented as a lambda
>> expression, a tool that manipulating all class files of this type
>> stops working. At the same time, end users do not really understand
>> the difference of their former anonymous class that is now expressed a
>> lambda expression and perceive the beaviour as a regression.
>
> The lambda body is analyzed because the body is translated to a static method 
> (which can be non static BTW) which is part of the class that uses the lambda.
> The lambda proxy is a runtime artifact and the way it is currently 
> implemented will likely to change in the future, using a vm anonymous class 
> is a workaround of the fact that there is currently no way to load a 
> function/method without a class. You should not try to analyze the lambda 
> proxy, it doesn't contain codes but it's a straw glue between the interface 
> and the body of the lambda.
>
>>
>> I have myself implemented a custom solution for my code generation
>> library that instruments the LambdaMetafactory to apply class file
>> transformers to these classes manually. This does however show two
>> disadvantages:
>>
>> 1. javac creates the target method of a lambda expression as a private
>> method. The only way to implement a lambda expression legally in byte
>> code is by loading the generated implementation anonymously what
>> requires non-public API. While it is possible to call
>> Unsafe::defineAnonymousClass from the instrumented LambdaMetafactory,
>> it is again required to use non-standardized APIs which might fail on
>> differing implementations of the JVM.
>
> The invokedynamic corresponding to a lambda creation contains a link to the 
> private method, it's i believe all you need, but i'm not sure because what 
> you're doing exactly is fuzy for me.
>
>>
>> 2. At the same time, there is no standardized way to receive all
>> ClassFileTransformers that are currently registered on the VM. this
>> also requires calls into internal APIs that are not necessarily
>> supported on other platforms.
>>
>> I fully understand the hesitation to support this from a technical
>> point of view but in reality, people are already dependant on this
>> feature and disallowing the instrumentation of lambda classes will
>> only inspire work-arrounds that reduce the stability of software using
>> this APIs that does currently work without problems for non-lambda
>> classes.
>
> again, there is no such thing as a lambda class, trying to see a lambda as an 
> anonymous class will never fully work.
> a lambda is a lambda, you have the link between the functional interface and 
> the lambda body encoded into the invokedynamic which is used to create the 
> lambda, you should not try to get more information, because as i said, it may 
> change.
>
>>
>> Best regards, Rafael
>>
>> PS: While implementing my solution, I found that the LambdaMetafactory
>> of the Open JDK creates private, final methods for the serialization
>> bits. The methods should however not be final as they are already
>> private.
>
> yes, private is enough but it's not a big deal.
>
>>
>
> regards,
&g

Re: ClassFileTransformer does not apply to anonymous classes

2016-01-26 Thread forax
Hello,

- Mail original -
> De: "Rafael Winterhalter" 
> À: "Remi Forax" 
> Cc: "Vladimir Ivanov" , "Coleen Phillimore" 
> ,
> core-libs-dev@openjdk.java.net, "serguei.spit...@oracle.com Spitsyn" 
> , "Daniel
> Daugherty" 
> Envoyé: Lundi 25 Janvier 2016 20:24:01
> Objet: Re: ClassFileTransformer does not apply to anonymous classes
> 
> Hi Vladmir, hello Remi,
> 
> what bothers me about instrumenting a lambda expression's target
> method is the difficulty of locating the method that contains the code
> and setting it into context. This is a lot of work to do since one
> needs to first locate any invokedynamic call sites and interpret the
> connection via the LambdaMetafactory. This is difficult to instrument
> without greater efforts and does not feel like a clean solution.
> 
> Many real life instrumentations are based on the assumption of being
> able to instrument any class of a given subtype or other any other
> class property. For example, one would want to instrument any class
> that implements InputStream to discover a resource leak. If the
> interface is however functional and implemented as a lambda
> expression, a tool that manipulating all class files of this type
> stops working. At the same time, end users do not really understand
> the difference of their former anonymous class that is now expressed a
> lambda expression and perceive the beaviour as a regression.

The lambda body is analyzed because the body is translated to a static method 
(which can be non static BTW) which is part of the class that uses the lambda.
The lambda proxy is a runtime artifact and the way it is currently implemented 
will likely to change in the future, using a vm anonymous class is a workaround 
of the fact that there is currently no way to load a function/method without a 
class. You should not try to analyze the lambda proxy, it doesn't contain codes 
but it's a straw glue between the interface and the body of the lambda.

> 
> I have myself implemented a custom solution for my code generation
> library that instruments the LambdaMetafactory to apply class file
> transformers to these classes manually. This does however show two
> disadvantages:
> 
> 1. javac creates the target method of a lambda expression as a private
> method. The only way to implement a lambda expression legally in byte
> code is by loading the generated implementation anonymously what
> requires non-public API. While it is possible to call
> Unsafe::defineAnonymousClass from the instrumented LambdaMetafactory,
> it is again required to use non-standardized APIs which might fail on
> differing implementations of the JVM.

The invokedynamic corresponding to a lambda creation contains a link to the 
private method, it's i believe all you need, but i'm not sure because what 
you're doing exactly is fuzy for me. 

> 
> 2. At the same time, there is no standardized way to receive all
> ClassFileTransformers that are currently registered on the VM. this
> also requires calls into internal APIs that are not necessarily
> supported on other platforms.
> 
> I fully understand the hesitation to support this from a technical
> point of view but in reality, people are already dependant on this
> feature and disallowing the instrumentation of lambda classes will
> only inspire work-arrounds that reduce the stability of software using
> this APIs that does currently work without problems for non-lambda
> classes.

again, there is no such thing as a lambda class, trying to see a lambda as an 
anonymous class will never fully work.
a lambda is a lambda, you have the link between the functional interface and 
the lambda body encoded into the invokedynamic which is used to create the 
lambda, you should not try to get more information, because as i said, it may 
change.

> 
> Best regards, Rafael
> 
> PS: While implementing my solution, I found that the LambdaMetafactory
> of the Open JDK creates private, final methods for the serialization
> bits. The methods should however not be final as they are already
> private.

yes, private is enough but it's not a big deal.

> 

regards,
Rémi

> 
> 2016-01-23 13:55 GMT+01:00 Remi Forax :
> > I agree with Vladimir,
> >
> > You should not be able to transform/redefine a VM anonymous class because
> > the transformer will certainly mess up with the order of the constant pool
> > entries.
> >
> > Slightly off-topic, about ASM, when you create a ClassWriter [1], you can
> > pass a ClassReader of an existing class, in that case ASM copy the
> > constant pool from the class reader to the class writer so the constant
> > pool is preserved.
> >
> > Rémi
> >

Re: ClassFileTransformer does not apply to anonymous classes

2016-01-26 Thread Andrew Dinn
On 26/01/16 08:39, Rafael Winterhalter wrote:
> Another note on this subject: I found that applying a
> reretransformation on a lambda expression's class does not provide the
> original class file to the retransformer but the class file that
> resulted from a previous retransformation. (If a lambda class is
> retransformed several times.) This is different to "normal" classes
> where the original class file is provided.

I think it is also /clearly wrong/ since it makes it at very least
difficult and perhaps, depending on circumstances, impossible for a
transformer to restore the original bytecode.

regards,


Andrew Dinn
---



Re: ClassFileTransformer does not apply to anonymous classes

2016-01-26 Thread Rafael Winterhalter
Another note on this subject: I found that applying a
reretransformation on a lambda expression's class does not provide the
original class file to the retransformer but the class file that
resulted from a previous retransformation. (If a lambda class is
retransformed several times.) This is different to "normal" classes
where the original class file is provided.

2016-01-25 20:24 GMT+01:00 Rafael Winterhalter :
> Hi Vladmir, hello Remi,
>
> what bothers me about instrumenting a lambda expression's target
> method is the difficulty of locating the method that contains the code
> and setting it into context. This is a lot of work to do since one
> needs to first locate any invokedynamic call sites and interpret the
> connection via the LambdaMetafactory. This is difficult to instrument
> without greater efforts and does not feel like a clean solution.
>
> Many real life instrumentations are based on the assumption of being
> able to instrument any class of a given subtype or other any other
> class property. For example, one would want to instrument any class
> that implements InputStream to discover a resource leak. If the
> interface is however functional and implemented as a lambda
> expression, a tool that manipulating all class files of this type
> stops working. At the same time, end users do not really understand
> the difference of their former anonymous class that is now expressed a
> lambda expression and perceive the beaviour as a regression.
>
> I have myself implemented a custom solution for my code generation
> library that instruments the LambdaMetafactory to apply class file
> transformers to these classes manually. This does however show two
> disadvantages:
>
> 1. javac creates the target method of a lambda expression as a private
> method. The only way to implement a lambda expression legally in byte
> code is by loading the generated implementation anonymously what
> requires non-public API. While it is possible to call
> Unsafe::defineAnonymousClass from the instrumented LambdaMetafactory,
> it is again required to use non-standardized APIs which might fail on
> differing implementations of the JVM.
>
> 2. At the same time, there is no standardized way to receive all
> ClassFileTransformers that are currently registered on the VM. this
> also requires calls into internal APIs that are not necessarily
> supported on other platforms.
>
> I fully understand the hesitation to support this from a technical
> point of view but in reality, people are already dependant on this
> feature and disallowing the instrumentation of lambda classes will
> only inspire work-arrounds that reduce the stability of software using
> this APIs that does currently work without problems for non-lambda
> classes.
>
> Best regards, Rafael
>
> PS: While implementing my solution, I found that the LambdaMetafactory
> of the Open JDK creates private, final methods for the serialization
> bits. The methods should however not be final as they are already
> private.
>
>
> 2016-01-23 13:55 GMT+01:00 Remi Forax :
>> I agree with Vladimir,
>>
>> You should not be able to transform/redefine a VM anonymous class because 
>> the transformer will certainly mess up with the order of the constant pool 
>> entries.
>>
>> Slightly off-topic, about ASM, when you create a ClassWriter [1], you can 
>> pass a ClassReader of an existing class, in that case ASM copy the constant 
>> pool from the class reader to the class writer so the constant pool is 
>> preserved.
>>
>> Rémi
>>
>> [1] 
>> http://asm.ow2.org/asm50/javadoc/user/org/objectweb/asm/ClassWriter.html#ClassWriter%28org.objectweb.asm.ClassReader,%20int%29
>>
>> - Mail original -----
>>> De: "Vladimir Ivanov" 
>>> À: "Rafael Winterhalter" 
>>> Cc: "Coleen Phillimore" , 
>>> core-libs-dev@openjdk.java.net, "serguei.spit...@oracle.com
>>> Spitsyn" , "Daniel Daugherty" 
>>> 
>>> Envoyé: Vendredi 22 Janvier 2016 18:47:31
>>> Objet: Re: ClassFileTransformer does not apply to anonymous classes
>>>
>>> Rafael,
>>>
>>> First of all, I'd like to agree on the terminology. There's some
>>> confusion there. Anonymous term is ambiguous in Java. There are
>>> anonymous classes on language level and there's
>>> Unsafe.defineAnonymousClass() which produce anonymous-in-VM-sense
>>> classes. I prefer to call them VM anonymous classes to avoid confusion.
>>>
>>> I assume that whenever you use anonymous you assume "VM anonymous".
>>>
>>> > thank you for your res

Re: ClassFileTransformer does not apply to anonymous classes

2016-01-25 Thread Rafael Winterhalter
Hi Vladmir, hello Remi,

what bothers me about instrumenting a lambda expression's target
method is the difficulty of locating the method that contains the code
and setting it into context. This is a lot of work to do since one
needs to first locate any invokedynamic call sites and interpret the
connection via the LambdaMetafactory. This is difficult to instrument
without greater efforts and does not feel like a clean solution.

Many real life instrumentations are based on the assumption of being
able to instrument any class of a given subtype or other any other
class property. For example, one would want to instrument any class
that implements InputStream to discover a resource leak. If the
interface is however functional and implemented as a lambda
expression, a tool that manipulating all class files of this type
stops working. At the same time, end users do not really understand
the difference of their former anonymous class that is now expressed a
lambda expression and perceive the beaviour as a regression.

I have myself implemented a custom solution for my code generation
library that instruments the LambdaMetafactory to apply class file
transformers to these classes manually. This does however show two
disadvantages:

1. javac creates the target method of a lambda expression as a private
method. The only way to implement a lambda expression legally in byte
code is by loading the generated implementation anonymously what
requires non-public API. While it is possible to call
Unsafe::defineAnonymousClass from the instrumented LambdaMetafactory,
it is again required to use non-standardized APIs which might fail on
differing implementations of the JVM.

2. At the same time, there is no standardized way to receive all
ClassFileTransformers that are currently registered on the VM. this
also requires calls into internal APIs that are not necessarily
supported on other platforms.

I fully understand the hesitation to support this from a technical
point of view but in reality, people are already dependant on this
feature and disallowing the instrumentation of lambda classes will
only inspire work-arrounds that reduce the stability of software using
this APIs that does currently work without problems for non-lambda
classes.

Best regards, Rafael

PS: While implementing my solution, I found that the LambdaMetafactory
of the Open JDK creates private, final methods for the serialization
bits. The methods should however not be final as they are already
private.


2016-01-23 13:55 GMT+01:00 Remi Forax :
> I agree with Vladimir,
>
> You should not be able to transform/redefine a VM anonymous class because the 
> transformer will certainly mess up with the order of the constant pool 
> entries.
>
> Slightly off-topic, about ASM, when you create a ClassWriter [1], you can 
> pass a ClassReader of an existing class, in that case ASM copy the constant 
> pool from the class reader to the class writer so the constant pool is 
> preserved.
>
> Rémi
>
> [1] 
> http://asm.ow2.org/asm50/javadoc/user/org/objectweb/asm/ClassWriter.html#ClassWriter%28org.objectweb.asm.ClassReader,%20int%29
>
> - Mail original -
>> De: "Vladimir Ivanov" 
>> À: "Rafael Winterhalter" 
>> Cc: "Coleen Phillimore" , 
>> core-libs-dev@openjdk.java.net, "serguei.spit...@oracle.com
>> Spitsyn" , "Daniel Daugherty" 
>> 
>> Envoyé: Vendredi 22 Janvier 2016 18:47:31
>> Objet: Re: ClassFileTransformer does not apply to anonymous classes
>>
>> Rafael,
>>
>> First of all, I'd like to agree on the terminology. There's some
>> confusion there. Anonymous term is ambiguous in Java. There are
>> anonymous classes on language level and there's
>> Unsafe.defineAnonymousClass() which produce anonymous-in-VM-sense
>> classes. I prefer to call them VM anonymous classes to avoid confusion.
>>
>> I assume that whenever you use anonymous you assume "VM anonymous".
>>
>> > thank you for your response. While I completely understand your view
>> > from a VM implementor's point of view, as a practicioner I would
>> > recommend against it. Not being able to instrument lambda expressions
>> > puts a severe limitation onto using the instrumentation API
>> > alltogether. For example, a monitoring application that promises to
>> > record all invocations of a method of a certain interface that only
>> > works 95% of the time is not 5% less usefull but might no longer be
>> > useful at all. People have build large applications based on the
>> > assumption that all user application code can be instrumented and such
>> > a regression would hurt them. For example, until today, over 30 people
>> > that use my code generation framewor

Re: ClassFileTransformer does not apply to anonymous classes

2016-01-23 Thread Remi Forax
I agree with Vladimir,

You should not be able to transform/redefine a VM anonymous class because the 
transformer will certainly mess up with the order of the constant pool entries.

Slightly off-topic, about ASM, when you create a ClassWriter [1], you can pass 
a ClassReader of an existing class, in that case ASM copy the constant pool 
from the class reader to the class writer so the constant pool is preserved.

Rémi

[1] 
http://asm.ow2.org/asm50/javadoc/user/org/objectweb/asm/ClassWriter.html#ClassWriter%28org.objectweb.asm.ClassReader,%20int%29

- Mail original -
> De: "Vladimir Ivanov" 
> À: "Rafael Winterhalter" 
> Cc: "Coleen Phillimore" , 
> core-libs-dev@openjdk.java.net, "serguei.spit...@oracle.com
> Spitsyn" , "Daniel Daugherty" 
> 
> Envoyé: Vendredi 22 Janvier 2016 18:47:31
> Objet: Re: ClassFileTransformer does not apply to anonymous classes
> 
> Rafael,
> 
> First of all, I'd like to agree on the terminology. There's some
> confusion there. Anonymous term is ambiguous in Java. There are
> anonymous classes on language level and there's
> Unsafe.defineAnonymousClass() which produce anonymous-in-VM-sense
> classes. I prefer to call them VM anonymous classes to avoid confusion.
> 
> I assume that whenever you use anonymous you assume "VM anonymous".
> 
> > thank you for your response. While I completely understand your view
> > from a VM implementor's point of view, as a practicioner I would
> > recommend against it. Not being able to instrument lambda expressions
> > puts a severe limitation onto using the instrumentation API
> > alltogether. For example, a monitoring application that promises to
> > record all invocations of a method of a certain interface that only
> > works 95% of the time is not 5% less usefull but might no longer be
> > useful at all. People have build large applications based on the
> > assumption that all user application code can be instrumented and such
> > a regression would hurt them. For example, until today, over 30 people
> > that use my code generation framework reached out to me and reported
> > the reported behavior as a bug in my library and people are only
> > starting to migrate their applications to Java 8. The outcome is
> > simply not intuitive as using a lambda expression over an anonyous
> > inner class should not change an application's behavior.
> Can you elaborate on that point, please?
> 
> I don't see any problems with instrumenting user code. Javac represents
> lambda expression body as a private static method of the enclosing
> class, which can be instrumented. VM anonymous classes are used only as
> a mechanism to glue functional interfaces and lambda expressions
> together at runtime.
> 
> For example:
> static void f(Runnable r) { r.run(); }
> f(() -> {});
> 
> Test::f (7 bytes)
>@ 1   Test$$Lambda$1/791452441::run (4 bytes)   inline (hot)
>  @ 0   Test::lambda$main$0 (1 bytes)   inline (hot)
> 
> Why do you need to instrument Test$$Lambda$1/... and not
> Test::lambda$main$0?
> 
> > The currently used workaround that people use is to instrument the
> > LambdaMetaFactory class itself to apply the transformer manually when
> > it is being created. This solution is spreading as a standard approach
> > and I am sure that forbidding a redefinition alltogether would only
> > inspire to other workarrounds for being able to migrate running code
> > to the next Java version.
> It doesn't sound like a workaround, but as a solution for a different
> problem.
> 
> If there's a need to gather profile for every lambda expression
> instantiation site (indy call), then redefining bootstrap method is the
> right way to go IMO. It allows to intercept and customize indy call site
> binding.
> 
> What does sound as a workaround is an attempt to instrument classes
> produced by LambdaMetaFactory. Right now, it generates a fresh VM
> anonymous class on every request, but it is an implementation detail and
> not a requirement.
> 
> For example, LambdaMetaFactory can reuse wrappers on per-functional
> interface basis. It would provide significant footprint savings for
> lambda expression-rich code bases (usually, there are much more
> instantiations than functional interface flavors).
> 
> > Furthermore, I do not think that not being able to patch constant pool
> > indices in the generated code introduces any problems in practice.
> > Most real-world instrumentation only appends new constant pool entries
> > without interfering with the existant pool. Rather, I would like to
> > see an exception being raised if one att

Re: ClassFileTransformer does not apply to anonymous classes

2016-01-22 Thread Vladimir Ivanov

Rafael,

First of all, I'd like to agree on the terminology. There's some 
confusion there. Anonymous term is ambiguous in Java. There are 
anonymous classes on language level and there's 
Unsafe.defineAnonymousClass() which produce anonymous-in-VM-sense 
classes. I prefer to call them VM anonymous classes to avoid confusion.


I assume that whenever you use anonymous you assume "VM anonymous".


thank you for your response. While I completely understand your view
from a VM implementor's point of view, as a practicioner I would
recommend against it. Not being able to instrument lambda expressions
puts a severe limitation onto using the instrumentation API
alltogether. For example, a monitoring application that promises to
record all invocations of a method of a certain interface that only
works 95% of the time is not 5% less usefull but might no longer be
useful at all. People have build large applications based on the
assumption that all user application code can be instrumented and such
a regression would hurt them. For example, until today, over 30 people
that use my code generation framework reached out to me and reported
the reported behavior as a bug in my library and people are only
starting to migrate their applications to Java 8. The outcome is
simply not intuitive as using a lambda expression over an anonyous
inner class should not change an application's behavior.

Can you elaborate on that point, please?

I don't see any problems with instrumenting user code. Javac represents 
lambda expression body as a private static method of the enclosing 
class, which can be instrumented. VM anonymous classes are used only as 
a mechanism to glue functional interfaces and lambda expressions 
together at runtime.


For example:
   static void f(Runnable r) { r.run(); }
   f(() -> {});

Test::f (7 bytes)
  @ 1   Test$$Lambda$1/791452441::run (4 bytes)   inline (hot)
@ 0   Test::lambda$main$0 (1 bytes)   inline (hot)

Why do you need to instrument Test$$Lambda$1/... and not 
Test::lambda$main$0?



The currently used workaround that people use is to instrument the
LambdaMetaFactory class itself to apply the transformer manually when
it is being created. This solution is spreading as a standard approach
and I am sure that forbidding a redefinition alltogether would only
inspire to other workarrounds for being able to migrate running code
to the next Java version.
It doesn't sound like a workaround, but as a solution for a different 
problem.


If there's a need to gather profile for every lambda expression 
instantiation site (indy call), then redefining bootstrap method is the 
right way to go IMO. It allows to intercept and customize indy call site 
binding.


What does sound as a workaround is an attempt to instrument classes 
produced by LambdaMetaFactory. Right now, it generates a fresh VM 
anonymous class on every request, but it is an implementation detail and 
not a requirement.


For example, LambdaMetaFactory can reuse wrappers on per-functional 
interface basis. It would provide significant footprint savings for 
lambda expression-rich code bases (usually, there are much more 
instantiations than functional interface flavors).



Furthermore, I do not think that not being able to patch constant pool
indices in the generated code introduces any problems in practice.
Most real-world instrumentation only appends new constant pool entries
without interfering with the existant pool. Rather, I would like to
see an exception being raised if one attempts to change the original
constant pool without me being able to consider this from a technical
perspective. I think this would serve to be sufficient for most
people.
If you care only about lambda expressions, then constant pool patching 
shouldn't be a problem (AFAIR it isn't used for lambda expressions). But 
in a more generic case (even for java.lang.invoke purposes), the 
coupling between class file and CP patches is very tight and can be 
easily broken with benign class file transformations. Considering ASM 
library, I'm not sure that even simple instrumentations preserve 
original constant pool structure.


Probably, VM can do some structural checks on CP to forbid any 
modifications except appends, but there are still aliasing problems - 
sharing doesn't work (even for string constants), so new code shouldn't 
use original CP entries.


I'd prefer to avoid such increase in complexity in VM implementation.


I really hope that there is a way to allow for patching anonymously
loaded classes even without exposing the constant pool patches.
From VM implementation perspective I don't see any problems with 
allowing class file redefinition for VM anonymous classes. What I want 
to do is to discourage from doing so. Again - it is very fragile and 
there's little we can do to fix that.



So far, thank you for looking into this. I am sure this a more complex
matter than what I am able to comprehend. I appreciate that you are
taking the time to consider my

Re: ClassFileTransformer does not apply to anonymous classes

2016-01-22 Thread Rafael Winterhalter
Hi Vladimir,

thank you for your response. While I completely understand your view
from a VM implementor's point of view, as a practicioner I would
recommend against it. Not being able to instrument lambda expressions
puts a severe limitation onto using the instrumentation API
alltogether. For example, a monitoring application that promises to
record all invocations of a method of a certain interface that only
works 95% of the time is not 5% less usefull but might no longer be
useful at all. People have build large applications based on the
assumption that all user application code can be instrumented and such
a regression would hurt them. For example, until today, over 30 people
that use my code generation framework reached out to me and reported
the reported behavior as a bug in my library and people are only
starting to migrate their applications to Java 8. The outcome is
simply not intuitive as using a lambda expression over an anonyous
inner class should not change an application's behavior.

The currently used workaround that people use is to instrument the
LambdaMetaFactory class itself to apply the transformer manually when
it is being created. This solution is spreading as a standard approach
and I am sure that forbidding a redefinition alltogether would only
inspire to other workarrounds for being able to migrate running code
to the next Java version.

Furthermore, I do not think that not being able to patch constant pool
indices in the generated code introduces any problems in practice.
Most real-world instrumentation only appends new constant pool entries
without interfering with the existant pool. Rather, I would like to
see an exception being raised if one attempts to change the original
constant pool without me being able to consider this from a technical
perspective. I think this would serve to be sufficient for most
people.

I really hope that there is a way to allow for patching anonymously
loaded classes even without exposing the constant pool patches.
So far, thank you for looking into this. I am sure this a more complex
matter than what I am able to comprehend. I appreciate that you are
taking the time to consider my opinion!

Best regards, Rafael

2016-01-22 16:42 GMT+01:00 Vladimir Ivanov :
> Rafael,
>
> What you are seeing are just consequences. My impression is that VM
> anonymous class redefinition/retransformation works mostly by accident.
>
> The real problem is that current API (both JVMTI and java.lang.instrument)
> doesn't serve for them well.
>
> When VM anonymous class is defined, a user provides both bytecode and CP
> patches:
> public native Class defineAnonymousClass(Class hostClass, byte[]
> data, Object[] cpPatches);
>
> Unless there's a way to adjust CP patches along with the bytecode, patching
> bytecode is very fragile (e.g., no way to add new patches, should keep
> patched CP entry indexes intact).
>
> The root cause is Unsafe.defineAnonymousClass is part of
> implementation-specific private API, so no way to expose it a public APIs
> (special entry points in JVMTI or java.lang.instrument).
>
> Also, though the concept of VM anonymous class was a step in the right
> direction, it isn't good enough to be standardized. The ultimate goal is to
> get lightweight code loading mechanism, but VM anonymous classes are still
> loaded with class semantics.
>
> So, I don't think we can do much w.r.t. VM anonymous classes. I'd prefer JVM
> to skip agent notifications or completely forbidding VM anonymous class
> retransformation/redefinition, but I haven't thought through compatibility
> consequences.
>
> Best regards,
> Vladimir Ivanov
>
>
> On 1/22/16 5:04 PM, Rafael Winterhalter wrote:
>>
>> Hi Coleen, thanks for looking into this. My original mail was the
>> following:
>>
>> Hello everybody,
>>
>> classes that are loaded via Unsafe::defineAnonymousClass are not
>> transformed by a registered ClassFileTransformer. At the same time, it
>> is possible to retransform / redefine such an anonymous classes using
>> the instrumentation API.
>>
>> Here is a rather confusing bug that I encountered when working with an
>> internally used Java agent after upgrading a code base to Java 8:
>>
>> The Java agent attaches at runtime (agentmain). It then registers a
>> ClassFileTransformer that also applies for retransformation.
>> Afterwards, all loaded classes that fullfil a given condition are
>> explicitly registered to be retransformed by the agent. (Doing so,
>> anonymous classes are returned by
>> Instrumentation::getAllLoadedClasses.) This resulted in the following
>> behavior of the agent:
>>
>> a) If the agent was attached after an anonymous class was loaded, the
>> retransformation would apply to an anonymous class.
>> b) If the agent was attached "too early", the (non-re-)transformation
>> would not apply to an anonymous class.
>>
>> I wonder if it is intentional that a ClassFileTransformer is not
>> applied when an anonymous class is loaded. Personally, I find this
>> count

Re: ClassFileTransformer does not apply to anonymous classes

2016-01-22 Thread Vladimir Ivanov

Rafael,

What you are seeing are just consequences. My impression is that VM 
anonymous class redefinition/retransformation works mostly by accident.


The real problem is that current API (both JVMTI and 
java.lang.instrument) doesn't serve for them well.


When VM anonymous class is defined, a user provides both bytecode and CP 
patches:
public native Class defineAnonymousClass(Class hostClass, 
byte[] data, Object[] cpPatches);


Unless there's a way to adjust CP patches along with the bytecode, 
patching bytecode is very fragile (e.g., no way to add new patches, 
should keep patched CP entry indexes intact).


The root cause is Unsafe.defineAnonymousClass is part of 
implementation-specific private API, so no way to expose it a public 
APIs (special entry points in JVMTI or java.lang.instrument).


Also, though the concept of VM anonymous class was a step in the right 
direction, it isn't good enough to be standardized. The ultimate goal is 
to get lightweight code loading mechanism, but VM anonymous classes are 
still loaded with class semantics.


So, I don't think we can do much w.r.t. VM anonymous classes. I'd prefer 
JVM to skip agent notifications or completely forbidding VM anonymous 
class retransformation/redefinition, but I haven't thought through 
compatibility consequences.


Best regards,
Vladimir Ivanov

On 1/22/16 5:04 PM, Rafael Winterhalter wrote:

Hi Coleen, thanks for looking into this. My original mail was the following:

Hello everybody,

classes that are loaded via Unsafe::defineAnonymousClass are not
transformed by a registered ClassFileTransformer. At the same time, it
is possible to retransform / redefine such an anonymous classes using
the instrumentation API.

Here is a rather confusing bug that I encountered when working with an
internally used Java agent after upgrading a code base to Java 8:

The Java agent attaches at runtime (agentmain). It then registers a
ClassFileTransformer that also applies for retransformation.
Afterwards, all loaded classes that fullfil a given condition are
explicitly registered to be retransformed by the agent. (Doing so,
anonymous classes are returned by
Instrumentation::getAllLoadedClasses.) This resulted in the following
behavior of the agent:

a) If the agent was attached after an anonymous class was loaded, the
retransformation would apply to an anonymous class.
b) If the agent was attached "too early", the (non-re-)transformation
would not apply to an anonymous class.

I wonder if it is intentional that a ClassFileTransformer is not
applied when an anonymous class is loaded. Personally, I find this
counter-intuitive, especially when converting anonymous inner classes
to lambda expressions where many users of instrumentation do not
forsee the behavioral change. It also puts a very unforseeable limit
to the instrumentation API. I would therefore like to suggest that
ClassFileTransformers are also applied to anonymous classes when
Unsafe::defineAnonymousClass is called just as when going via
ClassLoader::defineClass.

I can tell that this behavior has not only affected me as I had this
question comming up by multiple users of my open-source code
generation library.

What is your view on this?

Thank you for your feedback!
Best regards, Rafael

2016-01-22 15:00 GMT+01:00 Coleen Phillimore :



On 1/22/16 4:11 AM, Andrew Dinn wrote:


On 21/01/16 22:14, Rafael Winterhalter wrote:


Hi Andrew,
if there is any update on the matter, I would of course love to hear
about it.
Unfortunately, I never received an answer to my question, but maybe I
picked the wrong list.
Thank you for your support on this issue!


I'm pretty sure this is the right list. But I don't know who cold answer
the question. I know that Coleen Phillmore (added explicitly to CC)
often deals with ClassFileTransformer issues. Coleen, can you answer?



Can you send the question again?  I didn't see it.  I also mostly look at
JVM code and rarely deal with the Java side.

I'm also adding Dan, Serguei and Markus.

Thanks,
Coleen



regards,


Andrew Dinn
---
Senior Principal Software Engineer
Red Hat UK Ltd
Registered in UK and Wales under Company Registration No. 3798903
Directors: Michael Cunningham (US), Michael O'Neill (Ireland), Paul
Argiry (US)





Re: ClassFileTransformer does not apply to anonymous classes

2016-01-22 Thread Rafael Winterhalter
You are right. It is observed for all JDK8u releases and persists in
the current builds of JDK9.
Best regards, Rafael

2016-01-22 16:15 GMT+01:00 Daniel D. Daugherty :
> On 1/22/16 7:29 AM, Alan Bateman wrote:
>>
>>
>> On 22/01/2016 14:00, Coleen Phillimore wrote:
>>>
>>> Can you send the question again?  I didn't see it.  I also mostly look at
>>> JVM code and rarely deal with the Java side.
>>>
>> The question was asked about ClassFileTransformer which is implemented by
>> the JPLIS agent via the JVM TI CFLH event. So I think the question is really
>> on whether this event can be posted for classes defined via
>> defineAnonymousClass. None of the standard APIs know about HotSpot specific
>> concepts like "host class" but maybe the host class defining loader and PD
>> can be used with this event. I don't know if this has been explored
>> elsewhere already.
>>
>> -Alan.
>>
>
> Sounds like defineAnonymousClass() is somehow by-passing the placement
> of the CFLH event poster.
>
> I don't see any information here about which JDK version this issue
> is being seen with. I suspect JDK8u, but that's just a guess...
>
> Dan


Re: ClassFileTransformer does not apply to anonymous classes

2016-01-22 Thread Daniel D. Daugherty

On 1/22/16 7:29 AM, Alan Bateman wrote:


On 22/01/2016 14:00, Coleen Phillimore wrote:
Can you send the question again?  I didn't see it.  I also mostly 
look at JVM code and rarely deal with the Java side.


The question was asked about ClassFileTransformer which is implemented 
by the JPLIS agent via the JVM TI CFLH event. So I think the question 
is really on whether this event can be posted for classes defined via 
defineAnonymousClass. None of the standard APIs know about HotSpot 
specific concepts like "host class" but maybe the host class defining 
loader and PD can be used with this event. I don't know if this has 
been explored elsewhere already.


-Alan.



Sounds like defineAnonymousClass() is somehow by-passing the placement
of the CFLH event poster.

I don't see any information here about which JDK version this issue
is being seen with. I suspect JDK8u, but that's just a guess...

Dan


Re: ClassFileTransformer does not apply to anonymous classes

2016-01-22 Thread Alan Bateman


On 22/01/2016 14:00, Coleen Phillimore wrote:
Can you send the question again?  I didn't see it.  I also mostly look 
at JVM code and rarely deal with the Java side.


The question was asked about ClassFileTransformer which is implemented 
by the JPLIS agent via the JVM TI CFLH event. So I think the question is 
really on whether this event can be posted for classes defined via 
defineAnonymousClass. None of the standard APIs know about HotSpot 
specific concepts like "host class" but maybe the host class defining 
loader and PD can be used with this event. I don't know if this has been 
explored elsewhere already.


-Alan.


Re: ClassFileTransformer does not apply to anonymous classes

2016-01-22 Thread Rafael Winterhalter
Hi Coleen, thanks for looking into this. My original mail was the following:

Hello everybody,

classes that are loaded via Unsafe::defineAnonymousClass are not
transformed by a registered ClassFileTransformer. At the same time, it
is possible to retransform / redefine such an anonymous classes using
the instrumentation API.

Here is a rather confusing bug that I encountered when working with an
internally used Java agent after upgrading a code base to Java 8:

The Java agent attaches at runtime (agentmain). It then registers a
ClassFileTransformer that also applies for retransformation.
Afterwards, all loaded classes that fullfil a given condition are
explicitly registered to be retransformed by the agent. (Doing so,
anonymous classes are returned by
Instrumentation::getAllLoadedClasses.) This resulted in the following
behavior of the agent:

a) If the agent was attached after an anonymous class was loaded, the
retransformation would apply to an anonymous class.
b) If the agent was attached "too early", the (non-re-)transformation
would not apply to an anonymous class.

I wonder if it is intentional that a ClassFileTransformer is not
applied when an anonymous class is loaded. Personally, I find this
counter-intuitive, especially when converting anonymous inner classes
to lambda expressions where many users of instrumentation do not
forsee the behavioral change. It also puts a very unforseeable limit
to the instrumentation API. I would therefore like to suggest that
ClassFileTransformers are also applied to anonymous classes when
Unsafe::defineAnonymousClass is called just as when going via
ClassLoader::defineClass.

I can tell that this behavior has not only affected me as I had this
question comming up by multiple users of my open-source code
generation library.

What is your view on this?

Thank you for your feedback!
Best regards, Rafael

2016-01-22 15:00 GMT+01:00 Coleen Phillimore :
>
>
> On 1/22/16 4:11 AM, Andrew Dinn wrote:
>>
>> On 21/01/16 22:14, Rafael Winterhalter wrote:
>>>
>>> Hi Andrew,
>>> if there is any update on the matter, I would of course love to hear
>>> about it.
>>> Unfortunately, I never received an answer to my question, but maybe I
>>> picked the wrong list.
>>> Thank you for your support on this issue!
>>
>> I'm pretty sure this is the right list. But I don't know who cold answer
>> the question. I know that Coleen Phillmore (added explicitly to CC)
>> often deals with ClassFileTransformer issues. Coleen, can you answer?
>
>
> Can you send the question again?  I didn't see it.  I also mostly look at
> JVM code and rarely deal with the Java side.
>
> I'm also adding Dan, Serguei and Markus.
>
> Thanks,
> Coleen
>
>>
>> regards,
>>
>>
>> Andrew Dinn
>> ---
>> Senior Principal Software Engineer
>> Red Hat UK Ltd
>> Registered in UK and Wales under Company Registration No. 3798903
>> Directors: Michael Cunningham (US), Michael O'Neill (Ireland), Paul
>> Argiry (US)
>
>


Re: ClassFileTransformer does not apply to anonymous classes

2016-01-22 Thread Coleen Phillimore



On 1/22/16 4:11 AM, Andrew Dinn wrote:

On 21/01/16 22:14, Rafael Winterhalter wrote:

Hi Andrew,
if there is any update on the matter, I would of course love to hear about it.
Unfortunately, I never received an answer to my question, but maybe I
picked the wrong list.
Thank you for your support on this issue!

I'm pretty sure this is the right list. But I don't know who cold answer
the question. I know that Coleen Phillmore (added explicitly to CC)
often deals with ClassFileTransformer issues. Coleen, can you answer?


Can you send the question again?  I didn't see it.  I also mostly look 
at JVM code and rarely deal with the Java side.


I'm also adding Dan, Serguei and Markus.

Thanks,
Coleen


regards,


Andrew Dinn
---
Senior Principal Software Engineer
Red Hat UK Ltd
Registered in UK and Wales under Company Registration No. 3798903
Directors: Michael Cunningham (US), Michael O'Neill (Ireland), Paul
Argiry (US)




Re: ClassFileTransformer does not apply to anonymous classes

2016-01-22 Thread Andrew Dinn
On 21/01/16 22:14, Rafael Winterhalter wrote:
> Hi Andrew,
> if there is any update on the matter, I would of course love to hear about it.
> Unfortunately, I never received an answer to my question, but maybe I
> picked the wrong list.
> Thank you for your support on this issue!

I'm pretty sure this is the right list. But I don't know who cold answer
the question. I know that Coleen Phillmore (added explicitly to CC)
often deals with ClassFileTransformer issues. Coleen, can you answer?

regards,


Andrew Dinn
---
Senior Principal Software Engineer
Red Hat UK Ltd
Registered in UK and Wales under Company Registration No. 3798903
Directors: Michael Cunningham (US), Michael O'Neill (Ireland), Paul
Argiry (US)


Re: ClassFileTransformer does not apply to anonymous classes

2016-01-21 Thread Rafael Winterhalter
Hi Andrew,
if there is any update on the matter, I would of course love to hear about it.
Unfortunately, I never received an answer to my question, but maybe I
picked the wrong list.
Thank you for your support on this issue!
Regards, Rafael

2016-01-21 10:07 GMT+01:00 Andrew Dinn :
> Hi Rafael,
>
> On 01/12/15 12:45, Rafael Winterhalter wrote:
>> I can tell that this behavior has not only affected me as I had this
>> question comming up by multiple users of my open-source code generation
>> library.
>>
>> What is your view on this?
>>
>> Thank you for your feedback!
>
> I have an interest in this issue because I lead a Java agent-based
> project (Byteman). I have not (yet) come across a case where the
> behaviour you describe has affected the operation of my agent -- I
> suspect that is because it will never attempt to transform a class
> defined via Unsafe::defineAnonymousClass. However, I agree with you that
> this behaviour appears anomalous and the outcome you describe is
> counter-intuitive. I would be very interested to know if there was a
> good reason for excluding anonymous classes from transformation.
>
> regards,
>
>
> Andrew Dinn
> ---
> Senior Principal Software Engineer
> Red Hat UK Ltd
> Registered in UK and Wales under Company Registration No. 3798903
> Directors: Michael Cunningham (US), Michael O'Neill (Ireland), Paul
> Argiry (US)


Re: ClassFileTransformer does not apply to anonymous classes

2016-01-21 Thread Andrew Dinn
Hi Rafael,

On 01/12/15 12:45, Rafael Winterhalter wrote:
> I can tell that this behavior has not only affected me as I had this
> question comming up by multiple users of my open-source code generation
> library.
> 
> What is your view on this?
> 
> Thank you for your feedback!

I have an interest in this issue because I lead a Java agent-based
project (Byteman). I have not (yet) come across a case where the
behaviour you describe has affected the operation of my agent -- I
suspect that is because it will never attempt to transform a class
defined via Unsafe::defineAnonymousClass. However, I agree with you that
this behaviour appears anomalous and the outcome you describe is
counter-intuitive. I would be very interested to know if there was a
good reason for excluding anonymous classes from transformation.

regards,


Andrew Dinn
---
Senior Principal Software Engineer
Red Hat UK Ltd
Registered in UK and Wales under Company Registration No. 3798903
Directors: Michael Cunningham (US), Michael O'Neill (Ireland), Paul
Argiry (US)


ClassFileTransformer does not apply to anonymous classes

2015-12-01 Thread Rafael Winterhalter
Hello everybody,

classes that are loaded via Unsafe::defineAnonymousClass are not
transformed by a registered ClassFileTransformer. At the same time, it is
possible to retransform / redefine such an anonymous classes using the
instrumentation API.

Here is a rather confusing bug that I encountered when working with an
internally used Java agent after upgrading a code base to Java 8:

The Java agent attaches at runtime (agentmain). It then registers a
ClassFileTransformer that also applies for retransformation. Afterwards,
all loaded classes that fullfil a given condition are explicitly registered
to be retransformed by the agent. (Doing so, anonymous classes are returned
by Instrumentation::getAllLoadedClasses.) This resulted in the following
behavior of the agent:

a) If the agent was attached after an anonymous class was loaded, the
retransformation would apply to an anonymous class.
b) If the agent was attached "too early", the (non-re-)transformation would
not apply to an anonymous class.

I wonder if it is intentional that a ClassFileTransformer is not applied
when an anonymous class is loaded. Personally, I find this
counter-intuitive, especially when converting anonymous inner classes to
lambda expressions where many users of instrumentation do not forsee the
behavioral change. It also puts a very unforseeable limit to the
instrumentation API. I would therefore like to suggest that
ClassFileTransformers are also applied to anonymous classes when
Unsafe::defineAnonymousClass is called just as when going via
ClassLoader::defineClass.

I can tell that this behavior has not only affected me as I had this
question comming up by multiple users of my open-source code generation
library.

What is your view on this?

Thank you for your feedback!
Best regards, Rafael