[jsr294-modularity-eg] Pain
Alex Buckley
Alex.Buckley at Sun.COM
Tue Jul 14 15:06:02 EDT 2009
Bryan, BJ, Doug, Sam, Bob, Daniel,
What are your opinions on Peter's mail?
Alex
Peter Kriens wrote:
> First, I think it is a fallacy to require to have the solution before
> you yell fire.
> However, many of the ideas I stand for are reported in the document I wrote when we started. Obviously there is some evolution, so let me elaborate
> a bit more. The following is obviously a sketch. More than willing to
> work this out in detail if it has a chance.
>
> Modules
> In the JLS we define a clean concept of module like .NET
> namespaces/Ruby/Modula etc. It is hierarchical and it is part of the
> Java source + class file.
>
> module com.acme.foo;
> package main;
> import com.acme.bar.*;
> import module org.osgi.service.log;
> module class A{}
>
> The type names are module name + package name + type name. I.e. in the
> previous example com.acme.foo.main.A. This is 100% compatible with our
> current model and fits the current JLS very nicely. This will simplify
> learning and porting.
>
> Jigsaw wants permits and OSGi has some resistance here. I there fore
> propose an implementation import in your compilation unit:
>
> import implementation module com.acme.impl;
> import implementation com.acme.impl;
>
> This will import all public and unspecified access packages but not
> private packages. By specifying the implementation keyword, you indicate
> that you're willing to suffer the consequences of using
> non-specification code. If security is on, we can prevent using this
> with security if the exporter really does not want it. Without security,
> you can do anything already so who cares. This model seems better than
> the reverse dependency model that permits/friends creates.
>
> You can nest modules: com.acme.foo/test
>
> module com.acme.foo;
> module test;
> package performance;
>
> class PerformanceTest {}
> A module info would NOT contain any dependencies and other packaging
> info, Only the top level module can have
> this. It can of course contain annotations.
>
> The package-info gets the capability to make a package public,
> implementation, or private:
>
> com/acme/foo/main/package-info.java:
> module com.acme.foo;
> private package main;
> com/acme/foo/service/package-info.java:
> module com.acme.foo;
> import module aQute.bnd.annotations;
> @Version(1.2)
> public package service;
> A public package is intended to be exported by the container and made
> available to others. A private package is local to the container, if not
> specified, it is allowed to be imported by classes import it as an
> implementation module (this prevents the need for friends). That is,
> types in a private package are not accessible outside the container. The
> default is private.
>
> If you import a module, you get visibility to all public packages but no
> private packages. That is, it looks like you do an import for each
> package marked public in the module with a * at the end.
>
> module accessibility is roughly defined as having access to your module
> + any higher modules. If you're not part of an explicitly defined
> module, you're part of the container. That is, the JLS must introduce
> the concept of a container and the container needs a
> container-info compilation unit. This unit is conceptually found at the root of the compilation tree. In this file, you describe your dependencies on other containers.
> The container file has all the messy stuff that we spent most of our
> time talking about. However, it has the following things standardized:
>
> name (which is like a fqn)
> version (a JSR 294 defined syntax, we MUST standardize this, it is
> ridiculous to leave this open)
> required modules
> optional public key
> module system specific info
>
> For example:
>
> container-info
> container com.acme.foo {
> version 2.1;
> key 1234567812121212121211212121212;
>
> require com.acme.bar, version=[2.1.2,3);
> require com.acme.util, version=[2.3.2,3);
> require com.acme.bar, version=[1.3,2);
> command foo;
> org.osgi {
> version 4.3;
> bundle-license "ASL 2.0";
> }
> com.sun.jigsaw {
> version 0.91;
> permit com.acme.yui;
> }
> }
>
> However, it is NOT compiled by the compiler, the compiler ONLY
> interprets this file, as do all the tools that need access to this
> information like ant, etc. However, the compiler records the exact
> version of the container against which it compiles in the class files of
> each compilation unit. That is, from the class file we know exactly the
> container we compiled against.
>
> I think this concludes the JLS part ... Now, the JDK part
>
> We need to reify the container into a JAR or some other artifact. This
> will be done by a tool like jar. This tool will create a container that
> has a container-info.class file. It contains a summary of:
>
> all actually used containers with the name, version, key, and indicated
> version range
> all public packages
> module system specific information (with the info if the ms is required
> or optional)
>
> The tool has a plugin model to create module system specific
> information. For OSGi, in this phase we can translate the information to
> import packages to reduce the fan-out and optionally do some other
> tricks that reduce deployment problems. Obviously, we can also calculate
> the uses constraints. Jigsaw just does what it needs to do. All
> information is collected in the container-info.class file.
>
> As some will wonder, why do I accept requires? Well, during development
> time I think the coarse granularity of containers is nice, I just think
> that at the runtime their fan-out is too large for comfort. I the
> sketched process, the container reifying tool can handle this conversion
> with a plugin.
>
> The next phase
> is runtime! I think we need a repository associated with a JVM. The still 100% standardized containers are inserted into the repository. A
> module system must have the facility to optimize the artifact for its
> deployment, for example, it must be able to maintain an OBR index. The
> insert in the repository must also verify the command option in the
> container-info. If this is set, it should create a command on the file
> system so the program can be run from the command line and/or desktop.
>
> The java command gets an option to run a container. E.g.
>
> java -run com.acme.foo
>
> The java looks in the repository and finds the container com.acme.foo.
> It looks to see what the container-info says about module systems and
> picks the first listed module system that is available in the vm (which
> should also be in the repository). It then passes control to the module
> system that resolves the given com.acme.foo and runs it. Alternatively,
> because foo is also registered as a command in the container, it can
> also run it:
>
> $ foo
> Or
> c:\>foo
>
> The module system is fully in control of what happens at runtime. It has
> access to the repository and can install containers when it needs to. A
> module system can also reuse the information from other module systems.
> For example, an OSGi framework could interpret the data from jigsaw and
> emulate their model. We could also look to see if there is Guice
> information in the container-info and run that as well.
>
> Again, this is a sketch, let me know if I should work out all the
> unspecified details. Kind regards,
>
> Peter Kriens
>
>
>
> On 9 jul 2009, at 19:26, Alex Buckley wrote:
>
>> What would you like to see happen? Details please.
>>
>> Alex
>>
>> Peter Kriens wrote:
>>> As you probably have noticed, I am not very happy where we are.
>>> Instead of providing a singular model based on best practices, we
>>> worsen the situation by introducing the world's first meta module
>>> system that is completely outside whatever we already have in Java.
>>> And while we're at it, we're not fixing any of the known
>>> deficiencies. Alas, we are not standardizing Java modules, we are
>>> agreeing to go our own way.
>>> We are not reusing any Java concepts, the complete definition of
>>> module is left to the module system. And sadly, Java has modules,
>>> they were called packages. As the JLS says: "Chapter 7 describes the
>>> structure of a program, which is organized into packages similar to
>>> the modules of Modula." In 294, instead of building on the existing
>>> Java Language constructs and fixing its shortcomings, we went off on
>>> something that is a hybrid of .NET's namespace and assemblies. I
>>> invariably notice that when 294 is discussed people are in the ".NET
>>> namespace/Ruby modules" world or in the ".NET assembly/Ruby gems"
>>> world, it is rare that I feel that the subtle distinctions and
>>> overlap in concepts is clearly understood. Hey, I am not even sure I
>>> get it. At the same time, each camp seems to have a clear view what
>>> it will get out of 294. Which I guess over time they will when a
>>> cotton industry of module systems has arisen, but in a Java world
>>> where the word Java is no longer sufficient to define the language.
>>> Module is a well defined word but it is fractal. A code block is a
>>> module, method is a module, a class is a module, a package is a
>>> module, a library is a module, and a program is a module. They all
>>> have an inside and an outside, where different rules apply. My
>>> problem with the current design is that it does not define anything
>>> that fits nicely in this hierarchy or even resembles existing Java
>>> concepts; it will leave details up to the module system. This will
>>> make the source code no longer portable, the antithesis of Java :-(
>>> Yes, I can see lots of cool features we can provide with the Eclipse
>>> compiler and the OSGi runtime but it saddens me that this will
>>> fragment the Java world, forcing the user to find out the features
>>> that are portable between module systems or committing to their
>>> favorite module system.
>>> In Java 1..6 the language offered a pretty pure model that was mapped
>>> to reality in the VM. With class loader tricks we could tweak the
>>> perspective each JAR had of this pure world, solving many real world
>>> problems. In JSR 294, we will for the first time introduce this messy
>>> and complex runtime world in the language. Untold millions have been
>>> spent to make Java run on hundreds of platforms, and with one simple
>>> JSR we bring back the need for #ifdef ...
>>> Kind regards,
>>> Peter Kriens
>>> ------------------------------------------------------------------------
>>> _______________________________________________
>>> jsr294-modularity-eg mailing list
>>> jsr294-modularity-eg at cs.oswego.edu
>>> <mailto:jsr294-modularity-eg at cs.oswego.edu>
>>> http://cs.oswego.edu/mailman/listinfo/jsr294-modularity-eg
>> _______________________________________________
>> jsr294-modularity-eg mailing list
>> jsr294-modularity-eg at cs.oswego.edu
>> <mailto:jsr294-modularity-eg at cs.oswego.edu>
>> http://cs.oswego.edu/mailman/listinfo/jsr294-modularity-eg
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> jsr294-modularity-eg mailing list
> jsr294-modularity-eg at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/jsr294-modularity-eg
More information about the jsr294-modularity-eg
mailing list