[jsr294-modularity-eg] dependency declaration syntax...
Bryan Atsatt
bryan.atsatt at oracle.com
Fri May 8 16:47:34 EDT 2009
Alex Buckley wrote:
> Regarding #3 and #4, it's hard to imagine a dependency which doesn't
> have a target (name and optionally version). If granularity
> conventionally gets its own term, the target should too:
>
> requires package bar @ [1.0,2.0) flag1 k="v" flag2 ;
>
> 'requires' ID ID ['@' VER] ( ID ['=' '"' ID '"'] )* ';'
Yes, pulling the target out makes sense to me as well. (I'm not
convinced that version should be optional, but that is a different
discussion).
>
> To validate the ID/VER terms, a compiler passes them to an API along
> the lines of
> http://cr.openjdk.java.net/~mr/jigsaw/api/java/lang/module/ModuleSystem.html
>
Absolutely; the compiler must use something like this abstraction to
both validate *and* resolve the declarations to actual module instances.
I think we also need to consider an extension mechanism that will allow
additional metadata to be introduced without updating the JLS. We've run
around in circles about 'permits' and 'classpath', etc, so... we
probably do need to open this space up. (Bob, I realize that your
proposal certainly does this, but I'd like to also explore the simple
end of the spectrum--given that a module system MUST be involved in
validation/resolution, I don't see that we need the compiler to do any
type checking).
I prefer to think about this problem by exploring how the grammar might
be reified. So here's a stab at it, using 'imports'/'exports' instead of
'requires'/'provides':
public interface Identifier {
public String getName();
public String getVersion();
}
public interface AttributeContainer {
public boolean hasAttribute(String name);
public String getAttribute(String name);
public Set<String> getAttributeNames();
}
public interface Contract extends AttributeContainer {
public String getScope(); // e.g. "package", "module",
"service", etc.
public Identifier getTarget();
}
public class ModuleInfo implements Identifier, AttributeContainer {
// Single common parsing method
public static ModuleInfo define(byte[] moduleInfo) {...}
// Module system
public Identifier getModuleSystem() {...};
// Module name and version
public String getName() {...};
public String getVersion() {...};
// Dependencies
public Set<Contract> getImports() {...};
public Set<Contract> getExports() {...};
// Generic metadata
public boolean hasAttribute(String name) {...};
public String getAttribute(String name) {...};
public Set<String> getAttributeNames() {...};
}
In this simple model, 'permits' and 'classpath' or any other such
constructs have to be represented as attribute strings. So (switching
from '@' to ':' for the version separator):
module ID ':' VER {
'system' ID ':' VER ';'
'imports' ID ID [':' VER] ( ID ['=' '"' ID '"'] )* ';'
'exports' ID ID [':' VER] ( ID ['=' '"' ID '"'] )* ';'
( ID '=' '"' ID '"' ';' )*
}
module M : 5.0 {
system jigsaw:1.0;
imports module P:2.0 local vendor="acme";
imports module N:1.0+ optional;
exports module M:4.5+; // M v5.0 is compatible with 4.5+
permits = "module O"; // Module O is M's friend
}
module M : 5.0 {
system osgi:3.2;
imports package P:(1.0,2.0];
imports module N:1.0 optional;
exports package m;
classpath="jar1, jar2";
}
// Bryan
>
> Alex
>
> Bryan Atsatt wrote:
>> We have now discussed a number of options for keyword (requires,
>> provides, etc.) operand syntax:
>>
>> requires <operand>;
>>
>> I thought I'd try to enumerate the options so far...
>>
>> 1. Opaque string:
>>
>> requires foo at 1.3;
>>
>> 2. Granularity + opaque string:
>>
>> requires module foo at 1.3;
>>
>> 3. Granularity + unbounded key/value strings:
>>
>> requires package name=bar, version=1.1, vendor=acme;
>>
>> 4. Granularity + bounded, typed key/value pairs (annotation using
>> lowercase and without leading "@"):
>>
>> requires package(name=bar, version=1.1); // Really @package.
>>
>>
>> (We also discussed an "unbounded, typed key/value pairs" variant,
>> re-using just the annotation style syntax, but... Without a type
>> declaration mechanism, we would be in the inference business; I don't
>> think we want/need to take that step).
>>
>>
>> For each operand type, we need to consider how it would be reified in
>> a ModuleInfo class. I expect that for each keyword, we will need a
>> method that returns a Set<T>, where T is the operand type, e.g.
>>
>> public Set<String> getRequires();
>>
>> for the opaque string case (1). For cases 2 and 3, we would need to
>> create a new descriptor type to wrap the granularity and the string
>> or key/value strings. Case 4 seems to require a return type of
>> Object, necessitating a downcast.
>>
>>
>> I believe one constraint on the design space here is that a key/value
>> syntax needs to be unbounded: OSGi supports arbitrary attributes on
>> dependency declarations. This would imply a hack in the annotations
>> case (e.g. name=bar, version=1.1, attributes="key1=value1, ...").
>>
>> And while I do like the idea that annotations provide an easily
>> consumed grammar, the extra complexity here does not seem worth it
>> (even aside from Alex's concerns about compiler difficulties).
>>
>> So far, I think 3 provides the best balance of
>> functionality/clarity/simplicity/extensibility.
>>
>> // Bryan
>>
>> _______________________________________________
>> 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