sun.reflect.Reflection.getCallerClass(int) is going to be removed... how to replace?

2013-07-02 Thread Jochen Theodorou
Hi all,

The Oracle JDK internal method sun.reflect.Reflection.
getCallerClass(int) is planned to be disabled in Oracle JDK 7u40. It is 
considered for removal in a later 7 update release.

As you may be aware, the Oracle JDK internal 
sun.reflect.Reflection.getCallerClass(int) method has been removed from 
JDK 8. [1]
The method is also planned [2] to be disabled in the 7u40 release. A 
call to the method would then trigger an UnsupportedOperationException.

That means the method will be fully away for jdk8 and is going away in 
7u40, but can still be enabled by a command line switch. There is a 
@CallSensitve annotation which allows calling Reflection.getCallerClass().

But this is causing some problems for us actually. Even if 
Reflection.getCallerClass() is ignoring all frames added by reflection 
(what about those added by invokedynamic/lambda?), it is not enough for 
us, since we will have also runtime generated classes appearing in there.

A simple example is a Groovy program calling 
ResourceBundle#getBundle(String). While in non-indy mode the first 
access from that call site may be done by reflection and then work, 
subsequent calls would be done with runtime generated classes and then 
it can stop working very fast. Another one is Groovy grapes, which add 
libraries to the classpath at runtime, and it depends on being able to 
get the caller class loader for that. The usual depths here are 3-4, and 
that means 3-4 frames, that are not our callsite caching or indy, or 
reflection.

With the runtime generated classes in the way I am not sure we can 
resolve the issue without really major changes, or we simply say that 
Groovy 2.x and earlier may not properly work on post jdk 7u40... unless 
you use indy, where I would still need confirmation there are no frames 
in the way from that then.

I imagine other languages will have similar problems here and there... 
or not?

bye Jochen

-- 
Jochen blackdrag Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: sun.reflect.Reflection.getCallerClass(int) is going to be removed... how to replace?

2013-07-02 Thread Attila Szegedi
FWIW, I'm currently working on Dynalink correctly supporting methods that are 
marked with @CallerSensitive; My tests from Nashorn show things work as 
expected, i.e. you can give some permissions to your script based on its URL in 
the security policy, and e.g. invoking AccessController.doPrivileged() through 
INVOKEDYNAMIC works as expected; it is actually a pretty big deal getting this 
to work right :-) (doPrivileged, of course, being @CallerSensitive).

Attila.

On Jul 2, 2013, at 2:56 PM, Jochen Theodorou blackd...@gmx.org wrote:

 Hi all,
 
 The Oracle JDK internal method sun.reflect.Reflection.
 getCallerClass(int) is planned to be disabled in Oracle JDK 7u40. It is 
 considered for removal in a later 7 update release.
 
 As you may be aware, the Oracle JDK internal 
 sun.reflect.Reflection.getCallerClass(int) method has been removed from 
 JDK 8. [1]
 The method is also planned [2] to be disabled in the 7u40 release. A 
 call to the method would then trigger an UnsupportedOperationException.
 
 That means the method will be fully away for jdk8 and is going away in 
 7u40, but can still be enabled by a command line switch. There is a 
 @CallSensitve annotation which allows calling Reflection.getCallerClass().
 
 But this is causing some problems for us actually. Even if 
 Reflection.getCallerClass() is ignoring all frames added by reflection 
 (what about those added by invokedynamic/lambda?), it is not enough for 
 us, since we will have also runtime generated classes appearing in there.
 
 A simple example is a Groovy program calling 
 ResourceBundle#getBundle(String). While in non-indy mode the first 
 access from that call site may be done by reflection and then work, 
 subsequent calls would be done with runtime generated classes and then 
 it can stop working very fast. Another one is Groovy grapes, which add 
 libraries to the classpath at runtime, and it depends on being able to 
 get the caller class loader for that. The usual depths here are 3-4, and 
 that means 3-4 frames, that are not our callsite caching or indy, or 
 reflection.
 
 With the runtime generated classes in the way I am not sure we can 
 resolve the issue without really major changes, or we simply say that 
 Groovy 2.x and earlier may not properly work on post jdk 7u40... unless 
 you use indy, where I would still need confirmation there are no frames 
 in the way from that then.
 
 I imagine other languages will have similar problems here and there... 
 or not?
 
 bye Jochen
 
 -- 
 Jochen blackdrag Theodorou - Groovy Project Tech Lead
 blog: http://blackdragsview.blogspot.com/
 german groovy discussion newsgroup: de.comp.lang.misc
 For Groovy programming sources visit http://groovy-lang.org
 
 ___
 mlvm-dev mailing list
 mlvm-dev@openjdk.java.net
 http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: sun.reflect.Reflection.getCallerClass(int) is going to be removed... how to replace?

2013-07-02 Thread Alessio Stalla
On Tue, Jul 2, 2013 at 2:56 PM, Jochen Theodorou blackd...@gmx.org wrote:
 I imagine other languages will have similar problems here and there...
 or not?

Hmm... what are you using that method for? I'm not aware of uses of it
in ABCL, but that may be because we aren't smart enough... ;)
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: sun.reflect.Reflection.getCallerClass(int) is going to be removed... how to replace?

2013-07-02 Thread Jochen Theodorou
Am 02.07.2013 15:10, schrieb Attila Szegedi:
 FWIW, I'm currently working on Dynalink correctly supporting methods
 that are marked with @CallerSensitive; My tests from Nashorn show
 things work as expected, i.e. you can give some permissions to your
 script based on its URL in the security policy, and e.g. invoking
 AccessController.doPrivileged() through INVOKEDYNAMIC works as
 expected; it is actually a pretty big deal getting this to work right
 :-) (doPrivileged, of course, being @CallerSensitive).

I imagine INVOKEDYNAMIC may not have a problem here, if additional 
frames added by it are taken into account as well. But in Groovy we have 
not only invokedynamic and reflection.

bye Jochen


-- 
Jochen blackdrag Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: sun.reflect.Reflection.getCallerClass(int) is going to be removed... how to replace?

2013-07-02 Thread Jochen Theodorou
Am 02.07.2013 15:10, schrieb Alessio Stalla:
 On Tue, Jul 2, 2013 at 2:56 PM, Jochen Theodorou blackd...@gmx.org wrote:
 I imagine other languages will have similar problems here and there...
 or not?

 Hmm... what are you using that method for? I'm not aware of uses of it
 in ABCL, but that may be because we aren't smart enough... ;)

for example... Class.forName(String). Not that I advice people using 
this at any time, but this class gets the caller class, to use its class 
loader, to load a class by name. If your language does not generate a 
direct method call, then the code in forName assumes, that additional 
frame by you is the caller and uses its classloader instead the real 
one. There are many such things, but I don't know if they are relevant 
for ABCL.

bye Jochen

-- 
Jochen blackdrag Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: sun.reflect.Reflection.getCallerClass(int) is going to be removed... how to replace?

2013-07-02 Thread John Rose
On Jul 2, 2013, at 7:00 AM, Jochen Theodorou blackd...@gmx.org wrote:

 for example... Class.forName(String)

That's a good example.

If you call Class.forName via reflection, it will sense its immediate caller, 
which (depending on your system) might be a random frame in your language 
runtime.  This approach gets wrong answers by accident, which sometimes causes 
subtle problems.  When your language runtime has a different privilege level 
than the script, you can get confusion about which privilege level is supposed 
to apply to the requested class name resolution.  This could lead to untimely 
surprises.

If you call Class.forName via a method handle in early versions of JDK 7, 
similar things can happen.  In more recent versions of JSR 292, when you look 
up a method handle that is known to be caller-sensitive, the call to 
Lookup.findStatic (for example) returns a caller-bound version of the method 
handle, which is permanently bound to the lookup class of the lookup object you 
used to find the method handle.  Then, regardless of where that MH gets 
installed or used (in some random MH graph, or directly in an invokedynamic) 
the caller sensitive aspect is always the same.

(Fine print:  This behavior is a corollary of the originally specified nature 
of MHs in terms of their bytecode behavior, since the bytecode behavior of a 
CS method includes the class holding the bytecodes performing the invoke.  Note 
that this does not work for publicLookup, since that guy doesn't possess a 
knowable containing class for his bytecode behaviors.)

The upshot of all this is that if you encapsulate your CS method calls in 
method handles obtained from a BSM or MethodHandles.lookup, your code won't be 
sensitive to the dynamic context of those calls.

On Jul 2, 2013, at 5:56 AM, Jochen Theodorou blackd...@gmx.org wrote:

 A simple example is a Groovy program calling 
 ResourceBundle#getBundle(String)

The same considerations apply to resource bundles also.

Basically, if you use Method.invoke on a caller sensitive method, it may sense 
a random caller.  Use method handles for these cases, if possible.

— John___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


hg: mlvm/mlvm/jdk: meth-info-8008688.patch: fix regression on BigArityTest

2013-07-02 Thread john . r . rose
Changeset: a49289c99587
Author:jrose
Date:  2013-07-02 17:15 -0700
URL:   http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/a49289c99587

meth-info-8008688.patch: fix regression on BigArityTest

! meth-info-8008688.patch

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


hg: mlvm/mlvm/jdk: meth-info-8008688.patch: incorporate review comments

2013-07-02 Thread john . r . rose
Changeset: 5e0f932f8ef0
Author:jrose
Date:  2013-07-02 18:23 -0700
URL:   http://hg.openjdk.java.net/mlvm/mlvm/jdk/rev/5e0f932f8ef0

meth-info-8008688.patch: incorporate review comments

! meth-info-8008688.patch

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: RFR(L): 8008688: Make MethodHandleInfo public

2013-07-02 Thread Christian Thalinger
Couldn't find any obvious problems.  Looks good.

-- Chris

On Jul 2, 2013, at 6:26 PM, John Rose john.r.r...@oracle.com wrote:

 Thanks for the helpful review, Vladimir.
 
 I have incorporated all your comments and updated the webrev here:
 
  http://cr.openjdk.java.net/~jrose/8008688/webrev.05
 
 Detailed replies follow.
 
 On Jul 1, 2013, at 3:36 PM, Vladimir Ivanov vladimir.x.iva...@oracle.com 
 wrote:
 
 John,
 
 I have some minor suggestions about code style and code readability.
 Otherwise, the change looks good!
 
 src/share/classes/java/lang/invoke/MemberName.java:
public MemberName(Method m, boolean wantSpecial) {
 ...
MethodHandleNatives.init(this, m);
 +if (clazz == null) {  // MHN.init failed
 +if (m.getDeclaringClass() == MethodHandle.class 
 +isMethodHandleInvokeName(m.getName())) {
 
 Please, add a comment with a short description why a custom init procedure 
 for MH.invoke* cases is needed.
 
 Done:
// The JVM did not reify this signature-polymorphic instance.
// Need a special case here.
// See comments on MethodHandleNatives.linkMethod.
 
 And I added several paragraphs in the javadoc for linkMethod.
 They cover non-reification, linker methods, appendixes, synthetic, varargs, 
 and more.
 
 +/** Create a name for a signature-polymorphic invoker. */
 +static MemberName makeMethodHandleInvoke(String name, MethodType type) {
 +return makeMethodHandleInvoke(name, type, MH_INVOKE_MODS | 
 SYNTHETIC);
 
 Please, add a comment why SYNTHETIC flag is necessary.
 
/**
 * Create a name for a signature-polymorphic invoker.
 * This is a placeholder for a signature-polymorphic instance
 * (of MH.invokeExact, etc.) that the JVM does not reify.
 * See comments on {@link MethodHandleNatives#linkMethod}.
 */
 
 src/share/classes/java/lang/invoke/MethodHandleInfo.java:
 src/share/classes/java/lang/invoke/MethodHandles.java:
 
 +import java.security.*;
 
 This import isn't used.
 
 Fixed.
 
 src/share/classes/java/lang/invoke/MethodHandles.java:
 
 +public MethodHandleInfo revealDirect(MethodHandle target) {
 ...
 +byte refKind = member.getReferenceKind();
 ...
 +// Check SM permissions and member access before cracking.
 +try {
 +//@@checkSecurityManager(defc, member, lookupClass());
 +checkSecurityManager(defc, member);
 +checkAccess(member.getReferenceKind(), defc, member);
 +} catch (IllegalAccessException ex) {
 +throw new IllegalArgumentException(ex);
 +}
 
 You prepare a separate refKind for MethodHandleInfo, but perform security 
 checks against original member.getReferenceKind(). Is it intentional?
 
 No, it's bug.  Thanks for catching that.
 
 src/share/classes/java/lang/invoke/InfoFromMemberName.java:
 
 81 public T extends Member T reflectAs(ClassT expected, Lookup 
 lookup) {
 82 if (member.isMethodHandleInvoke()  !member.isVarargs()) {
 83 // this member is an instance of a signature-polymorphic 
 method, which cannot be reflected
 84 throw new IllegalArgumentException(cannot reflect signature 
 polymorphic method);
 
 Please, add a comment why (!member.isVarargs()) check is necessary.
 
// This member is an instance of a signature-polymorphic method, 
 which cannot be reflected
// A method handle invoker can come in either of two forms:
// A generic placeholder (present in the source code, and varargs)
// and a signature-polymorphic instance (synthetic and not 
 varargs).
// For more information see comments on {@link 
 MethodHandleNatives#linkMethod}.
 
 
 src/share/classes/java/lang/invoke/InfoFromMemberName.java:
 
 127 private void checkAccess(Member mem, Lookup lookup) throws 
 IllegalAccessException {
 128 byte refKind = (byte) getReferenceKind();
 129 if (mem instanceof Method) {
 130 boolean wantSpecial = (refKind == REF_invokeSpecial);
 131 lookup.checkAccess(refKind, getDeclaringClass(), new 
 MemberName((Method) mem, wantSpecial));
 132 } else if (mem instanceof Constructor) {
 133 lookup.checkAccess(refKind, getDeclaringClass(), new 
 MemberName((Constructor) mem));
 134 } else if (mem instanceof Field) {
 135 boolean isSetter = (refKind == REF_putField || refKind == 
 REF_putStatic);
 136 lookup.checkAccess(refKind, getDeclaringClass(), new 
 MemberName((Field) mem, isSetter));
 137 }
 138 }
 
 Can you introduce a factory method to convert a Member instance into 
 MemberName and call lookup.checkAccess(refKind, getDeclaringClass(), 
 covertToMemberName(mem)) instead? It'll considerably simplify the code and 
 make the intention clearer.
 
 Good idea.  Done.
 
 — John
 
 Best regards,
 Vladimir Ivanov
 
 On 6/27/13