Having the proxy class be public in most circumstances is a 15-plus-year-old contract. You can't justify breaking it out of the blue by saying "well it's deprecated now". Deprecating this method is fine, but you can't break it at the same time. There are two problems here, and they're both Jigsaw problems.

The first problem is that a magic dynamic module is created for proxy classes. This is a bit of a punt because of the natural dissonance/chaos that arises from decoupling the module from the class loader; however there's possibly a better way to mitigate this: let the layer decide how to place the proxy class into a *real* module the same way that in the past, the proxy class was placed into the real class loader as a normal (usually public) class.

The second problem is that the requirement for adding read edges all over the place for reflection is unreasonable (and has already been recognized as such by the EG). I'd argue that this should be completely generalized: read edges as a whole are not a good solution to the encapsulation problem; the "friend" package approach which has been proposed by myself and others has many clear advantages, not the least of which is to guarantee that "public" means "public" in all circumstances, and that encapsulation enforcement can be done by the JVM by the classic team of the bytecode verifier and the linker, which do this job well today for all non-public relationships. Fixing this problem not only means that the first problem essentially goes away (because public is public no matter what module it's in), but also that more powerful proxy classes could be constructed which have access to multiple non-public package classes, using the more elegant security mechanism.

On 04/07/2016 08:29 AM, Remi Forax wrote:
The problem is that RestEasy is using getProxyClass() which is deprecated in 9.

RestEasy want to do a call to Constructor.newInstance on a constructor of the 
proxy class,
and as Stephane said, RestEasy (which is in the unamed module in your case) do 
not have access to the proxy class which is in a dynamic module

quote from the javadoc of j.l.r.Proxy
"
Dynamic Modules

A dynamic module is a named module generated at runtime. A proxy class defined 
in a dynamic module is encapsulated and not accessible to any module. Calling 
Constructor.newInstance(Object...) on a proxy class in a dynamic module will 
throw IllegalAccessException; Proxy.newProxyInstance method should be used 
instead.
"

so the solution is easier to add a read edge in the code of RestEasy as 
Stephane said or to change the code of RestEasy to use newProxyInstance() 
instead.

regards,
Rémi

----- Mail original -----
De: "Stephane Epardaud" <s...@epardaud.fr>
À: jigsaw-dev@openjdk.java.net
Envoyé: Jeudi 7 Avril 2016 15:02:28
Objet: Re: Proxy classes and reflection (IllegalAccessException)

No, you have to add a read to the module of the class you're proxying,
not com.sun.proxy. That'd be your application's module.

On 07/04/16 14:25, Neil Bartlett wrote:
Stephane, I don’t think that would help since the package is not exported:
"module jdk.proxy2 does not export com.sun.proxy.jdk.proxy2”.

Regards,
Neil

On 7 Apr 2016, at 13:13, Stephane Epardaud <s...@epardaud.fr> wrote:

IIRC RestEasy needs to add a module read to that Class's module it wants
to create a Proxy of.

On 07/04/16 14:05, Alan Bateman wrote:
On 07/04/2016 12:39, Dawid Weiss wrote:
I don't want to hijack the other thread, so here's a new one I'm stuck
with. I get this exception (simplified stack trace a bit):

Caused by: java.lang.IllegalAccessException: class
org.jboss.resteasy.core.ContextParameterInjector cannot access class
com.sun.proxy.jdk.proxy2.$Proxy65 (in module jdk.proxy2) because
module jdk.proxy2 does not export com.sun.proxy.jdk.proxy2 to unnamed
module @79ca92b9
at
sun.reflect.Reflection.throwIllegalAccessException(java.base@9-ea/Reflection.java:411)
at
sun.reflect.Reflection.throwIllegalAccessException(java.base@9-ea/Reflection.java:402)
at
sun.reflect.Reflection.ensureMemberAccess(java.base@9-ea/Reflection.java:99)
at
java.lang.reflect.AccessibleObject.slowCheckMemberAccess(java.base@9-ea/AccessibleObject.java:355)
at
java.lang.reflect.AccessibleObject.checkAccess(java.base@9-ea/AccessibleObject.java:347)
at
java.lang.reflect.Constructor.newInstance(java.base@9-ea/Constructor.java:444)
at
org.jboss.resteasy.core.ContextParameterInjector.createProxy(ContextParameterInjector.java:94)
... 53 more

I think RestEasy attempts to do create a new instance of a proxy class
here (the complete process here eludes my understanding for now). Any
clues how this can be solved?
I assume it should be using newProxyInstance rather that trying to
instantiate the proxy class directly. The reason it can't instantiate it
directly is because it has been generated into a "dynamic module"
(jdk.proxy2 in this case). I assume you'll find that the proxy was
created with an interface that is not in an exported package.

The "Package and Module Membership of Proxy Class" and "Dynamic Modules"
sections of the Proxy javadoc [1] has all the details.

-Alan.

[1]
http://download.java.net/java/jdk9/docs/api/java/lang/reflect/Proxy.html





--
- DML

Reply via email to