[jsr294-modularity-eg] Problems for JSR 294 to address

Alex Buckley Alex.Buckley at Sun.COM
Mon Feb 2 20:06:23 EST 2009


I wonder why C# namespaces were not designed such that hierarchy governs 
accessibility?

Alex

Hal Hildebrand wrote:
> 
> On Feb 2, 2009, at 7:58 AM, Peter Kriens wrote:
> 
>> Hmm. .NET shows that you do not have to know all the module boundaries 
>> during compilation. 'internal' indicates inside the assembly and the 
>> source assembly is clearly not known during compilation. This concept 
>> looks attractively simple and is in line with common practice.
> 
> This is something I was wondering.  How can it be that .NET can do this, 
> but the gods of Java are unable to figure out how to accomplish this.
> 
>> For 294, during compilation, the JAR files and project source can 
>> easily be used inside the compiler for the scope. During runtime, the 
>> module system can set this boundary.
>>
>> However, I also like a module concept that is defined in the language. 
>> This will be more complex (and probably should be hierarchical) but it 
>> should be not attempt to define the deployment artifact nor 
>> dependencies. That is, it should be more like namespaces.
>>
>> Kind regards,
>>
>>     Peter Kriens
>>     
>> On 28 jan 2009, at 03:56, Alex Buckley wrote:
>>
>>> I am happy to discuss module-private accessibility first, in that it 
>>> addresses the limitations of packages on which we all agree.
>>>
>>> The issue we cannot ignore is that to check module-private 
>>> accessibility at compile-time means knowing the modules to which the 
>>> requesting and requested types belong. If I invoke:
>>>
>>> javac Foo.java Bar.java
>>>
>>> where Foo.java refers to Bar, then a compiler must be able to compute 
>>> at least the module name to which Foo belongs as Foo is compiled, if 
>>> Bar is found to be module-private as it is compiled. There are no 
>>> deployment artifacts around yet. It shouldn't be a surprise that 
>>> Foo.class and Bar.class are subsequently emitted to encode their 
>>> module membership.
>>>
>>> So with module accessibility comes module membership. Module 
>>> dependencies are a quite different topic which we'll get to soon 
>>> enough, and they are the place where minimizing new concepts is 
>>> essential.
>>>
>>> Alex
>>>
>>> Peter Kriens wrote:
>>>> I think it would make sense to work from first principles
>>>>  1. What problem are we trying to solve?
>>>>  2. How do we scope this problem to an acceptable area for all?
>>>>  3. What requirements should the solution fulfill
>>>> I would like to have a short discussion about the problem so we are 
>>>> sure we are all on the same page. I can start off with the problem I 
>>>> think we are trying to solve.
>>>> Modularity
>>>> Modularity is the art of encapsulation and hiding. A module limits 
>>>> the amount of information outside its boundaries. This reduces the 
>>>> overall complexity of a system because it becomes possible to reason 
>>>> (and change) locally about a module instead of understanding the 
>>>> whole system, and it provides a local namespace that is easier to 
>>>> work with for humans than a global namespace.
>>>> Java provides modularity in many places. A type encapsulates its 
>>>> fields and methods and selectively exposes them to other types with 
>>>> the access modifies: private, protected and public. A package 
>>>> encapsulates a number of types and resources. And last, but not 
>>>> least, the class loader provides a class space that can be distinct 
>>>> from other class spaces.
>>>> The modularity that is enabled with class loaders has been exploited 
>>>> by many. However, the Java Language has little to say about class 
>>>> loaders; it is outside the scope of the language.
>>>> So what problem do we need to solve, seeing that Java provides 
>>>> already so many forms of modularity? There is a sense in the 
>>>> community that packages are too small for modules. Though the 
>>>> package names hint at a hierarchy (and this is how they are found in 
>>>> a file system), this hierarchy does not provide a preferential 
>>>> treatment for children. Many programs consist of hundreds of 
>>>> packages. However, except for the limited package concept, the 
>>>> programmer cannot indicate that the visibility of an artifact should 
>>>> be limited to the program, or part of the program.
>>>> A large number of delivery formats have been created over the years, 
>>>> most of the based on the JAR format (which is also not a part of the 
>>>> language): WAR, EAR, OSGi bundles, midlets, xlets, and likely many 
>>>> more proprietary formats. Usually, the modularity of these modules 
>>>> is based on a rather simplistic hierarchical class loader model. 
>>>> That is, all classes in ancestors are visible, but not any siblings 
>>>> or their children. The language is moot on the point of this type of 
>>>> encapsulation.
>>>> Delivery modules contain types that depend on types in other 
>>>> delivery modules. There is no uniformly agreed Java standard to 
>>>> model these dependencies. During build time, the compiler is 
>>>> provided with a linear list of JARs and the compiler picks the first 
>>>> type that matches a name. Only the name is encoded in the class 
>>>> file, not the originating delivery module. During runtime, the same 
>>>> process is used to find classes, albeit in a hierarchical class 
>>>> loader model. This has all so far been outside the Java Language.
>>>> It is crucial that we distinguish the language/logic modularity and 
>>>> the modularity based on the deployment artifact. Interestingly, in 
>>>> my understanding, .NET makes such a distinction between the 
>>>> modularity of a delivery unit (called an assembly) and the finer 
>>>> grained modularity inside a delivery unit, represented by 
>>>> namespaces. The "internal" keyword indicates that the artifact is 
>>>> visible only inside an assembly and the "namespace" keyword provides 
>>>> a hierarchical namespace.
>>>> Therefore, one can identify two problems in the Java platform 
>>>> concerning modularity
>>>>  1. Packages are too limited for proper language/logic modularity
>>>>  2. Lack of a runtime module concept that is related to deployment
>>>>     artifacts (physical modularity)
>>>> Looking at the proposed time frame (EDR by mid-April), attacking 
>>>> both problems simultaneously seems rather unrealistic based on my 
>>>> limited experience. I therefore suggest to start with problem #1: 
>>>> Packages are too limited for proper language/logic modularity. What 
>>>> do you think?
>>>> Kind regards,
>>>> Peter Kriens
>>>> On 27 jan 2009, at 05:31, Alex Buckley wrote:
>>>>> Comments welcome.
>>>>>
>>>>> 1) Packages are typically arranged in hierarchies, but types can 
>>>>> only be
>>>>> used across different branches of the hierarchy by being made public,
>>>>> which exposes implementation details too widely. Information hiding is
>>>>> further reduced by interface members always being public.
>>>>>
>>>>> Non-solution: hierarchical package membership. Redefining existing
>>>>> well-known semantics is always a bad idea, and this one is especially
>>>>> complicated. There would need to be a way to stop package-private
>>>>> artifacts from being accessible to subpackages, or else we would be
>>>>> strengthening information hiding in one place only to weaken it
>>>>> elsewhere. Also, there would need to be a way to configure the 
>>>>> depth of
>>>>> exposure of package-private artifacts, since artifacts in package A
>>>>> should sometimes be accessible to A.B and not to A.B.C, and so on.
>>>>>
>>>>> 2) Dependencies of one type on another are expressed in source and
>>>>> classfiles, but there is no standard way for a Java compiler or JVM to
>>>>> interact with its environment to read and resolve dependencies. This
>>>>> causes compile-time and runtime environments to differ, and 
>>>>> complicates
>>>>> any effort to version types available in the (compile-time or runtime)
>>>>> environment.
>>>>>
>>>>> Non-solution: standardize the CLASSPATH. One list for all programs and
>>>>> libraries in the JVM makes versioning almost meaningless, and packages
>>>>> whose types occur in multiple CLASSPATH entries can behave poorly. 
>>>>> (See
>>>>> Peter Kriens' presentation at Devoxx 2008.)
>>>>>
>>>>> 3) Many packages have grown large over the years. They are effectively
>>>>> impossible to refactor now, since it is binary-incompatible to rename
>>>>> types and dangerous to "split" packages. The next-best option is to 
>>>>> let
>>>>> subsets be taken of existing packages, and deliver subsets
>>>>> independently, but there is no mechanism in the Java language or 
>>>>> JVM for
>>>>> that.
>>>>>
>>>>> Non-solution: a mechanism for renaming packages and types outside the
>>>>> Java language. This would require updating Java's model of binary
>>>>> compatibility, and would make source code incomprehensible.
>>>>>
>>>>> Alex
>>>>> _______________________________________________
>>>>> 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
>>
>> _______________________________________________
>> 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