Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-14 Thread Alan Bateman

On 14/12/2016 16:51, Rony G. Flatscher wrote:


Thanks to everyone who commented and/or shed some light about the situation for 
objects that need to
invoke/access protected members in superclasses. The conclusion is, that 
nothing will change as
protected members are still regarded to be public members for subclasses or 
objects of subclasses.
In my case that is fine as I have adhered to allowing access to public members 
(and protected ones
from subclasses or subclass instances) in the Java bridge.

Being in the process of tidying up various development threads in the beta 
version of the bridge
(including adding javax.script/jsr-223 support) of the past two years, I want 
to make sure that the
GA-version scheduled for April will be able to be fully usable with Java 9 that 
will appear
thereafter (currently in July). Therefore I have been lurking around jdk9-dev 
and jigsaw-dev and
reading the informal description
Oracle publish weekly builds [1] of JDK 9 so it might be best to just 
run your tests to see if hit any issues.


-Alan

[1] https://jdk9.java.net/download/


Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-14 Thread Rony G. Flatscher
Thanks to everyone who commented and/or shed some light about the situation for 
objects that need to
invoke/access protected members in superclasses. The conclusion is, that 
nothing will change as
protected members are still regarded to be public members for subclasses or 
objects of subclasses.
In my case that is fine as I have adhered to allowing access to public members 
(and protected ones
from subclasses or subclass instances) in the Java bridge.

Being in the process of tidying up various development threads in the beta 
version of the bridge
(including adding javax.script/jsr-223 support) of the past two years, I want 
to make sure that the
GA-version scheduled for April will be able to be fully usable with Java 9 that 
will appear
thereafter (currently in July). Therefore I have been lurking around jdk9-dev 
and jigsaw-dev and
reading the informal description I was unsure how non-public members get 
treated in this particular
case. Or with other words, there is nothing I have to take into account for 
and/or need to change
because of #AwkwardStrongEncapsulation which is great! :)

Of course, other tooling, JVM languages and other bridges may meet different 
needs and employ
different techniques, so it has also been interesting to see and to learn about 
them and what
changes for them with Java 9, what problems they have to master and what means 
are being explored to
do so. (And BTW it has been very interesting and motivating to see the 
constructive communication
culture in these lists from all involved parties!)

---rony


On 14.12.2016 09:07, Alan Bateman wrote:
>
>
> On 14/12/2016 07:30, Peter Levart wrote:
>> Hi David,
>>
>> On 12/14/2016 07:17 AM, David Holmes wrote:
 But let me explain why .setAccessible(true) can't be allowed for
 protected members in general.
>>>
>>> I'm confused as to what is being argued for/against here. 
>>
>> Rony asked why .setAccessible(true) can't be used for protected members even 
>> if called from a
>> subclass of the member's declaring class.
> Right, I think it would be helpful if Rory could paste in a stack trace from 
> where setAccessible
> is failing so that there are specifics to discuss.
>
> -Alan



Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-14 Thread Alan Bateman

On 14/12/2016 14:30, Jochen Theodorou wrote:


:

I don't intend to get access to hidden API after all... just exported.
If you only interested in accessing the types and members that you have 
access to in these exported packages then you don't need setAccessible 
of course. We have seen a few cases, not many, where code uses 
setAccessible for performance reasons but I don't know if this is what 
you are thinking about here.



Which leaves us with: you want this change and I am unhappy with it. I 
don't see a technical reason for the limit.
Strong encapsulation has always been a goal of this project. If you let 
setAccessible be used to suppress access and get at any member of any 
type then it makes a mockery of that. The initial attempt at a 
compromise in 2015 was to have it fail when attempting to break into any 
member of any type in non-exported packages. That is what has been in 
JDK 9 for some time. The problem with this compromise is that it makes 
it impossible to encapsulate the internal implementation that is in 
exported package - if you read the JSR issue then you'll see the example 
of code breaking into java.lang.invoke.MethodHandles.Lookup to get at 
its private constructor and using that to create full power lookups with 
a lookup classes in non-exported packages. You'll also see the 
unworkable concern that module authors will be forced to move all their 
internals to non-exported packages. This is what 
#AwkwardStrongEncapsulation is about.  Hopefully it's a bit clearer now.


-Alan


Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-14 Thread Jochen Theodorou



On 13.12.2016 23:17, Peter Levart wrote:
[...]

You might have access to a protected method, but you can not delegate
that access to a 3rd party unless you make the Method object
.setAccessible(true) and pass it to the 3rd party as a capability. (I
recommend using MethodHandle(s) for such delegation of rights instead of
reflection though).


that is unlikely to happen


But let me explain why .setAccessible(true) can't be allowed for
protected members in general.

Jigsaw establishes strong encapsulation. What that means is that even
without a SecurityManager present, code should not be allowed to gain
access to a member beyond what is allowed by accessibility rules of Java
language unless that member is in a class in an open package or such
access is willingly delegated to code by some other code.


I am aware of this. For me it is more a question of how far strong 
encapsulation is supposed to go and you can understand strong 
encapsulation in a module system in different ways as well.


I don't intend to get access to hidden API after all... just exported.

[...]

You can't perform the access check for a protected
instance member without knowing the 'targetClass' (the runtime class of
the target instance).


sure, I already commented on this part with: why do access checks for 
this at all? Your answer is because of strong encapsulation and my 
comment for that is that you guys are maybe overdoing it a bit. Which 
leaves us with: you want this change and I am unhappy with it. I don't 
see a technical reason for the limit.


bye Jochen


Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-14 Thread David Holmes

On 14/12/2016 8:15 PM, Alan Bateman wrote:

On 14/12/2016 09:56, David Holmes wrote:



Sorry I don't follow. Calling setAccessible(true), logically does
nothing except set a flag that controls whether reflective use of the
member will need to pass an access check -it doesn't (or shouldn't)
perform the access check!

Best to read the javadoc as this changed to align with modules. When
reading the javadoc then keep in mind that the JDK modules do not open
their packages for deep reflection.


Yes - thanks Alan. I've only just noticed that setAccessible has been 
updated to check the accessibility and throw an exception! That came as 
a surprise. It doesn't have all the info needed to make the decision in 
all cases.


David
-


The actual use then has the full access check. Due to the added
complication of module encapsulation we can't simply skip the access
check if setAccessible is true, because we also need to see if the
target module is "open" in the right way.

If setAccessible(true) succeeds then it means access checks are
suppressed when using that AccessibleObject is used. There are no
changes here. Having setAccessible(true) succeed but still do an access
check when using the AccessibleObject would be too significant a change
in behavior.




If the current implementation is trying to cache the result of the
accessibility check at setAccessible time then that would seem an
invalid attempt at optimisation. java.lang.reflect objects are not,
AFAIK, intended to be capabilities the way MethodHandles are.

I don't see an issue here as it is not used when the accessible flag has
been set with setAccessible(true).



BTW in this discussion when setAccessible says that it is "suppressing
default Java language access control checks" are the module related
checks considered "language access control checks" or are they
considered something outside the language?

The former.

-Alan


Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-14 Thread Alan Bateman

On 14/12/2016 09:56, David Holmes wrote:



Sorry I don't follow. Calling setAccessible(true), logically does 
nothing except set a flag that controls whether reflective use of the 
member will need to pass an access check -it doesn't (or shouldn't) 
perform the access check!
Best to read the javadoc as this changed to align with modules. When 
reading the javadoc then keep in mind that the JDK modules do not open 
their packages for deep reflection.


The actual use then has the full access check. Due to the added 
complication of module encapsulation we can't simply skip the access 
check if setAccessible is true, because we also need to see if the 
target module is "open" in the right way.
If setAccessible(true) succeeds then it means access checks are 
suppressed when using that AccessibleObject is used. There are no 
changes here. Having setAccessible(true) succeed but still do an access 
check when using the AccessibleObject would be too significant a change 
in behavior.





If the current implementation is trying to cache the result of the 
accessibility check at setAccessible time then that would seem an 
invalid attempt at optimisation. java.lang.reflect objects are not, 
AFAIK, intended to be capabilities the way MethodHandles are.
I don't see an issue here as it is not used when the accessible flag has 
been set with setAccessible(true).




BTW in this discussion when setAccessible says that it is "suppressing 
default Java language access control checks" are the module related 
checks considered "language access control checks" or are they 
considered something outside the language?

The former.

-Alan


Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-14 Thread Alan Bateman



On 14/12/2016 07:30, Peter Levart wrote:

Hi David,

On 12/14/2016 07:17 AM, David Holmes wrote:

But let me explain why .setAccessible(true) can't be allowed for
protected members in general.


I'm confused as to what is being argued for/against here. 


Rony asked why .setAccessible(true) can't be used for protected 
members even if called from a subclass of the member's declaring class.
Right, I think it would be helpful if Rory could paste in a stack trace 
from where setAccessible is failing so that there are specifics to discuss.


-Alan


Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-13 Thread Peter Levart

Hi David,

On 12/14/2016 07:17 AM, David Holmes wrote:

But let me explain why .setAccessible(true) can't be allowed for
protected members in general.


I'm confused as to what is being argued for/against here. 


Rony asked why .setAccessible(true) can't be used for protected members 
even if called from a subclass of the member's declaring class.


setAccessible(true) simply says to disable access checks when the 
member is used. At the time of use you have all the necessary 
information available:

- current class
- member defining class
- receiver class (target class??) 


At the time of use (when the member is reflectively accessed), you have 
that information, but that information is not used when the access 
checks have been suppressed by .setAccessible(true). When the 
.setAccessible() is called OTOH, you don't have the target (receiver) 
object, so you can't allow .setAccessible() to succeed for protected 
instance member if you want to respect strong encapsulation as this 
would allow elevation of access privilege. You only allow elevation if 
the member's declaring class is in an open package (or in unnamed module).


...

/**
 * Verify access to a member, returning {@code false} if no access
 */
public static boolean verifyMemberAccess(Class currentClass,
 Class memberClass,
 Class targetClass,
 int modifiers)
{


Where does this method exist? 


In jdk.internal.reflect.Reflection.


Regards, Peter



Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-13 Thread David Holmes

On 14/12/2016 8:17 AM, Peter Levart wrote:

Hi Jochen,


On 12/13/2016 06:32 PM, Jochen Theodorou wrote:



On 12.12.2016 20:56, Alex Buckley wrote:
[...]

The ability of protected members to be accessed from outside their
package means they are essentially public members for the purposes of
inheritance and reflection. So, setAccessible should work for protected
members of exported packages. I know what you mean about the receiver
object being of the correct class, but that's outside the capability of
setAccessible to check, so I don't believe it is checked.


why does it have to be checked? why not just allow it? I mean that is
why I use setAccessible in the first place. I have much less use of
making something accessible for which I already have access rights

bye Jochen


You might have access to a protected method, but you can not delegate
that access to a 3rd party unless you make the Method object
.setAccessible(true) and pass it to the 3rd party as a capability. (I
recommend using MethodHandle(s) for such delegation of rights instead of
reflection though).

But let me explain why .setAccessible(true) can't be allowed for
protected members in general.


I'm confused as to what is being argued for/against here. 
setAccessible(true) simply says to disable access checks when the member 
is used. At the time of use you have all the necessary information 
available:

- current class
- member defining class
- receiver class (target class??)


Jigsaw establishes strong encapsulation. What that means is that even
without a SecurityManager present, code should not be allowed to gain
access to a member beyond what is allowed by accessibility rules of Java
language unless that member is in a class in an open package or such
access is willingly delegated to code by some other code. For core
reflection that means the following check is performed each time a
reflective access is performed:

/**
 * Verify access to a member, returning {@code false} if no access
 */
public static boolean verifyMemberAccess(Class currentClass,
 Class memberClass,
 Class targetClass,
 int modifiers)
{


Where does this method exist?

Thanks,
David
-



// Verify that currentClass can access a field, method, or
// constructor of memberClass, where that member's access bits are
// "modifiers".

boolean gotIsSameClassPackage = false;
boolean isSameClassPackage = false;

if (currentClass == memberClass) {
// Always succeeds
return true;
}

if (!verifyModuleAccess(currentClass, memberClass)) {
return false;
}

if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
isSameClassPackage = isSameClassPackage(currentClass,
memberClass);
gotIsSameClassPackage = true;
if (!isSameClassPackage) {
return false;
}
}

// At this point we know that currentClass can access memberClass.

if (Modifier.isPublic(modifiers)) {
return true;
}

boolean successSoFar = false;

if (Modifier.isProtected(modifiers)) {
// See if currentClass is a subclass of memberClass
if (isSubclassOf(currentClass, memberClass)) {
successSoFar = true;
}
}

if (!successSoFar && !Modifier.isPrivate(modifiers)) {
if (!gotIsSameClassPackage) {
isSameClassPackage = isSameClassPackage(currentClass,
memberClass);
gotIsSameClassPackage = true;
}

if (isSameClassPackage) {
successSoFar = true;
}
}

if (!successSoFar) {
return false;
}

// Additional test for protected instance members
// and protected constructors: JLS 6.6.2
if (targetClass != null && Modifier.isProtected(modifiers) &&
targetClass != currentClass)
{
if (!gotIsSameClassPackage) {
isSameClassPackage = isSameClassPackage(currentClass,
memberClass);
gotIsSameClassPackage = true;
}
if (!isSameClassPackage) {
if (!isSubclassOf(targetClass, currentClass)) {
return false;
}
}
}

return true;
}


The interesting part is at the end - the additional test for protected
instance members. You can't perform the access check for a protected
instance member without knowing the 'targetClass' (the runtime class of
the target instance). The protected member must be declared by the same
class (memberClass) or a superclass of the class from where you are
accessing it (currentClass), but to allow access to the protected
instance member, the runtime class of the 

Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-13 Thread Peter Levart

Hi Jochen,


On 12/13/2016 06:32 PM, Jochen Theodorou wrote:



On 12.12.2016 20:56, Alex Buckley wrote:
[...]

The ability of protected members to be accessed from outside their
package means they are essentially public members for the purposes of
inheritance and reflection. So, setAccessible should work for protected
members of exported packages. I know what you mean about the receiver
object being of the correct class, but that's outside the capability of
setAccessible to check, so I don't believe it is checked.


why does it have to be checked? why not just allow it? I mean that is 
why I use setAccessible in the first place. I have much less use of 
making something accessible for which I already have access rights


bye Jochen


You might have access to a protected method, but you can not delegate 
that access to a 3rd party unless you make the Method object 
.setAccessible(true) and pass it to the 3rd party as a capability. (I 
recommend using MethodHandle(s) for such delegation of rights instead of 
reflection though).


But let me explain why .setAccessible(true) can't be allowed for 
protected members in general.


Jigsaw establishes strong encapsulation. What that means is that even 
without a SecurityManager present, code should not be allowed to gain 
access to a member beyond what is allowed by accessibility rules of Java 
language unless that member is in a class in an open package or such 
access is willingly delegated to code by some other code. For core 
reflection that means the following check is performed each time a 
reflective access is performed:


/**
 * Verify access to a member, returning {@code false} if no access
 */
public static boolean verifyMemberAccess(Class currentClass,
 Class memberClass,
 Class targetClass,
 int modifiers)
{
// Verify that currentClass can access a field, method, or
// constructor of memberClass, where that member's access bits are
// "modifiers".

boolean gotIsSameClassPackage = false;
boolean isSameClassPackage = false;

if (currentClass == memberClass) {
// Always succeeds
return true;
}

if (!verifyModuleAccess(currentClass, memberClass)) {
return false;
}

if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
isSameClassPackage = isSameClassPackage(currentClass, 
memberClass);

gotIsSameClassPackage = true;
if (!isSameClassPackage) {
return false;
}
}

// At this point we know that currentClass can access memberClass.

if (Modifier.isPublic(modifiers)) {
return true;
}

boolean successSoFar = false;

if (Modifier.isProtected(modifiers)) {
// See if currentClass is a subclass of memberClass
if (isSubclassOf(currentClass, memberClass)) {
successSoFar = true;
}
}

if (!successSoFar && !Modifier.isPrivate(modifiers)) {
if (!gotIsSameClassPackage) {
isSameClassPackage = isSameClassPackage(currentClass,
memberClass);
gotIsSameClassPackage = true;
}

if (isSameClassPackage) {
successSoFar = true;
}
}

if (!successSoFar) {
return false;
}

// Additional test for protected instance members
// and protected constructors: JLS 6.6.2
if (targetClass != null && Modifier.isProtected(modifiers) &&
targetClass != currentClass)
{
if (!gotIsSameClassPackage) {
isSameClassPackage = isSameClassPackage(currentClass, 
memberClass);

gotIsSameClassPackage = true;
}
if (!isSameClassPackage) {
if (!isSubclassOf(targetClass, currentClass)) {
return false;
}
}
}

return true;
}


The interesting part is at the end - the additional test for protected 
instance members. You can't perform the access check for a protected 
instance member without knowing the 'targetClass' (the runtime class of 
the target instance). The protected member must be declared by the same 
class (memberClass) or a superclass of the class from where you are 
accessing it (currentClass), but to allow access to the protected 
instance member, the runtime class of the target instance (targetClass) 
must also be the same as or a subclass of the class from where you are 
accessing the member (currentClass).


You don't know in advance what target instance will be used when 
deciding whether to allow .setAccessible(true) for an instance member.


Regards, Peter



Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-13 Thread Peter Levart

Hi Rony,


On 12/13/2016 07:07 PM, Rony G. Flatscher wrote:

To make a long story short: I have always adhered to the Java rules for the 
Rexx users, in that they
are only allowed to access public Java classes, public fields and public methods 
("there must be a
reason why the Java language has defined these rules":)  ). The exception are 
protected members of a
Java class that are accessed via instances of subclasses (maybe even created 
for ooRexx on the fly
at runtime) in order to adhere to the Java model as close as possible. So the 
classic Java
reflection (BSF4Rexx the initial Rexx-Java bridge worked even with Java 1.1.8, 
sic!, on OS/2)
mechanism is really at the heart of this implementation, hence the question.



You still haven't explained in detail why you have to invoke 
.setAccessible(true) on a Method object to invoke a protected method 
from a subclass. This should not be needed.


Regards, Peter



Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-13 Thread Rony G. Flatscher
On 13.12.2016 16:56, Alan Bateman wrote:
> On 13/12/2016 15:47, Rony G. Flatscher wrote:
>
>> :
>>
>> So the current code does not take protected members into account. If 
>> protected members (cf. Alex'
>> comment)  get added, wouldn't e.g. java.lang.reflect.Method.invoke(...)  or
>> java.lang.reflect.Field.get(...) be the place to check in the next step, 
>> throwing an
>> IllegalAccessException if the object is not instantiated from a subclass of 
>> the class the protected
>> method to invoke or protected Field to get is defined?
>>
> If you mean you are asking for setAccessible(true) to succeed but still do 
> the access check then
> it will cause a lot of complications.
>
> So I'm curious, are you calling setAccessible on protected members that you 
> do have access or not?
> If you do have access (you are in the same package or a sub-type) then you 
> don't need to call
> setAccessible. On the other hand, if you are looking to use the 
> AccessibleObject to get into a
> different subtype then you are out of luck, the package needs to be open to 
> you to do that.
The reason for the question is a language binding (to IBM's Object Rexx in the 
open-sourced form
called open Object Rexx, ooRexx, and heavily improved since in the hands of the 
Rexx Language
Assocation, www.rexxla.org) to Java that I have created 2000 (yup, quite some 
time) using Apache's
Bean scripting framework BSF (rooted in another open-source project at IBM) and 
have constantly
improved since then. The ooRexx Java bridge is available for Windows, Linux and 
MacOSX.

ooRexx is an interpreted language implemented in C++, the bridge to Java is 
realized via JNI and a
Java framework. It allows proxying Java objects with Rexx objects (no strong 
typing, caseless, quite
a few Smalltalk concepts, sending ooRexx messages cause the appropriate Java 
classes, members to be
looked up, methods to be invoked on behalf of the Rexx program), and proxying 
Rexx objects with Java
objects (causing Java method invocations to result in sending appropriate Rexx 
messages to the
proxied Rexx objects), including the ability to implement Java interface or 
abstract classes in
ooRexx (i.e. implement the abstract methods with ooRexx methods). The fact that 
ooRexx is based on
classic Rexx carrying forward the Rexx philosophy of "human-centricness" in its 
design makes it an
easy to learn language, yet a powerful one, which allows me at a Business 
Administration University
to teach oo-programming from zero knowledge to becoming able to interact and 
exploit Windows-OLE, C#
and then Java within one (sic!) semester with a four hour class. The Java 
support is intentionally
used to teach and demonstrate that it is rather easy to create applications, 
that do not lock-in
businesses into specific operating systems. ooRexx "surfing Java" allows one to 
do the same thing:
create applications that are open on all major operating system platforms by 
virtue of exploiting
Java under the covers.

To make a long story short: I have always adhered to the Java rules for the 
Rexx users, in that they
are only allowed to access public Java classes, public fields and public 
methods ("there must be a
reason why the Java language has defined these rules" :) ). The exception are 
protected members of a
Java class that are accessed via instances of subclasses (maybe even created 
for ooRexx on the fly
at runtime) in order to adhere to the Java model as close as possible. So the 
classic Java
reflection (BSF4Rexx the initial Rexx-Java bridge worked even with Java 1.1.8, 
sic!, on OS/2)
mechanism is really at the heart of this implementation, hence the question.

---rony

P.S.: Even if it is the first time you might have heard of Rexx/ooRexx do not 
mistake that with
Rexx/ooRexx not being deployed in quite a few large shops on quite a large 
scale in addition. For me
a great value lies in ooRexx easy syntax that allows me to teach it and the oo 
concepts faster than
in any other programming language that I have experimented with in the past 25 
years with Business
Administration students.



Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-13 Thread Jochen Theodorou



On 12.12.2016 20:56, Alex Buckley wrote:
[...]

The ability of protected members to be accessed from outside their
package means they are essentially public members for the purposes of
inheritance and reflection. So, setAccessible should work for protected
members of exported packages. I know what you mean about the receiver
object being of the correct class, but that's outside the capability of
setAccessible to check, so I don't believe it is checked.


why does it have to be checked? why not just allow it? I mean that is 
why I use setAccessible in the first place. I have much less use of 
making something accessible for which I already have access rights


bye Jochen


Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-13 Thread Alan Bateman

On 13/12/2016 15:47, Rony G. Flatscher wrote:


:

So the current code does not take protected members into account. If protected 
members (cf. Alex'
comment)  get added, wouldn't e.g. java.lang.reflect.Method.invoke(...)  or
java.lang.reflect.Field.get(...) be the place to check in the next step, 
throwing an
IllegalAccessException if the object is not instantiated from a subclass of the 
class the protected
method to invoke or protected Field to get is defined?

If you mean you are asking for setAccessible(true) to succeed but still 
do the access check then it will cause a lot of complications.


So I'm curious, are you calling setAccessible on protected members that 
you do have access or not? If you do have access (you are in the same 
package or a sub-type) then you don't need to call setAccessible. On the 
other hand, if you are looking to use the AccessibleObject to get into a 
different subtype then you are out of luck, the package needs to be open 
to you to do that.


-Alan


Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-13 Thread Rony G. Flatscher


On 12.12.2016 22:42, Peter Levart wrote:
>
>
> On 12/12/2016 08:56 PM, Alex Buckley wrote:
>> On 12/11/2016 8:16 AM, Rony G. Flatscher wrote:
>>> On 23.11.2016 12:55, Alan Bateman wrote:
 As people on this mailing list know, jake has the changes for 
 #AwkwardStrongEncapsulation [1]
 where setAccessible has been changed so it can't be used to break into 
 non-public members/types in
 exported packages of JDK modules. It was changed more than a year ago to 
 fail when attempting to
 use it to break into non-exported packages. Dialing it up further is a 
 disruptive change that will
 expose a lot of hacks and issues with existing code that is used to 
 accessing non-public
 fields/methods in JDK classes. It will take some libraries and tools a bit 
 of time to digest this
 change, even with the --add-opens command line option and Add-Opens 
 manifest in application JAR
 files to keep existing code going. I plan to send mail to jdk9-dev in 
 advance of this integration
 to create wider awareness of this change.

 -Alan

 [1] 
 http://openjdk.java.net/projects/jigsaw/spec/issues/#AwkwardStrongEncapsulation
>>> Would #AwkwardStrongEncapsulation inhibit setAccessible to work on 
>>> protected methods (in
>>> addition to
>>> private and package private members) as well?
>>>
>>> As subclasses are allowed to access protected members in their 
>>> superclasses, setAccessible should
>>> work for protected methods in classes that are invoked for objects that are 
>>> instances of their
>>> subclasses?
>>
>> The ability of protected members to be accessed from outside their package 
>> means they are
>> essentially public members for the purposes of inheritance and reflection. 
>> So, setAccessible
>> should work for protected members of exported packages. I know what you mean 
>> about the receiver
>> object being of the correct class, but that's outside the capability of 
>> setAccessible to check,
>> so I don't believe it is checked.
>>
>> Alex
>
> That's right, currently setAccessible is allowed only within a module, for 
> any members of any
> classes in unnamed module(s), for public members of public classes in 
> exported packages of named
> module(s) and for any members of any classes of open packages. Here's the 
> actual code used to
> check the ability to make a member setAccessible(true):
>
> void checkCanSetAccessible(Class caller, Class declaringClass) {
> Module callerModule = caller.getModule();
> Module declaringModule = declaringClass.getModule();
>
> if (callerModule == declaringModule) return;
> if (callerModule == Object.class.getModule()) return;
> if (!declaringModule.isNamed()) return;
>
> // package is open to caller
> String pn = packageName(declaringClass);
> if (declaringModule.isOpen(pn, callerModule))
> return;
>
> // package is exported to caller and class/member is public
> boolean isExported = declaringModule.isExported(pn, callerModule);
> boolean isClassPublic = 
> Modifier.isPublic(declaringClass.getModifiers());
> int modifiers;
> if (this instanceof Executable) {
> modifiers = ((Executable) this).getModifiers();
> } else {
> modifiers = ((Field) this).getModifiers();
> }
> boolean isMemberPublic = Modifier.isPublic(modifiers);
> if (isExported && isClassPublic && isMemberPublic)
> return;
>
> // not accessible
> String msg = "Unable to make ";
> if (this instanceof Field)
> msg += "field ";
> msg += this + " accessible: " + declaringModule + " does not \"";
> if (isClassPublic && isMemberPublic)
> msg += "exports";
> else
> msg += "opens";
> msg += " " + pn + "\" to " + callerModule;
> Reflection.throwInaccessibleObjectException(msg);
> }
>
>
> This could be relaxed a bit for protected static fields/methods and for 
> protected constructors,
> but can't be for instance members, because there is no target object to check 
> against when
> setAccessible() is called...
So the current code does not take protected members into account. If protected 
members (cf. Alex'
comment)  get added, wouldn't e.g. java.lang.reflect.Method.invoke(...)  or
java.lang.reflect.Field.get(...) be the place to check in the next step, 
throwing an
IllegalAccessException if the object is not instantiated from a subclass of the 
class the protected
method to invoke or protected Field to get is defined?

---rony





Re: Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-12 Thread Alex Buckley

On 12/11/2016 8:16 AM, Rony G. Flatscher wrote:

On 23.11.2016 12:55, Alan Bateman wrote:

As people on this mailing list know, jake has the changes for 
#AwkwardStrongEncapsulation [1]
where setAccessible has been changed so it can't be used to break into 
non-public members/types in
exported packages of JDK modules. It was changed more than a year ago to fail 
when attempting to
use it to break into non-exported packages. Dialing it up further is a 
disruptive change that will
expose a lot of hacks and issues with existing code that is used to accessing 
non-public
fields/methods in JDK classes. It will take some libraries and tools a bit of 
time to digest this
change, even with the --add-opens command line option and Add-Opens manifest in 
application JAR
files to keep existing code going. I plan to send mail to jdk9-dev in advance 
of this integration
to create wider awareness of this change.

-Alan

[1] 
http://openjdk.java.net/projects/jigsaw/spec/issues/#AwkwardStrongEncapsulation

Would #AwkwardStrongEncapsulation inhibit setAccessible to work on protected 
methods (in addition to
private and package private members) as well?

As subclasses are allowed to access protected members in their superclasses, 
setAccessible should
work for protected methods in classes that are invoked for objects that are 
instances of their
subclasses?


The ability of protected members to be accessed from outside their 
package means they are essentially public members for the purposes of 
inheritance and reflection. So, setAccessible should work for protected 
members of exported packages. I know what you mean about the receiver 
object being of the correct class, but that's outside the capability of 
setAccessible to check, so I don't believe it is checked.


Alex


Question ad #AwkwardStrongEncapsulation (Re: Moving the changes in jake to jdk9/dev

2016-12-11 Thread Rony G. Flatscher
On 23.11.2016 12:55, Alan Bateman wrote:
>
> We've been accumulating changes in the jake forest that are tied to JSR 
> issues for the last few
> months. Some of the changes (such as #ClassLoaderNames) have already been 
> pushed upstream to
> jdk9/dev but we've still sitting on a large patch.
>
> We would like to move the changes that we have in jake to jdk9/dev soon, 
> early December if
> possible. One motivation is to get the changes and new APIs into JDK 9 main 
> line so that they can
> be used and tested more widely. This should help reduce some of the confusion 
> with having two
> builds too. Another motivation is that the merging is getting painful, esp. 
> the langtools
> repository where we have regular conflicts with changes to javac pushed via 
> jdk9/dev.
>
> To that end, I will start a code review soon that will be a snapshot of the 
> changes in the jake
> forest. Once these changes are reviewed and in jdk9/dev then we will continue 
> in the jake forest
> where appropriate - particularly in areas that are tied to JSR issues where 
> we need to iterate and
> prototype, also in areas where we need to re-work some areas of the 
> implementation.
>
> As people on this mailing list know, jake has the changes for 
> #AwkwardStrongEncapsulation [1]
> where setAccessible has been changed so it can't be used to break into 
> non-public members/types in
> exported packages of JDK modules. It was changed more than a year ago to fail 
> when attempting to
> use it to break into non-exported packages. Dialing it up further is a 
> disruptive change that will
> expose a lot of hacks and issues with existing code that is used to accessing 
> non-public
> fields/methods in JDK classes. It will take some libraries and tools a bit of 
> time to digest this
> change, even with the --add-opens command line option and Add-Opens manifest 
> in application JAR
> files to keep existing code going. I plan to send mail to jdk9-dev in advance 
> of this integration
> to create wider awareness of this change.
>
> -Alan
>
> [1] 
> http://openjdk.java.net/projects/jigsaw/spec/issues/#AwkwardStrongEncapsulation
Would #AwkwardStrongEncapsulation inhibit setAccessible to work on protected 
methods (in addition to
private and package private members) as well?

As subclasses are allowed to access protected members in their superclasses, 
setAccessible should
work for protected methods in classes that are invoked for objects that are 
instances of their
subclasses?

---rony