[jsr294-modularity-eg] Expressing module dependencies

Alex Buckley Alex.Buckley at Sun.COM
Wed Apr 8 21:32:39 EDT 2009


In the putative 294 spec, a module compilation unit ("module-info")
defines a module's name, version, and dependencies. The EG has expressed 
interest in what dependencies look like as annotations v. as keywords, 
so here are some examples of what is possible syntactically.

Bear in mind that non-JLS annotation types must be imported. The JLS 
changes already allow 'import' statements before a module declaration 
for this reason.


1) Annotations

@Requires("com.foo.bar @ 4.0+")
module com.foo.app @ 1.0;

@Requires(module="com.foo.bar", version=">=4.0")
module com.foo.app @ 1.0;

@Requires(package="com.foo.bar", version=">=4.0", uses="com.foo.bar")
module com.foo.app @ 1.0;

@Requires(package="com.foo.bar", attributes="friend:yes")
module com.foo.app;

JSR 175 decided not to allow multiple annotations of the same name on 
the same element. That decision might be changed one day, but 294 is not 
the place to change it. Multiple dependencies must be encoded somehow:

@Requires({ "com.foo.bar @ 4.0+", "com.foo.baz @ 5.0+" })
module com.foo.app @ 1.0;

@Requires({ "com.foo.bar", "com.foo.baz" }, { ">=4.0", ">=5.0" })
module com.foo.app @ 1.0;

@RequiresContainer({
   @Requires(module="com.foo.bar", version=">=4.0"),
   @Requires(module="com.foo.baz", version=">=5.0")
})
module com.foo.app @ 1.0;

@Requires({ "com.foo.bar @ 4.0+" })
@RequiresOptional({ "com.foo.baz @ 5.0+", "com.quux.nab @ 6.0+" })
module com.foo.app @ 1.0;

import org.osgi.annotations.*;
@RequireBundles({ "com.foo.bar @ [4.0,5.0)" })
@ImportPackages({ "com.foo.baz @ [5.0,6.0)", "com.quux.nab @ 6.0" })
module com.foo.app @ 1.0;

Dependencies have many facets - the kind of target, optionality, 
constraints (OSGi's "uses") - and it looks like every combination would 
require its own annotation type ... or else define one common annotation 
type with many fields that will often be empty.

Note that imported annotation types implicitly indicate which module 
system a dependency is for. Other module systems just ignore annotations 
not of their own annotation types.

Having said that, at least one standard annotation type for dependencies 
will have to be defined in the JLS, to be understood by a compiler which 
isn't using any module system.


2) Keywords

module com.foo.app @ 1.2 {
   requires com.foo.bar @ 4.0+, com.foo.baz @ 5.0+;
   requires optional com.quux.nab @ 6.0+;
}

And using the "free" grammar which allows arbitrary terms after 
'requires', plus a convention that a dependency specific to a module 
system is identified by the first term:

module com.foo.app @ 1.2 {
   requires osgi optional dynamic package com.quux.nab @ [1.0,2.0);
}


Annotations play the role of metadata in Java programs; they should not 
affect the meaning of programs. They are extra-lingual - outside the 
language. Most people who want to expand the Java language with new 
features cannot do so, so express their features outside the language 
via annotations.

The EG is not so limited. The aim of JSR 294 is to make modular 
programming easier *in the Java language*. Not via XML files, not via 
tools, but with language constructs. We can expand the language to 
include the concept of a dependency, expressed via 'requires', even if 
some aspects of a dependency are not controlled by the language. The 
rubber (language) has to meet the road (module system) somewhere.

By way of analogy, Java would be better if the @Override annotation was 
a restricted keyword 'override' which acted as a method modifier.

Alex
_______________________________________________
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