Module Views

Jesse Glick jesse.glick at oracle.com
Wed Dec 7 14:32:39 PST 2011


On 12/07/2011 04:17 PM, mark.reinhold at oracle.com wrote:
> A series of `exports` and `permits` clauses at the top syntactic level of
> a module declaration defines the module's _default view_.  Further views
> of a module's content can be defined using the new `view` construct,
> which specifies a view name together with a bracketed list of exports and
> permits declarations.

This feels confusing. A class may either have an implicit no-arg constructor or an explicit list of constructors, but not both. I think the same should be true of views - 
either you do not use the view keyword, or all exports in the module must be defined in explicit views (one of which may have the same name as the module).

> It also exports all public
> types in the `foo` package because the non-default views of a module
> inherit the exports clauses of that module's default view.

This also seems needlessly confusing, especially in light of the fact that permits are _not_ inherited. Clearer to have each view list its complete contents.

>      module commands {
>          view cat {
>              class org.foo.commands.Cat;
>          }
>          view find {
>              class org.foo.commands.Find;
>          }
>          view ls {
>              class org.foo.commands.List;
>          }
>      }
>
> defines three entry points, `cat`, `find`, and `ls`.

Entry points as currently in Jigsaw strike me as very limited; they seem to only apply to main(String[]) classes, meaning they are only useful for command-line programs. 
A more general approach would be to define

package java.lang; // ?
public interface Application {
     void /* or int? */ main(String... arguments) throws Exception;
}

and permit a module to register it using the 'service' declaration. The command-line launcher in module mode would just look for one (and only one) instance of the 
Application service and run it, whereas an applet container would look for an Applet, etc. Legacy main classes could trivially be retrofitted. This would eliminate the 
need for a special 'class' declaration in module metadata.

>      module jdk.tls @ 8-ea {
>          requires local jdk.boot @ 8-ea;
>          exports com.sun.net.ssl.*;
>          exports java.net.*;
>          exports javax.net.*;
>          exports javax.net.ssl.*;
>          exports javax.security.cert.*;
>          view jdk.tls.internal {
>              permits jdk.crypto, jdk.sunpkcs11, sun.compat,
>                      sun.jndi, sun.kerberos, sun.management, sun.rmi;
>              exports sun.security.internal.interfaces.*;
>              exports sun.security.internal.spec.*;
>              exports sun.security.pkcs.*;
>              exports sun.security.ssl.*;
>              exports sun.security.util.*;
>              exports sun.security.x509.*;
>          }
>      }

With my suggested changes:

     module jdk.tls @ 8-ea {
         requires local jdk.boot @ 8-ea;
         view jdk.tls {
             exports com.sun.net.ssl.*;
             exports java.net.*;
             exports javax.net.*;
             exports javax.net.ssl.*;
             exports javax.security.cert.*;
         }
         view jdk.tls.internal {
             permits jdk.crypto, jdk.sunpkcs11, sun.compat,
                     sun.jndi, sun.kerberos, sun.management, sun.rmi;
             exports sun.security.internal.interfaces.*;
             exports sun.security.internal.spec.*;
             exports sun.security.pkcs.*;
             exports sun.security.ssl.*;
             exports sun.security.util.*;
             exports sun.security.x509.*;
         }
     }

and usage of the internal view:

     module jdk.crypto @ 8-ea {
          // assuming it needs the public types (maybe it does not):
         requires jdk.tls @ 8-ea;
         // for its special access add:
         requires jdk.tls.internal @ 8-ea;
     }

> Another possibility is to structure the names of non-default views so that they always include the names of their containing modules, but that turns views into
> second-class entities.

I suppose you mean that in the above example, the compiled jdk.crypto module's metadata would refer to the name "jdk.tls" only, so that when packaged natively, 
jdk.crypto.deb would simply depend on jdk.tls.deb. This seems natural enough; the view just controls what is exposed to whom, but does not change the nature of the 
module-to-module dependency. Virtual dependencies introduce a lot more complexity and points of failure, though perhaps you deal with this anyway as part of the 
"substitution" requirement.



More information about the jigsaw-dev mailing list