[jsr294-modularity-eg] Pain
Sam Pullara
sam at sampullara.com
Fri Jul 17 13:50:07 EDT 2009
This looks good to me. It has easy syntax for those that want to
support and use it. It also appears to work for those that want to
ignore it and just stuff the classpath. The only thing that is
missing is some way to use legacy jars as modules, though I can
imagine some sort of POM compiler that could bridge the gap between
the current maven repositories and this new module world. It also
seems to jive well with current best practices around Java coding
which means there isn't much to learn.
Sam
On Jul 10, 2009, at 1:59 AM, 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
>>> 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
>
> _______________________________________________
> jsr294-modularity-eg mailing list
> jsr294-modularity-eg at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/jsr294-modularity-eg
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/jsr294-modularity-eg/attachments/20090717/9f42a40c/attachment-0001.html>
More information about the jsr294-modularity-eg
mailing list