[jsr294-modularity-eg] Pain

Bryan Atsatt bryan.atsatt at oracle.com
Tue Jul 14 19:13:58 EDT 2009


I think we've been around this circle before: module names in source, 
nested modules/containers, module system specific clauses in the 
declaration, etc. Still not buying.

I am all for standardizing the "require" directive as much as possible, 
and the semantics that 'require module' == all of its public packages 
(with no split packages). OSGi can support 'require bundle' with the 
split package semantic if it wants to. It should also support 'require 
package', rather than using a different directive like 'import'.

I am even in favor of standardizing a version/range syntax, but only if 
we also provide Version/VersionRange classes that are syntax agnostic.

My issue at the moment with the proposed drafts is that the api doc is 
incomplete and so it is hard to see how this all hangs together. I'll 
send a more complete (and refactored) api in a separate message.

// Bryan

Alex Buckley wrote:
> 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
> _______________________________________________
> 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