On 09/28/2016 05:31 AM, Gunnar Morling wrote:
David,

there is too much existing work out there, and the requirements go far
beyond
what can be satisfied by these simple questions.

What are examples for such requirements? I.e. what from the list of your
requirements cannot be mapped to the mechanism suggested by Stephen? I
find his proposal quite appealing and am wondering whether it couldn't
be tweaked to cater for the remaining requirements.

I would rather in this case ask: how does his proposal solve all of our requirements? The burden is always on the implementer to solve requirements, not the other way around.

Btw. I second the concern that the exposure of internal parts for
reflective access should not be implicitly enabled by merely depending
on a module requesting such access. It seems too easy for users to
accidentally give access to internal code without being aware of it.

Possibly. But that's a usability concern and does not change the requirement.

For example it's not hard to imagine that someone importing such a module has to acknowledge the requested access explicitly (without defining the specifics of it) in order for the module to successfully link. Of course that's just one idea to illustrate that the requirement can be addressed; it's not a proposal.



2016-09-27 16:30 GMT+02:00 David M. Lloyd <david.ll...@redhat.com
<mailto:david.ll...@redhat.com>>:

    Hi Stephen,

    I just want to point out that this isn't a proposal per se.  I don't
    advocate any particular syntax, nor recommendation for patterns that
    users should use.  This is merely a set of requirements that we (Red
    Hat) have identified as necessary in order to enable the widest
    range of existing middleware systems to continue to function with a
    minimum of disruption or security compromises.  Any proposal that we
    accept will necessarily meet these requirements, though these
    requirements may or may not be sufficient for acceptance (only
    testing will tell us the full story).

    The reason I didn't boil it down to the same set of questions that
    you have asked is that those questions are simply not sufficient to
    meet the requirements of a modern middleware application.  To quote
    the JSR description: "This JSR will define an approachable yet
    scalable module system [...] so that developers can use it to
    construct and maintain libraries and large applications for both the
    Java SE and Java EE Platforms. [...]"

    I think it's very possible for the platform module system to be
    specified and implemented in such a way as to enable the continued
    maintenance of existing libraries and large applications, however in
    order to do so, it is our estimation that these requirements must be
    met.

    In response to the way you've narrowed down the scope of
    requirements: I agree that such simplifications work well when
    establishing boundaries for a new project and encouraging good usage
    patterns.  But I don't think we can really do that here; there is
    too much existing work out there, and the requirements go far beyond
    what can be satisfied by these simple questions.


    On 09/26/2016 05:11 AM, Stephen Colebourne wrote:

        Having read this proposal a number of times, and considering how the
        talks explained things at JavaOne, I have come to the conclusion
        that
        this proposal is too complex. FWIW, I like the idea that a module
        should be able to declare that it needs reflective access from its
        users, however given that the proposal is what results from the
        idea,
        it doesn't seem as appealing as it should.

        The reason why I put forward the exports/exposes approach [1] is
        that
        it keeps the questions that must be asked when creating a module
        simple:
        - what do I depend on publicly (requires)
        - what do I publish publicly (exports)
        - what do I publish privately (exposes)

        From a security point of view it also seems that it should be the
        responsibility of a module to allow the publishing of its private
        details, and simply depending on another module seems very minimal
        (and easy to miss) as a mechanism to allow that extra permission.

        Stephen

        [1]
        
http://mail.openjdk.java.net/pipermail/jigsaw-dev/2016-September/009370.html
        
<http://mail.openjdk.java.net/pipermail/jigsaw-dev/2016-September/009370.html>


        On 21 September 2016 at 17:39, David M. Lloyd
        <david.ll...@redhat.com <mailto:david.ll...@redhat.com>> wrote:

            In our internal discussion of the proposal for
            #ReflectiveAccessToNonExportedTypes, we discussed the ins
            and outs of
            various behaviors and have come up with a few ideas or
            starting points for
            solutions that we think would be more workable in
            conjunction with existing
            middleware (ours and others').

            For reasons previously explained, we do not think that weak
            modules are a
            good way forward; I won't go into that again here.  But the
            logical
            re-starting point is: If not weak modules, then what?

            I will boil it down to a few basic requirements that we have
            established.
            This list is probably non-exhaustive but hopefully complete
            enough to go on
            for now:

            • A module definition must be able to establish that a
            dependent has (or all
            modules have) access to one or more (or all) packages for
            public reflection
            only.
            • A module definition must be able to establish that a
            dependent has (or all
            modules have) access to one or more (or all) packages for
            public or private
            reflection only.
            • A module definition must be able to establish that a
            dependent has (or all
            modules have) access to one or more (or all) packages for
            public reflection
            and compilation/linkage (i.e. it's an export by today's
            terminology).
            • A module definition must be able to establish that a
            dependent has (or all
            modules have) access to one or more (or all) packages for
            public or private
            reflection and compilation/linkage (i.e. it's a "private"
            export by today's
            terminology).
            • As today, any packages not declared in one or more of the
            above categories
            is inaccessible outside of the module in any way (note that
            as I showed
            previously we have also concluded that it should continue to
            be impossible
            to export a package for compilation/linkage without public
            reflection, as we
            have not discovered any use for such a mode).

            More generally:

            • The syntax for all of the above has no particular
            constraint (in fact I
            will try to actively avoid touching what could be a very
            bikeshedding-rich
            discussion), except that it should not be construable as
            being pejorative
            against the usage of reflective frameworks; rather, it
            should be clear what
            level of trust is being established without raising undue
            warning.
            • Applications should not need gratuitous amounts of
            declarations in their
            module(s) in order to utilize frameworks.
            • As previously established, it should not be possible for
            one declaration
            to reduce the scope of access of another declaration in a
            module definition.
            • Access to a module (for reflective purposes only) must not
            cause conflicts
            if multiple such modules which contain identical packages
            are accessible to
            a single consumer; in other words, reflection-only access into
            non-dependency modules is not bound by duplicate package
            restrictions as
            long as each package is unique per class loader, as per the
            current (Java 8)
            class loader rules.

            The above cover the useful access modes that we have
            identified.  This is
            _nearly_ adequate to cover the use cases that we are
            currently concerned
            about; for example, I could export all packages for public
            reflection only
            to a specific framework, if only I know the module name of the
            implementation.

            Unfortunately, this does not work well in the case where a
            module may
            consume a framework whose specification is separate from the
            implementation.
            An application module may need to use (say) EJB and JPA;
            there is presently
            no clean way to do so without either (a) relying on a
            container environment
            to rewrite the descriptor or (b) opening up the module and
            defeating the
            security mechanism (e.g. "weak").  Without either of these
            workarounds, the
            application developer must have a good deal of knowledge
            about what modules
            provide what services within a framework-rich environment,
            possibly
            resulting in a very verbose (and error-prone) descriptor;
            none of these
            options is really satisfactory.

            Thus, apart from the option of redesigning (to an extent)
            the security
            mechanism (thereby eliminating the need to seal off access
            to public
            reflection, which is definitely still an attractive option
            for various
            reasons from our perspective, but which is also a very different
            discussion), we need some sort of mechanism which decouples
            the literal
            dependency system from access permission (much like
            uses/provides does).

            For example if I could declare that my module uses
            "javax.ejb", and, in so
            doing, automatically grants public and private reflective
            access to the
            module that provides that service, this would be a good
            outcome.  A module
            which answers to that service name could be responsible for
            reflective
            access to the application module, providing that information
            privately to
            any other framework modules which require it.

            The migration story looks much better in this light: module
            descriptors
            still can be quite terse and specific.  Applications which
            use reflective
            frameworks do not need gratuitous exports; in fact it's much
            more fluid for
            a user to say "I require these helper libraries; I use EJB;
            that's it" which
            means they don't have to worry about the details of whatever
            particular
            environment they run in.  This also has the advantage of
            allowing new Java
            9-generation specifications to stipulate standard service
            names for each
            specification (e.g. "javax.ejb", "javax.cdi", that sort of
            thing).

            While this doesn't cover 100% of our remaining issues with
            Jigsaw (of
            course; we'll all continue moving through the issues list as
            we have been to
            get us there), meeting these requirements would go a long
            way towards at
            least having a reflection story that is more practical for
            present-day
            frameworks to move forward with.  So the last requirement
            would be:

            • A module definition must be able to establish that an
            "indirect"
            dependency exists on an otherwise unknown module providing a
            capability,
            wherein that module may require public or public+private
            reflection access
            to some or all packages without compile/link access.  This
            could possibly
            exist in conjunction with, or as an evolution of, the
            current services
            mechanism, however a complicating factor is that the current
            mechanism is
            based specifically on types, whereas a purely symbolic
            relationship might be
            better for this purpose (this is not a requirement though if
            it can be made
            to work as-is).  Note that any symbolic relationship system
            would need some
            in-code discovery mechanism such that consumers of the
            capability are made
            available to the provider and/or vice-versa, in order to
            make practical use
            of the relationship.

            The following example syntax is meant to be unambiguous and
            illustrative; no
            specific attempt is made to reuse existing keywords (for
            example), or even
            to imply an endorsement of the current descriptor mechanism
            at all, but to
            clarify how this might look in practice and provide a
            practical application
            of the ideas herein.

            Example 1: A contrived provider of the fictional framework
            "javax.fictional.orm" illustrating provides/uses-based
            access granting

            module org.foo.orm.provider {

                  // Require a module dependency, and give it private
            reflection access
            to everything
                  requires org.apache.commons.beanutils with private
            reflection on *;

                  // Require a module dependency with no reflection
                  requires org.apache.commons.logging;

                  // Provide the framework
                  provides javax.fictional.orm.ORM
                      using private reflection
                      with org.foo.orm.provider.ORMImpl1,
                           org.foo.orm.provider.ORMImpl2;
            }

            Example 2: A contrived consumer of #1

            module com.mycompany.application {
                  uses javax.fictional.orm.ORM; // automatically gives
            private
            reflection
            }

            Example 3: Grant reflection access to a couple of packages
            to a named
            non-dependency module

            module com.mycompany.application {
                  grant public reflection on
                      com.mycompay.application.package1,
                      com.mycompay.application.package2
                  to org.foo.framework;
            }

            Example 4: Behave like Java 8

            module com.mycompany.application {
                  grant private reflection on * to *;
            }

            Example 5: Behave like Java 8, but restrict private access
            without requiring
            a security manager

            module com.mycompany.application {
                  grant public reflection on * to *;
            }

            Example 6: An example of using CDI and EJB with symbolic
            capabilities

            module com.mycompany.application {
                  uses capability javax.ejb, javax.cdi
            }

            Example 7: An example of providing EJB with symbolic
            capabilities

            module org.foo.ejb.provider {
                  [...]
                  provides capability javax.ejb using private reflection;
            }


            --
            - DML


    --
    - DML



--
- DML

Reply via email to