[jsr294-modularity-eg] Module directive types
Peter Kriens
peter.kriens at aqute.biz
Fri May 8 12:00:00 EDT 2009
I can find myself quite well in this approach :-) I like the potential
of type safety and constants a lot.
Just some minor issues.
The ':' instead of '=' looks good, but seems to deviate rather
strongly from Java style? Though I must admit that it brought back
pleasant memories from my smalltalk days, but then the semicolon threw
me off ...
Would there be a possibility to allow syntax for a map? We have a
number of places where we have arbitrary attributes. Almost any
language supports a map type, never understood why Java did not have
one. For example [ a=b, c=d ]
I am a bit uncomfortable that we highly leverage annotations but add a
bit and deviate a bit. Over time, this will be a maintenance hell.
A lot of the ideas seem very interesting for annotations anyway, it
would be a shame if these features could not be used for other
purposes. How do we control this evolves together?
Kind regards,
Peter Kriens
On 7 mei 2009, at 19:24, Bob Lee wrote:
> I can define a grammar and write a Coin-style proposal for these
> ideas if
> you'd like, but Doug told me I should send out the examples sooner
> rather
> than later.
>
> First, we have a typical module declaration containing declarative
> "module
> directives" for Jigsaw, OSGi, and Guice.
>
> Note: I've always thought that a module declaration would be the
> perfect
> place to configure Guice-style dependency injection; we configure type
> dependencies here, why not object dependencies? The two go hand-in-
> hand. I
> originally thought I'd have to wait for Java 8 to build this
> directly into
> the language, but if we make the syntax extensible, I could use it for
> dependency injection configuration right away. If 294 goes with a
> less type
> safe approach, I probably won't use it for Guice configuration
> because our
> current Java-based approach is more straightforward and type safe.
>
> Example usage:
>
> import com.sun.jigsaw.permits;
> import com.sun.jigsaw.provides;
> import com.sun.jigsaw.requires;
>
> import org.osgi.jsr294.export;
> import org.osgi.jsr294.import;
> import org.osgi.jsr294.classpath;
> static import org.osgi.jsr294.Granularity.*;
>
> import guice.bind;
>
> module m1 {
> // Module directives
>
> // Jigsaw
> provides version: "3.4.5";
> provides alias: "acme" version: "3.4.5";
> requires module: "m2" version: "1.0+";
> permits module: "m3";
>
> // OSGi
> export name: "com.m1" version: "3.4.5";
> import granularity: BUNDLE version: ">1.0";
>
> // "value:" is assumed if only one operand exists.
> classpath { "m2.jar", "api.jar" };
> classpath "./classes";
>
> // Guice
> bind type: Foo.class annotatedWith: Red.class to: FooImpl.class;
> }
>
> Here are the module directive types (defined with @module) used for
> the
> module directives above:
>
> package com.sun.jigsaw;
>
> /** Expresses a dependency on another module. */
> public @module requires {
> /** Module name. */
> String module();
> /** Module version query. */
> String version();
> }
>
> /** Versions and optionally renames this module. */
> public @module provides {
> /** Overrides the default module name. */
> String alias() default null;
> /** Module version. */
> String version();
> }
>
> /** Permits another module access. */
> public @module permits {
> /** Module name. */
> String module();
> }
>
> package org.osgi.jsr294;
>
> /** Granularity of import or export. */
> public enum Granularity {
> PACKAGE, BUNDLE;
> }
>
> /** Exports part of this module. */
> public @module export {
> /** Name of package or module. */
> String name();
> /** Specifies the granularity of the export. */
> Granularity granularity() default Granularity.PACKAGE;
> /** Version. */
> String version();
> }
>
> /** Imports part or all of another module. */
> public @module import {
> /** Name of package or module. */
> String name();
> /** Specifies the granularity of the import. */
> Granularity granularity() default Granularity.PACKAGE;
> /** Version range. */
> String version();
> /** Whether or not this import is required. */
> boolean optional() default false;
> }
>
> /** Specifies the classpath of this module. */
> public @module classpath {
> /** Array of path elements. */
> String[] value();
> }
>
> package guice;
>
> /** Binds type T to a more specific version of T. */
> public @module bind<T> {
> Class<T> type();
> Class<? extends Annotation> annotatedWith() default null;
> Class<? extends T> to() default null;
> }
>
> Further ideas:
>
> 1. Like annotations, you can already elide value: in the operand if
> you only
> have one operand. Instead, we could always allow you to elide value:
> for the
> *first* operand. With some adjustments to the module directive
> types, our
> example module could look like this:
>
> module m1 {
> // Module directives
>
> // Jigsaw
> provides "3.4.5";
> provides alias: "acme" version: "3.4.5";
> requires "m2" version: "1.0+";
> permits "m3";
>
> // OSGi
> export name: "com.m1" version: "3.4.5";
> import BUNDLE version: ">1.0";
>
> // "value:" is assumed if only one operand exists.
> classpath { "m2.jar", "api.jar" };
> classpath "./classes";
>
> // Guice
> bind Foo.class annotatedWith: Red.class to: FooImpl.class;
> }
>
> Instead of forcing the first attribute name to be value, we could
> use a
> qualifier instead:
>
> /** Binds type T to a more specific version of T. */
> public @module bind<T> {
> *default* Class<T> type();
> Class<? extends Annotation> annotatedWith() default null;
> Class<? extends T> to() default null;
> }
>
> 2. We could elide the operand for boolean-typed attributes. For
> example:
>
> import name: "com.m2" version: ">1.0" optional;
> import name: "com.m3" version: "2" !optional;
>
> Of course, this could result in ambiguity if used for the first
> operand, in
> which case we should generate an error and force the user to
> explicitly
> specify the name and value.
>
> 3. We could support nested directives. The nested directives would be
> enclosed in curly braces as the final operand. For example:
>
> bind Foo.class to: FooImpl.class {
> bind Bar.class to: BarThatOnlyFooShouldUse.class;
> };
>
> If the directive type has a value attribute with an array type and the
> directive has only nested directives as the operand, we wouldn't be
> able to
> tell what the user intended, and we should generate an error.
>
> 4. We should support constants. For example:
>
> module m1 {
> String VERSION = "3.4.5";
> provides VERSION;
> export name: "com.m1" version: VERSION;
> }
>
> The compiler can tell the difference between a constant and a
> directive
> based on the type.
>
> 5. Java desperately needs literals for generic types. Guice has worked
> around their absence with
> TypeLiteral<http://google-guice.googlecode.com/svn/trunk/latest-javadoc/com/google/inject/TypeLiteral.html
> >.
> I know of two JSRs that have already copied this idea into their own
> APIs
> (299 and JAX-RS). I used Class<?> in the directive type examples
> above, but
> we probably want to define a new type (something like
> javax.lang.model.TypeMirror) that can be used easily at compile and
> run
> time.
>
> 6. An astute observer might ask how we can reference type literals
> for types
> that come from modules. The answer is that we defer resolution and
> validation of these types until after the modules have all been
> resolved.
> Obviously, a directive that imports a module can't directly
> reference types
> from that module. We can generate an error when we encounter these
> cases.
>
> Thanks,
> Bob
> _______________________________________________
> jsr294-modularity-eg mailing list
> jsr294-modularity-eg at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/jsr294-modularity-eg
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/jsr294-modularity-observer/attachments/20090508/801aa3db/attachment.html>
-------------- next part --------------
_______________________________________________
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