Proposal: #ReflectiveAccessToNonExportedTypes: `exports dynamic`
Rafael Winterhalter
rafael.wth at gmail.com
Wed Jun 29 23:23:55 UTC 2016
I also agree here that the use of reflection should not require any form of
explicit permission by the user of a library. In a way, this ties an
implementation detail (reflection in this case) to the usage of the
library. The library cannot work without the explicit configuration by a
user and this only adds boilerplate to using Hibernate.
Unfortunately, many Java developers still do not know much about reflection
or about the inner workings of many libraries in the market. If a user
needed to explicitly export packages, this might just lead to people "over
exporting" their packages just to "make Hibernate work".
In my opinion, reflection should not apply any module-boundary checks.
Best regards, Rafael
2016-06-29 20:13 GMT+02:00 Paul Benedict <pbenedict at apache.org>:
> Replying to "observers" list...
>
> I think the main problem here is that core reflection has become too
> restrictive. Reflection should be "magical" and have no knowledge of any
> kind of module and/or visibility boundaries. If you really want to control
> what can be reflected upon, that should be done via the Policy file of the
> Security Manager.
>
> This proposal is trying to hack out-of-the-box created by too strict of a
> design. It is very awkward to denote which packages must be reflectable
> ahead of time --- how can you figure that out?? The consumers who are doing
> the reflection are innumerable. I'd go as far to say it's it's impossible
> to devise a preemptive comprehensive strategy that may satisfy the kinds of
> tooling in the wild.
>
> It's best just to open up reflection so it can continue doing what it
> always has done well: let me see anything I want unless the Security
> Manager says no.
>
> Cheers,
> Paul
>
> On Wed, Jun 29, 2016 at 3:51 AM, Remi Forax <forax at univ-mlv.fr> wrote:
>
> >
> >
> > ----- Mail original -----
> > > De: "Mark Reinhold" <mark.reinhold at oracle.com>
> > > À: jpms-spec-experts at openjdk.java.net
> > > Envoyé: Mardi 28 Juin 2016 23:18:15
> > > Objet: Proposal: #ReflectiveAccessToNonExportedTypes: `exports dynamic`
> > >
> > > Issue summary
> > > -------------
> > >
> > > #ReflectiveAccessToNonExportedTypes --- Some kinds of framework
> > > libraries require reflective access to members of the non-exported
> > > types of other modules; examples include dependency injection
> (Guice),
> > > persistence (JPA), debugging tools, code-automation tools, and
> > > serialization (XStream). In some cases the particular library to be
> > > used is not known until run time (e.g., Hibernate and EclipseLink
> both
> > > implement JPA). This capability is also sometimes used to work
> around
> > > bugs in unchangeable code. Access to non-exported packages can, at
> > > present, only be done via command-line flags, which is extremely
> > > awkward. Provide an easier way for reflective code to access such
> > > non-exported types. [1]
> > >
> > > Proposal
> > > --------
> > >
> > > Extend the language of module declarations so that a package can be
> > > declared to be exported at run time but not at compile time. This is,
> > > roughly, the dual of the `requires static` construct proposed for
> > > #CompileTimeDependences, hence we propose to introduce a new modifier,
> > > `dynamic`, for use on the `exports` directive. It has the following
> > > meanings:
> > >
> > > - At compile time, `exports dynamic P` does not cause the package `P`
> > > to be exported, though it does require `P` to be a package defined
> > > in the module.
> > >
> > > - In phases after compile time, `exports dynamic P` behaves in
> exactly
> > > the same way as `exports P`. It therefore takes part fully in
> > > resolution and configuration, and is subject to the same
> consistency
> > > constraints as normally-exported packages (e.g., no split
> packages).
> > >
> > > Thus a module declaration of the form
> > >
> > > module com.foo.app {
> > > requires hibernate.core;
> > > requires hibernate.entitymanager;
> > > exports dynamic com.foo.app.model;
> > > }
> > >
> > > makes the types in the `com.foo.app.model` package accessible at run
> time
> > > but not at compile time. In combination with the earlier change to
> > > enable #ReflectionWithoutReadability [2] this means that frameworks
> that
> > > today use core reflection to manipulate user classes at run time are
> more
> > > likely to work out-of-the-box, without change, as automatic modules.
> If
> > > the `com.foo.app.model` package in this example includes entity classes
> > > to be managed by Hibernate then the framework will be able to access
> them
> > > without further ado, but under normal circumstances an attempt to
> compile
> > > code that refers directly to those classes will fail.
> > >
> > > The `dynamic` modifier can be applied to both unqualified and qualified
> > > `exports` directives, though the caveats on using qualified exports [3]
> > > still apply.
> > >
> > > Notes
> > > -----
> > >
> > > - To access a non-public member in a dynamically-exported package you
> > > must still invoke the appropriate `setAccessible` method, just as
> > > you do today to access non-public members in an exported package.
> > >
> > > - This proposal is similar to Rémi's suggestion to add a way to
> export
> > > a package only for reflection, still requiring that `setAccessible`
> > > be invoked [4]. This proposal differs in that it does not require
> > > `setAccessible` to be invoked to access public members in a
> > > dynamically-exported package.
> > >
> > > - This proposal primarily addresses "friendly" uses of reflection,
> such
> > > as dependency injection and persistence, in which the author of a
> > > module knows in advance that one or more packages must be exported
> at
> > > run time for reflective access by frameworks. This proposal is
> also
> > > convenient for frameworks that generate code at run time, since the
> > > constant pool of a generated class file can include static
> references
> > > to types in dynamically exported packages.
> > >
> > > - This proposal opens the door to a category of second-class APIs.
> If
> > > a package is exported dynamically then you can still compile code
> > > that refers to types in the package, by using `-XaddExports` or its
> > > equivalent at compile time, and it will work as expected at run
> time.
> > > It thus may be useful to use `exports dynamic` for packages that
> > > contain legacy APIs whose use is strongly discouraged, e.g., those
> in
> > > the `jdk.unsupported` module of the reference implementation,
> thereby
> > > forcing anyone who wants to compile against them to go to the
> trouble
> > > of using `-XaddExports`.
> > >
> > > - Intrusive access to arbitrary packages of arbitrary modules by,
> e.g.,
> > > debugging tools, will still require the use of sharp knives such as
> > > the `-XaddExports` command-line option or its equivalent, or JVM
> TI.
> > >
> > > - Using the `-XaddExports` option or its equivalent remains awkward,
> > > and sometimes it's the only way out. To ease migration I think
> it's
> > > worth considering some way for an application packaged as a JAR
> file
> > > to include such options in its `MANIFEST.MF` file, as suggested by
> > > Simon Nash [5]. I'll create a separate issue for that.
> > >
> > > - New kinds of resolution failures are possible. If module `A`
> > > requires `B`, and `B` requires `C`, then if `B` and `C` both
> declare
> > > some package `P` to be exported dynamically, then a split-package
> > > error will be reported. This may surprise, since the packages are
> > > just internal implementation details that were exported dynamically
> > > so that some framework could access their types. This is not,
> > > however, all that different from the kinds of resolution and
> > > layer-creation failures that are already possible due to package
> > > collisions. It's unlikely to happen all that often in practice,
> > > and the fix is straightforward: Just use reverse-DNS or otherwise
> > > sufficiently-unique package names, as most people already do. It
> > > is worth exploring whether javac can detect at least some of these
> > > kinds of collisions and issue appropriate warnings.
> >
> > I would like to agree on that proposal only on the ground that it
> requires
> > to change the classfile format thus allows in the same time to fix the
> > issues of the current classfile spec (encoding of the name module as a
> > Class instead of UTF8, wrong flag for requires public), but i'm not sure
> > this proposal support it's own weight.
> >
> > Without dynamic, a 'classical' export works the same way at runtime so
> > adding 'dynamic' to an export only restrict the usage at compile time.
> > Given that we can already selectively export packages to some chosen
> > modules which hide them for the rest of the other modules at compile
> time,
> > adding dynamic to the spec adds little value.
> >
> > And it has several drawbacks, the main one is that it weaken the
> > compiletime/runtime fidelity story, with a dynamic export the runtime
> world
> > is not the compiletime world anymore.
> > The main motivation to add dynamic seems to be for backward compatibility
> > during the transition between the classpath world and the full module
> world,
> > for several other cases, we use the command line for that, i don't see
> why
> > this case is so special that it should not work like the other
> > compatibility issues.
> >
> > Moreover, an agent, an annotation processor and a jlink plugin are all
> > able to implement the same trick, add export after the compilation and
> > before the runtime,
> > so i don't think it's a good idea to change the spec for that.
> >
> > Rémi
> >
> > >
> > >
> > > [1]
> > >
> >
> http://openjdk.java.net/projects/jigsaw/spec/issues/#ReflectiveAccessToNonExportedTypes
> > > [2]
> > >
> >
> http://openjdk.java.net/projects/jigsaw/spec/issues/#ReflectionWithoutReadability
> > > [3]
> > http://openjdk.java.net/projects/jigsaw/spec/sotms/#qualified-exports
> > > [4]
> > >
> >
> http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2015-December/000205.html
> > > [5]
> > >
> >
> http://mail.openjdk.java.net/pipermail/jigsaw-dev/2015-December/005745.html
> > >
> >
>
More information about the jpms-spec-observers
mailing list