[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