Optional Module Dependency
Roger Riggs
Roger.Riggs at Oracle.com
Mon May 23 07:59:14 PDT 2011
Hi Mandy,
It would helpful to developers if the compiler could check that classes
that refer to optional module classes will not fail verification at runtime
(due to type checking of the referred to classes).
It should be a compilation warning (or error) to refer to an optional class
in a way that will cause the referring class to fail verification if the
optional class is not available.
Can the semantics of optional modules be supported at compile
time as well as at runtime?
Thanks, Roger
On 5/20/11 4:54 PM, Roger Riggs wrote:
> Hi Mandy,
>
> Some comments on optional modules.
>
> The terminology of "optional method" might be improved.
> The method itself is not optional; but its behavior is based on the
> presence
> of classes within a module that may not be present. The behavior depends
> on code to check the (class, module or configuration) dependencies and
> (in many cases) throw an exception. The @RequireModule annotation only
> seems to be informative.
>
> The Module.isModulePresent(String mn) method might be renamed to
> isModuleAvailable
> since it includes the check for availability from the calling module.
>
> Does the module name being checked include the version ? I.e.
> "jdk.jaxp at 1.4"
> Some dependencies will be relative to specific versions of the modules.
>
> There is a potential disconnect between testing for a module name and the
> specific dependency on a class.
> Developers may not be clear on the relationship between the Class names
> that are used in the code and the module packaging. As an example, in
> the webrev of java.util.Properties, the code that has the dependency is
> not in the same class as the test for the module. There may be a
> mismatch
> between the module name and the understanding of its contents.
>
> In many cases, Class.forName is the right function because it is
> specific.
> But for classes that are not present and not going to be present, it
> is too slow to be repeated often and the method be fail fast since the
> contents of the module are/can be known.
> Alternatively, would it be possible to have a (ClassLoader) method to
> test if
> a class was available but without the side effect of loading it?
>
> The embedding of module names in the source code may too rigid and
> lead to maintenance issues since changing the dependency will require
> changing the code and generating an updated module with a new version
> number.
> This may be less of problem if the module namespace is very carefully
> managed and is generic enough to allow substitution of equivalent
> implementation modules.
> It depends on how much flexibility can be accomodated in module name
> and contents.
> Could the argument to isModulePresent be an indirect reference through
> the module-info contents? That might help decouple the source code
> from the
> module relationships.
>
> With respect the @RequireModule annotation on methods, I don't see that
> it provides much value. It documents the method as having a dependency
> but it will be hard to go beyond that. The method may or may not
> directly
> refer to the classes in the module. Without analyzing the control flow
> of the code it would be difficult for a tool to help the developer
> identify
> the dependencies that could not be met (at runtime) if the module was
> not present.
> (All modules have to be present at compile time.)
>
> When refering to types that are not (going to be) present, care must
> be taken
> to ensure the classfile can be verified without needing to evalate the
> missing
> types. This can be a bit subtle. In my experience, the coding patterns
> that are easy to understand limit where references to optional types
> may be
> used. If there is an annotation, it might be most useful if it is
> placed in the
> source at a point that reinforces the way verification works but I
> haven't
> thought this through. (For now, annotations can only appear in some
> places.)
>
> Thanks for the chance to comment,
> Roger
>
>
>> I have implemented the new @RequireAnnotation annotation and a new
>> API (Module.isModulePresent method) to test whether a module has been
>> resolved and linked.
>>
>> This note summarizes for the optional module dependency work:
>> http://openjdk.java.net/projects/jigsaw/doc/topics/optional.html
>>
>> Webrev:
>>
>> http://cr.openjdk.java.net/~mchung/jigsaw/webrevs/require-module-annotation/
>>
>> A few questions to discuss:
>> 1. There are some APIs that require another module depending on the
>> input parameters passed in. Bidi, JNDI, JMX are some examples. The
>> optional module is guaranteed to be present when the given input
>> parameter depends on it.
> The requirement is on the type of the input parameters (not the values).
>>
>> I wonder what the best practice or recommendation of using
>> @RequireAnnotation. For APIs that throws ModuleNotPresentException,
>> they clearly need to be annotated so that javadoc and other tools can
>> process them when appropriate.
>>
>> I think it's generally a good idea to annotate the source of an
>> optional dependency so that a tool can check if the optional
>> dependency is declared in the module-info.java (if there is no static
>> reference to types from the optional module; otherwise, the compiler
>> can detect that). If a module P didn't declare the optional
>> dependency on M and M is present, P will be compiled successfully.
>> At runtime, isModulePresent method will return false even if M is
>> present but it is not visible to P. P's module class loader will
>> fail to find a class in module M. This is the case the new test
>> "optional-method.sh" shows.
>>
>> I currently put this annotation in these APIs (e.g.
>> sun.text.bidi.BidiBase, com.sun.jmx.mbeanserver.Introspector, etc).
>> Alan mentioned in an offline discussion I had with him if it's more
>> appropriate to have a different annotation for this type of
>> dependency. Any other thought?
> Figure out the semantics of the annotation and then revisit the name.
>>
>> 2. Class.forName is the existing (legacy) approach to determine if a
>> class is present. In a modular world, a modular application can use
>> isModulePresent method instead. This leads to another question that
>> module P should statically reference types from an optional module M;
>> replace the use of Class.forName if it was to eliminate static
>> dependency (this is the approach JDK uses).
> Directly using references to classes may cause verification failures
> because in order to verify class P;
> the Class being referenced must be resolved. Check with those most
> knowledgable about the verifier.
>>
>> Mandy
>
More information about the jigsaw-dev
mailing list