[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