[jsr294-modularity-eg] Pain

Alex Buckley Alex.Buckley at Sun.COM
Fri Jul 10 14:27:24 EDT 2009


Do other EG members agree with this mail? If so, how?

Alex

P.S. Please do not take my lack of commentary on your initial mail or 
this mail as indicating that I have no opinion on the content. I have 
opinions on every sentence. It would be premature to give them now.

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
_______________________________________________
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-observer mailing list