6729739: Update JSR 277 API and javadoc
authorstanleyh
Thu Jul 24 17:30:52 2008 -0700 (16 months ago)
changeset 4242cc8f34251ff
parent 423594b22f33ae5
child 425af85cd8f8b56
6729739: Update JSR 277 API and javadoc
Summary: Updated the JSR 277 API and javadoc
Reviewed-by: mchung
src/share/classes/java/lang/Class.java
src/share/classes/java/lang/ClassLoader.java
src/share/classes/java/lang/ModuleInfo.java
src/share/classes/java/lang/annotation/ElementType.java
src/share/classes/java/module/ImportDependency.java
src/share/classes/java/module/ImportOverridePolicy.java
src/share/classes/java/module/ImportPolicy.java
src/share/classes/java/module/Module.java
src/share/classes/java/module/ModuleContent.java
src/share/classes/java/module/ModuleDefinition.java
src/share/classes/java/module/ModuleDependency.java
src/share/classes/java/module/ModuleInitializer.java
src/share/classes/java/module/ModuleSystem.java
src/share/classes/java/module/Modules.java
src/share/classes/java/module/PackageDependency.java
src/share/classes/java/module/Repository.java
src/share/classes/java/module/RepositoryMetadata.xml
src/share/classes/java/module/Version.java
src/share/classes/java/module/VersionConstraint.java
src/share/classes/java/module/annotation/AllowShadowing.java
src/share/classes/java/module/annotation/Attribute.java
src/share/classes/java/module/annotation/Attributes.java
src/share/classes/java/module/annotation/ClassesDirectoryPath.java
src/share/classes/java/module/annotation/ExportLegacyClasses.java
src/share/classes/java/module/annotation/ExportResources.java
src/share/classes/java/module/annotation/ImportModule.java
src/share/classes/java/module/annotation/ImportPolicyClass.java
src/share/classes/java/module/annotation/JarLibraryPath.java
src/share/classes/java/module/annotation/MainClass.java
src/share/classes/java/module/annotation/ModuleInitializerClass.java
src/share/classes/java/module/annotation/NativeLibraryPath.java
src/share/classes/java/module/annotation/NativeLibraryPaths.java
src/share/classes/java/module/annotation/PlatformBinding.java
src/share/classes/java/module/annotation/ResourceModuleConstraint.java
src/share/classes/java/module/annotation/ResourceTargetConstraint.java
src/share/classes/java/module/annotation/ServiceProvider.java
src/share/classes/java/module/annotation/ServiceProviders.java
src/share/classes/java/module/annotation/Services.java
src/share/classes/java/module/annotation/Version.java
src/share/classes/java/module/annotation/package-info.java
src/share/classes/java/module/package-info.java
src/share/classes/java/util/ResourceBundle.java
src/share/classes/java/util/ServiceLoader.java
src/share/classes/sun/module/ModuleLauncher.java
src/share/classes/sun/module/bootstrap/BootstrapModuleSystem.java
src/share/classes/sun/module/bootstrap/BootstrapRepository.java
src/share/classes/sun/module/bootstrap/VirtualModuleDefinitions.java
src/share/classes/sun/module/config/ImportOverridePolicyFile.java
src/share/classes/sun/module/core/ExtensionModuleLoader.java
src/share/classes/sun/module/core/ModuleImpl.java
src/share/classes/sun/module/core/ModuleLoader.java
src/share/classes/sun/module/core/ModuleSystemImpl.java
src/share/classes/sun/module/core/ModuleUtils.java
src/share/classes/sun/module/osgi/OSGiRepository.java
src/share/classes/sun/module/repository/AbstractRepository.java
src/share/classes/sun/module/repository/LocalRepository.java
src/share/classes/sun/module/repository/RepositoryConfig.java
src/share/classes/sun/module/repository/URLRepository.java
src/share/classes/sun/module/repository/cache/Cache.java
src/share/classes/sun/module/repository/cache/LocalModuleContent.java
src/share/classes/sun/module/repository/cache/LocalModuleDefInfo.java
src/share/classes/sun/module/repository/cache/URLModuleContent.java
src/share/classes/sun/module/tools/JRepo.java
test/java/module/modinit/RunMTest.java
test/java/module/repository/LocalRepositoryTest.java
test/java/module/repository/MetadataCompareTest.java
test/java/module/repository/RepositoryConfigTest.java
test/java/module/repository/RepositoryFactoryTest.java
test/java/module/repository/RepositoryTest.java
test/java/module/repository/ShutdownOnExitTest.java
test/java/module/repository/Test6574851.java
test/java/module/repository/Test6574852.java
test/java/module/repository/URLRepoInstallTest.java
test/java/module/repository/URLRepositoryReloadTest.java
test/java/module/repository/URLRepositoryTest.java
test/java/module/repository/VisibilityPolicyTest.java
test/java/module/service/src/reposerv/client/Main.java
test/java/module/version/VersionTest.java
--- a/src/share/classes/java/lang/Class.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/lang/Class.java Thu Jul 24 17:30:52 2008 -0700
@@ -739,6 +739,7 @@ public final
}
/**
+ * <span style="color: rgb(204, 0, 0);"><B>[NEW]</B></span>
* Returns the information of the module that this class is a member of,
* or null if this class is not a member of any module.
*
--- a/src/share/classes/java/lang/ClassLoader.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/lang/ClassLoader.java Thu Jul 24 17:30:52 2008 -0700
@@ -253,15 +253,20 @@ public abstract class ClassLoader {
}
/**
- * Returns the {@code Module} instance this {@code ClassLoader} is
- * associated with.
- *
- * <p>If this class loader is the module class loader of a
- * {@link Module}, this method returns that {@code Module} object.
- * Otherwise, it returns null.
- *
- * @return the {@code Module} instance this {@code ClassLoader} is
- * associated with or null.
+ * <span style="color: rgb(204, 0, 0);"><B>[NEW]</B></span>
+ * Returns the {@code Module} instance associated with this
+ * {@code ClassLoader}.
+ *
+ * <p>If this class loader is the
+ * {@linkplain java.module.Module#getClassLoader module class loader}
+ * of a {@link Module} instance, this method returns that
+ * {@code Module} object. Otherwise, it returns null.
+ *
+ * @return the {@code Module} instance associated with
+ * this {@code ClassLoader}, or {@code null}.
+ * @throws IllegalStateException if a {@code Module} instance is
+ * associated with this {@code ClassLoader} but the
+ * {@code Module} instance has not been fully initialized.
* @since 1.7
*/
public Module getModule() {
@@ -1579,6 +1584,7 @@ public abstract class ClassLoader {
}
/**
+ * <span style="color: rgb(204, 0, 0);"><B>[NEW]</B></span>
* Returns a <tt>ModuleInfo</tt> that has been defined by this class loader
* or any of its ancestors. </p>
*
@@ -1593,6 +1599,7 @@ public abstract class ClassLoader {
}
/**
+ * <span style="color: rgb(204, 0, 0);"><B>[NEW]</B></span>
* Returns all of the <tt>ModuleInfo</tt> defined by this class loader and
* its ancestors. </p>
*
--- a/src/share/classes/java/lang/ModuleInfo.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/lang/ModuleInfo.java Thu Jul 24 17:30:52 2008 -0700
@@ -38,8 +38,9 @@ import sun.module.annotation.*;
* <p>
* {@code ModuleInfo} has no public constructor. Instead {@code ModuleInfo}
* objects are constructed automatically by the Java Virtual Machine as modules
- * are loaded and by calls to the {@code defineModuleInfo} method in the class
- * loader.
+ * are loaded and by calls to the
+ * {@link ClassLoader#defineModuleInfo defineModuleInfo}
+ * method in the class loader.
* <p>
* Within each {@code ClassLoader} instance all classes from the same
* java module have the same {@code ModuleInfo} object. The static methods
@@ -47,7 +48,6 @@ import sun.module.annotation.*;
* modules known to the current class loader to be found.
*
* @see java.lang.Class#getModuleInfo
- * @see java.lang.ClassLoader#defineModuleInfo
* @see java.lang.ClassLoader#findModuleInfo
* @since 1.7
*/
@@ -183,7 +183,7 @@ public final class ModuleInfo implements
* the module has no members.
*
* @return an array of the names of all member packages
- * @throws UnsupporterOperationException if the packages cannot be
+ * @throws UnsupportedOperationException if the packages cannot be
* determined.
*/
public String[] getMemberPackages() {
@@ -193,15 +193,15 @@ public final class ModuleInfo implements
/**
* Returns an array of String objects reflecting the binary names of all
* packages that have exported classes and interfaces that are a member
- * of this module. The names returned by this method are a subset of the
- * names returned by {@link #getMemberPackages}.
+ * of this module. The names returned by this method must be a subset of
+ * the names returned by {@link #getMemberPackages}.
*
* <p>The elements in the array returned are not sorted and are not in
* any particular order. This method returns an array of length 0 if
* the module has no members that are exported types.
*
* @return an array of the names of all packages that have exported types.
- * @throws UnsupporterOperationException if the packages cannot be
+ * @throws UnsupportedOperationException if the packages cannot be
* determined.
*/
public String[] getExportedPackages() {
@@ -217,7 +217,7 @@ public final class ModuleInfo implements
* the module has no exported types.
*
* @return an array of the names of all exported types.
- * @throws UnsupporterOperationException if the exported types cannot be
+ * @throws UnsupportedOperationException if the exported types cannot be
* determined.
*/
public String[] getExportedClasses() {
@@ -238,6 +238,59 @@ public final class ModuleInfo implements
return packages;
}
+ /**
+ * Returns an array of String objects reflecting the fully-qualified binary
+ * names of all {@linkplain java.util.ServiceLoader services} that
+ * are defined in this module.
+ *
+ * <p>The elements in the array returned are not sorted and are not in
+ * any particular order. This method returns an array of length 0 if
+ * the module has no service.
+ *
+ * @return an array of the names of all defined services
+ * @throws UnsupportedOperationException if the defined services
+ * cannot be determined.
+ */
+ public String[] getDefinedServices() {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ /**
+ * Returns an array of String objects reflecting the fully-qualified binary
+ * names of all {@linkplain java.util.ServiceLoader services} that
+ * are implemented by service providers in this module.
+ *
+ * <p>The elements in the array returned are not sorted and are not in
+ * any particular order. This method returns an array of length 0 if
+ * the module has no service provider for any service.
+ *
+ * @return an array of the names of all implemented services
+ * @throws UnsupportedOperationException if the implemented services
+ * cannot be determined.
+ */
+ public String[] getImplementedServices() {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
+ /**
+ * Returns an array of String objects reflecting the fully-qualified binary
+ * names of all {@linkplain java.util.ServiceLoader service providers}
+ * in this module for the given service.
+ *
+ * <p>The elements in the array returned are not sorted and are not in
+ * any particular order. This method returns an array of length 0 if
+ * the module has no service providers for the given service.
+ *
+ * @paramm service the name of the service
+ * @return an array of the names of all service providers for the given
+ * service
+ * @throws UnsupportedOperationException if the service providers
+ * cannot be determined.
+ */
+ public String[] getServiceProviders(String service) {
+ throw new UnsupportedOperationException("Not implemented yet.");
+ }
+
private static final class Loader extends ClassLoader {
Loader() {
super(null);
--- a/src/share/classes/java/lang/annotation/ElementType.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/lang/annotation/ElementType.java Thu Jul 24 17:30:52 2008 -0700
@@ -62,6 +62,7 @@ public enum ElementType {
PACKAGE,
/**
+ * <span style="color: rgb(204, 0, 0);"><B>[NEW]</B></span>
* Module declaration
*
* @since 1.7
--- a/src/share/classes/java/module/ImportDependency.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/ImportDependency.java Thu Jul 24 17:30:52 2008 -0700
@@ -32,41 +32,50 @@ import java.util.Set;
/**
- * This interface represents an import dependency in a module definition.
+ * This interface represents a generic import dependency on a module definition.
+ * All import dependency interfaces must extend this interface.
* <p>
* @see java.module.VersionConstraint
* @see java.io.Serializable
*
* @since 1.7
* @serial include
+ * @see ModuleDependency
+ * @see PackageDependency
*/
public interface ImportDependency extends java.io.Serializable {
/**
- * Returns the name of the import.
+ * Returns the name in the context of this {@code ImportDependency}.
*
- * @return the name of the import.
+ * @return the name in the context of this {@code ImportDependency}.
*/
public String getName();
/**
- * Returns the version constraint of the import.
+ * Returns the version constraint in the context of this
+ * {@code ImportDependency}.
*
- * @return the version constraint of the import.
+ * @return the version constraint in the context of this
+ * {@code ImportDependency}.
*/
public VersionConstraint getVersionConstraint();
/**
- * Returns true if the import is re-exported; otherwise, returns false.
+ * Returns true if this {@code ImportDependency} is re-exported;
+ * otherwise, returns false.
*
- * @return true if the import is re-exported; otherwise, returns false.
+ * @return true if this {@code ImportDependency} is re-exported;
+ * otherwise, returns false.
*/
public boolean isReexported();
/**
- * Returns true if the import is optional; otherwise, returns false.
+ * Returns true if this {@code ImportDependency} is optional;
+ * otherwise, returns false.
*
- * @return true if the import is optional; otherwise, returns false.
+ * @return true if this {@code ImportDependency} is optional;
+ * otherwise, returns false.
*/
public boolean isOptional();
--- a/src/share/classes/java/module/ImportOverridePolicy.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/ImportOverridePolicy.java Thu Jul 24 17:30:52 2008 -0700
@@ -29,19 +29,12 @@ import java.util.Map;
import java.util.Map;
/**
- * This interface represents the import override policy in the JAM
- * module system. The import override policy allows deployers to narrow
- * the version constraints in the import dependencies of a specific
- * module definition to control the resolution in the module system.
+ * This interface represents an import override policy in the JAM
+ * module system. An import override policy allows deployers to
+ * control the resolution of a module instance in the JAM module system
+ * by narrowing the version constraints in the import dependencies.
* <p>
- * During the module initialization in the JAM module system, the
- * {@link #narrow(ModuleDefinition, Map) <tt>narrow</tt>} method of the
- * {@code ImportOverridePolicy} object returned from
- * {@link Modules#getImportOverridePolicy()} is
- * invoked before the import policy of the module instance is executed.
- * <p>
- * @see java.module.ImportDependency;
- * @see java.module.ImportPolicy
+ * @see java.module.ImportDependency
* @see java.module.ModuleDefinition
* @see java.module.VersionConstraint
*
@@ -51,20 +44,21 @@ public interface ImportOverridePolicy {
/**
* Returns a map of import dependencies and overridden version constraints
- * for the module definition. The returned map must contain the same set of
- * import dependencies as in the given {@code map}.
+ * for the specified module definition.
* <p>
- * For each import dependency, the overridden version constraint must be
- * within the boundary of the original version constraint that was
- * specified in the module definition at build time. Otherwise, module
- * initialization will fail.
+ * The returned map must contain the same set of import dependencies as
+ * in the given {@code map}. For each import dependency in the returned
+ * map, the overridden version constraint must be within the boundary of
+ * the original version constraint of the import dependency
+ * that is returned from the specified module definition's
+ * {@link ModuleDefinition#getImportDependencies() getImportDependencies}
+ * method.
*
* @param importer the importing module definition.
* @param map an unmodifiable map of import dependencies and
* overridden version constraints.
* @return the map of import dependencies and overridden version
- * constraints. It contains the same set of import dependencies as
- * in the given {@code map}.
+ * constraints.
*/
public abstract Map<ImportDependency, VersionConstraint> narrow(ModuleDefinition importer,
Map<ImportDependency, VersionConstraint> map);
--- a/src/share/classes/java/module/ImportPolicy.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/ImportPolicy.java Thu Jul 24 17:30:52 2008 -0700
@@ -68,7 +68,7 @@ public interface ImportPolicy {
* constraints for resolving, and it is passed in one of the parameters of
* this method.
* <p>
- * All implementations should return a map of import dependencies and
+ * Implementations must return a map of import dependencies and
* version constraints after resolving the imports. If an import cannot
* be resolved and the import dependency is mandatory (i.e. non-optional),
* {@code UnsatisfiedDependencyException} must be thrown. If an import
--- a/src/share/classes/java/module/Module.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/Module.java Thu Jul 24 17:30:52 2008 -0700
@@ -28,21 +28,20 @@ import java.util.List;
import java.util.List;
/**
- * This class represents a reified module instance in a module system.
+ * This class represents a module instance in a module system.
+ * A module instance has its own copies of the classes defined by its
+ * {@linkplain ModuleDefinition module definition}.
+ * A newly created module instance is <i>uninitialized</i>.
+ * A <i>fully initialized</i> module instance is one which
+ * has completed the <a href="ModuleSystem.html#Initialization">
+ * initialization</a> successfully.
*
- * Each {@code Module} instance has its own copies of the classes defined
- * by the module definition, each with their own independent static
- * state. Each {@code Module} instance is also interconnected with
- * instances of the modules it imports.
- * <p>
* @see java.lang.ClassLoader
* @see java.module.ModuleDefinition
* @see java.module.ModuleSystemPermission
* @since 1.7
*/
-public abstract class Module
-{
- private static ModuleSystem defaultImpl = null;
+public abstract class Module {
/**
* Creates a new {@code Module} instance.
@@ -59,12 +58,37 @@ public abstract class Module
public abstract ModuleDefinition getModuleDefinition();
/**
- * Returns the classloader associated with this {@code Module}.
+ * Returns the class loader associated with this {@code Module}. This
+ * class loader is also called the <i>module class loader</i>.
+ * <p>
+ * Module class loader implementations must be able to load all
+ * classes and resources in this {@code Module} if this {@code Module}
+ * has been <i>fully initialized</i>. The module class loader
+ * implementation must return this {@code Module} in its
+ * {@link ClassLoader#getModule() getModule}
+ * method if this {@code Module} is fully initialized.
+ * <p>
+ * Module class loader implementations must support parallel
+ * classloading as defined in Java SE 7 to enable searches that cross
+ * class loader boundaries from multiple threads without deadlocks.
+ * <p>
+ * Module class loader implementations may search classes and resources
+ * from the imported module instances by delegating to their module
+ * class loaders, based on how the imports were
+ * <a href="ModuleSystem.html#Resolution">resolved</a> during
+ * module initialization. The delegation model and the search model for
+ * classes and resources are module system specific.
+ * <p>
+ * Module class loader implementations must continue to make all
+ * classes and resources in this {@code Module} visible to its
+ * importing module instances after this {@code Module} instance is
+ * {@linkplain ModuleSystem#releaseModule released} from its module
+ * system.
* <p>
* If a security manager is present, and the caller's class loader is not
- * null and the caller's class loader is not the same as or an ancestor of
- * the class loader for the module instance whose class loader is
- * requested, then this method calls the security manager's
+ * {@code null} and the caller's class loader is not the same as or an
+ * ancestor of the class loader for the module instance whose class loader
+ * is requested, then this method calls the security manager's
* {@code checkPermission} method with a
* {@code RuntimePermission("getClassLoader")} permission to ensure it's
* ok to access the class loader for this {@code Module}.
@@ -73,6 +97,8 @@ public abstract class Module
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method denies access to the class loader
* for this {@code Module}.
+ * @throws IllegalStateException if the class loader has not yet been
+ * created during module initialization.
*/
public abstract ClassLoader getClassLoader();
@@ -80,21 +106,35 @@ public abstract class Module
* Returns an unmodifiable list of imported module instances.
*
* @return an unmodifiable list of imported module instances.
+ * @throws IllegalStateException if the list of imported
+ * module instances has not yet been created during module
+ * initialization.
*/
public abstract List<Module> getImportedModules();
/**
- * Check if deep validation is supported on this {@code Module}.
+ * Returns true if this {@code Module} supports
+ * <a href="ModuleSystem.html#DeepValidation">deep validation</a>;
+ * otherwise, returns false.
+ * <p>
+ * This {@code Module} may support deep validation if its
+ * {@linkplain ModuleDefinition#getMemberClasses() member classes}
+ * and all the member classes from the {@code Module}s
+ * imported transitively by this {@code Module} are known.
*
* @return true if deep validation is supported; otherwise, returns false.
+ * @see #deepValidate()
*/
public abstract boolean supportsDeepValidation();
/**
- * Perform deep validation on this {@code Module}.
+ * Performs <a href="ModuleSystem.html#DeepValidation">deep validation</a> on this
+ * {@code Module}.
*
- * @throws UnsupportedOperationException if deep validation is not supported.
+ * @throws UnsupportedOperationException if this {@code Module} does not
+ * support deep validation.
* @throws ModuleInitializationException if deep validation fails.
+ * @see #supportsDeepValidation()
*/
public abstract void deepValidate() throws ModuleInitializationException;
--- a/src/share/classes/java/module/ModuleContent.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/ModuleContent.java Thu Jul 24 17:30:52 2008 -0700
@@ -30,6 +30,7 @@ import java.io.ByteArrayOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
+import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.util.Set;
@@ -51,8 +52,8 @@ public interface ModuleContent {
/**
* Returns true if the specified entry is found.
* <p>
- * The entry's name is specified using {@code '/'} as path separator; it
- * has no leading {@code '/'}.
+ * The entry's name must be specified using {@code '/'} as the path
+ * separator; it must have no leading {@code '/'}.
*
* @param name the name of the entry.
* @return true if the specified entry is found; otherwise, return false.
@@ -64,8 +65,8 @@ public interface ModuleContent {
* Returns the readable byte channel for the specified entry or
* {@code null} if not found.
* <p>
- * The entry's name is specified using {@code '/'} as path separator; it
- * has no leading {@code '/'}.
+ * The entry's name must be specified using {@code '/'} as the path
+ * separator; it must have no leading {@code '/'}.
*
* @param name the name of the entry.
* @return the readable byte channel for the specified entry or
@@ -78,8 +79,8 @@ public interface ModuleContent {
* Returns the read-only byte buffer for the specified entry or
* {@code null} if not found.
* <p>
- * The entry's name is specified using {@code '/'} as path separator; it
- * has no leading {@code '/'}.
+ * The entry's name must be specified using {@code '/'} as the path
+ * separator; it must have no leading {@code '/'}.
*
* @param name the name of the entry.
* @return the readable byte channel for the specified entry or
@@ -91,8 +92,8 @@ public interface ModuleContent {
/**
* Returns an unmodifiable set of the names of the entries.
* <p>
- * The entry's name is specified using {@code '/'} as path separator; it
- * has no leading {@code '/'}.
+ * Each entry's name uses {@code '/'} as the path separator with no
+ * leading {@code '/'}.
*
* @return an unmodifiable set of the names of the entries.
* @throws IOException if an I/O error occurs.
@@ -110,6 +111,14 @@ public interface ModuleContent {
public File getNativeLibrary(String libraryName) throws IOException;
/**
+ * Returns the location that is the origin of the content. The location
+ * may be {@code null}.
+ *
+ * @return the location that is the origin of the content.
+ */
+ public URL getLocation();
+
+ /**
* Returns an unmodifiable set of code signers. If there is no code
* signer, an empty set is returned.
*
--- a/src/share/classes/java/module/ModuleDefinition.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/ModuleDefinition.java Thu Jul 24 17:30:52 2008 -0700
@@ -32,80 +32,75 @@ import java.util.Set;
import java.util.Set;
/**
- * This class represents a reified module definition in a module system.
- * <p>
- * A {@code ModuleDefinition} identifies a logical module in a module system.
- * It specifies which classes and resources are provided by the module, and
- * what the module imports and exports. The classes in the
- * {@code ModuleDefinition} could be from one or more Java packages.
- * {@code ModuleDefinition}s from one or more module systems can coexist in
- * the same Java virtual machine (JVM) instance. A {@code ModuleDefinition}
- * is inherently stateless, and its identity is represented by its
- * {@link #getName() <tt>name</tt>} and
- * {@link #getVersion() <tt>version</tt>}.
- * <p>
- * A module definition can be instantiated by its module system creating a
- * {@code Module} instance at runtime, using the
- * {@link #getModuleInstance() <tt>getModuleInstance</tt>} method or the
- * module system's
- * {@link ModuleSystem#getModule(ModuleDefinition)
- * <tt>getModule(ModuleDefinition)</tt>} method.
- * <p>
- * The name of a {@code ModuleDefinition} is a case-sensitive string.
- * The Java Module System does not enforce any naming convention on module
- * definitions; each module system can have its own naming convention for its
- * module definitions.
- * <p>
- * Each {@code ModuleDefinition} contains zero or more module
- * attributes. Each module attribute is a name-value pair of case-sensitive
- * strings. Module attributes are generally defined and used by components
- * at a higher layer on top of the Java Module System.
- * <p>
- * Each {@code ModuleDefinition} defines which classes that are part of
- * the module, and the information can be obtained using the
- * {@link getMemberClasses()} method.
- * <p>
- * Each {@code ModuleDefinition} defines which classes and resources are visible
- * externally to other modules though the export mechanism. The export
- * mechanisms for classes and resources serve different purposes:
+ * This class represents a module definition in a module system.
+ * A module definition identifies a logical module in a module system
+ * within the Java Module System. A module definition implementation is
+ * responsible for exposing the information in the metadata of a module
+ * and exposing the content of that module; the format of the metadata
+ * and the content of a module are specific to the corresponding
+ * module system.
+ * <p>
+ * A module definition must have a {@linkplain #getName() name}
+ * and a {@linkplain #getVersion() version}. The Java Module
+ * System does not enforce any naming convention on module definitions;
+ * each module system may enforce its own naming convention on its module
+ * definitions. The version of a module definition must conform to the
+ * {@linkplain Version versioning scheme} in the Java Module System. A
+ * module definition implementation for a module system must be responsible
+ * for translating the versioning information in a module based on this
+ * versioning scheme, if the module system uses a different scheme.
+ * <p>
+ * A module definition may have one or more
+ * {@linkplain #getAnnotations() annotations}.
+ * A module definition may also have one or more
+ * {@linkplain #getAttribute(String) module attributes}. Each module
+ * attribute is a name-value pair of case-sensitive strings, and module
+ * attributes are generally defined and used by components at a higher
+ * layer on top of the Java Module System.
+ * <p>
+ * A module definition has {@linkplain #getMemberClasses() members} that
+ * are classes and resources provided by the module. The classes are from
+ * one or more Java packages.
+ * <p>
+ * A module definition may define which classes and resources are visible
+ * externally to other modules in the Java Module System through the export
+ * mechanism. The export mechanisms for classes and resources serve
+ * different purposes:
* <ul>
* <li><p>The class export defines which classes are visible to other
- * modules at build-time and after the module is interconnected
- * at runtime. When Java code is compiled against other imported
- * modules at build-time, the compiler would leverage the class
- * export of the imported modules to ensure only exported classes
- * can be compiled against. At runtime, a module system could also
- * leverage the class export to determine how to search classes
- * efficiently across imported modules in a module.
- * The class export information can be obtained using the
- * {@link #getExportedClasses()} method and the
- * {@link #isClassExported(String)} method.</p></li>
+ * modules at build-time and at runtime. A compiler may use the
+ * information to enforce that only exported classes in a module
+ * can be compiled against other modules. At runtime, a module
+ * system may leverage the information to search classes more
+ * efficiently across modules.
+ * The class export's information can be obtained using the
+ * {@link #getExportedClasses() getExportedClasses},
+ * {@link #getExportedPackageDefinitions() getExportedPackageDefinitions}, and
+ * {@link #isClassExported(String) isClassExported}
+ * methods.</p></li>
*
* <li><p>The resource export defines which resources are visible to
- * other modules at runtime after the module is interconnected.
- * A module system could leverage the resource export to search
- * resources efficiently across imported modules; however, at
- * build-time, the compiler compiles classes but not resources,
- * thus the resource export is not used at all.
- * Similarly, the resource export information can be obtained
- * using the {@link #getExportedResources()} method and the
- * {@link #isResourceExported(String)} method.</p></li>
+ * other modules at runtime. A module system may leverage the
+ * information to search resources more efficiently across
+ * modules.
+ * The resource export's information can be obtained using the
+ * {@link #getExportedResources() getExportedResources} and
+ * {@link #isResourceExported(String) isResourceExported}
+ * methods.</p></li>
* </ul>
* <p>
- * Each {@code ModuleDefinition} also defines its dependencies upon other
- * module definitions using the import mechanism. These imports are expressed
- * as a list of {@link ImportDependency} instances which are returned by the
- * {@link #getImportDependencies()} method. At runtime, the module system of
- * the {@code ModuleDefinition} is the one responsible to recognize and
- * resolve these imports accordingly when it creates a module instance from
- * the module definition.
- * <p>
- * Some implememtations of {@code ModuleDefinition} may not support the
- * {@link #getExportedClasses()}, {@link #getMemberClasses()}, and
- * {@link #getModuleContent()} methods; invoking these methods may throw
+ * A module definition may define its dependencies upon other modules
+ * using the {@linkplain #getImportDependencies() import} mechanism.
+ * A module definition must express its import dependencies as a list
+ * of {@link ImportDependency} instances.
+ * <p>
+ * A module definition implementation may not support the
+ * {@link #getExportedClasses() getExportedClasses},
+ * {@link #getMemberClasses() getMemberClasses}, and
+ * {@link #getModuleContent() getModuleContent} methods;
+ * calling these methods may throw
* {@code UnsupportedOperationException}.
*
- * <p>
* @see java.module.Module
* @see java.module.ModuleSystem
* @see java.module.Repository
@@ -146,20 +141,32 @@ public abstract class ModuleDefinition {
/**
* Returns the value corresponding to the specified attribute name that is
- * associated with this {@code ModuleDefinition}. If this
- * {@code ModuleDefinition} has attributes with duplicate names, the value
- * of the attribute in the last occurrence is returned.
+ * associated with this {@code ModuleDefinition}.
*
* @param name the name of the attribute.
- * @return the value of the attribute. Returns null if the specified
- * attribute name is not found.
+ * @return the value of the attribute. Returns {@code null} if the
+ * specified attribute name is not found.
*/
public abstract String getAttribute(String name);
/**
- * Returns an unmodifiable list of all import dependencies. The order of
- * the import dependencies in the list follows the declared import order in
- * the {@code ModuleDefinition}.
+ * Returns an unmodifiable list of all import dependencies in this
+ * {@code ModuleDefinition}. The order of the import dependencies in
+ * the list must follow the declared import order in this
+ * {@code ModuleDefinition}.
+ * <p>
+ * If this {@code ModuleDefinition} has a module dependency with another
+ * module, the dependency must be represented by an implementation of
+ * {@link ModuleDependency} in the list.
+ * <p>
+ * If this {@code ModuleDefinition} has an package dependency with another
+ * module, the dependency must be represented by an implementation of
+ * {@link PackageDependency} in the list.
+ * <p>
+ * If this {@code ModuleDefinition} has an import dependency with another
+ * module that is neither a module dependency nor a package dependency, the
+ * dependency must not be represented by an implementation of
+ * {@link ModuleDependency} or {@link PackageDependency} in the list.
*
* @return an unmodifiable list of all import dependencies.
*/
@@ -183,18 +190,23 @@ public abstract class ModuleDefinition {
/**
* Returns the name of the main class in this {@code ModuleDefinition}.
+ * <p>
+ * The main class must be declared {@code public}. It must have a
+ * {@code main} method which is declared {@code public}, {@code static},
+ * and {@code void}; the {@code main} method must accept a single argument
+ * that is an array of strings.
*
* @return the name of the main class if it exists; otherwise returns null.
*/
public abstract String getMainClass();
/**
- * Returns an unmodifiable set of the names of the classes that are members
- * of this {@code ModuleDefinition}.
+ * Returns an unmodifiable set of the names of the member classes in
+ * this {@code ModuleDefinition}.
*
* @return The unmodifiable set of the names of the member classes.
* @throws UnsupportedOperationException if the set of member classes
- * in this {@code ModuleDefinition} cannot be determined.
+ * cannot be determined.
*/
public abstract Set<String> getMemberClasses();
@@ -208,12 +220,13 @@ public abstract class ModuleDefinition {
/**
* Returns an unmodifiable set of the names of the classes that are
- * exported by this {@code ModuleDefinition}. This is a subset of the
- * classes returned by {@link #getMemberClasses() getMemberClasses()}.
+ * exported by this {@code ModuleDefinition}. This must be a subset of the
+ * classes returned by the {@link #getMemberClasses() getMemberClasses}
+ * method.
*
* @return The unmodifiable set of the names of the exported classes.
* @throws UnsupportedOperationException if the set of exported classes
- * in this {@code ModuleDefinition} cannot be determined.
+ * cannot be determined.
*/
public abstract Set<String> getExportedClasses();
@@ -228,17 +241,17 @@ public abstract class ModuleDefinition {
public abstract Set<PackageDefinition> getExportedPackageDefinitions();
/**
- * Returns true if the specified class is exported by this
+ * Returns true if the specified class may be exported by this
* {@code ModuleDefinition}; returns false otherwise.
* <p>
* If this method returns {@code true} for a specified class, it implies
- * neither that the class is actually found in the module definition, nor
- * the class is guaranteed to be loaded successfully through the
- * {@link ClassLoader#loadClass(String) loadClass} methods of
- * the {@code ClassLoader} object in the module instance at runtime.
+ * neither that the class actually exists in the module definition, nor
+ * the class will be loaded successfully through the
+ * {@link ClassLoader#loadClass(String) loadClass} method of
+ * the {@code ClassLoader} object of the module instance at runtime.
*
* @param name the name of the class.
- * @return true if the class is exported; otherwise, returns false.
+ * @return true if the class may be exported; otherwise, returns false.
*/
public boolean isClassExported(String name) {
try {
@@ -254,22 +267,25 @@ public abstract class ModuleDefinition {
* Returns an unmodifiable set of the path of the resources exported by
* this {@code ModuleDefinition}.
* <p>
- * Each resource's path is specified using {@code '/'} as path
- * separator, with no leading {@code '/'}.
+ * Each resource's path uses {@code '/'} as the path separator and with no
+ * leading {@code '/'}.
*
* @return The unmodifiable set of the path of the exported resources.
* @throws UnsupportedOperationException if the set of exported resources
- * in this {@code ModuleDefinition} cannot be determined.
+ * cannot be determined.
*/
public abstract Set<String> getExportedResources();
/**
- * Returns true if the specified resource is exported by this
+ * Returns true if the specified resource may be exported by this
* {@code ModuleDefinition}; returns false otherwise.
* <p>
+ * The resource's path uses {@code '/'} as the path separator and with no
+ * leading {@code '/'}.
+ * <p>
* If this method returns {@code true} for a specified resource, it implies
- * neither that the resource is actually found in the module definition, nor
- * the resource is guaranteed to be loaded successfully through the
+ * neither that the resource actually exists in the module definition, nor
+ * the resource will be loaded successfully through the
* {@link ClassLoader#getResource(String) getResource},
* {@link ClassLoader#getResourceAsStream(String) getResourceAsStream},
* or {@link ClassLoader#getResources(String) getResources}
@@ -277,7 +293,7 @@ public abstract class ModuleDefinition {
* instance at runtime.
* @param path A {@code '/'} delimited path (e.g. {@code x/y/Z.class})
- * @return true if the resource in the path is exported.
+ * @return true if the resource in the path may be exported.
*/
public boolean isResourceExported(String path) {
try {
@@ -290,15 +306,19 @@ public abstract class ModuleDefinition {
/**
* Returns a {@code Module} instance for the specified
- * {@code ModuleDefinition} in the {@code ModuleSystem}. The {@code Module}
- * is initialized and ready to use. Equivalent to:
+ * {@code ModuleDefinition} from its {@code ModuleSystem}.
+ * The {@code Module} instance must be fully initialized
+ * and its module classloader must be ready for classloading.
+ * Equivalent to:
* <pre>
* getModuleSystem().getModule(this);</pre>
*
- * @return a {@code Module} instance of the {@code ModuleDefinition}.
- * @throws ModuleInitializationException if the module instance cannot be initialized.
+ * @return a {@code Module} instance of this {@code ModuleDefinition}.
+ * @throws ModuleInitializationException if the module system fails to initialize
+ * the module instance.
* @throws IllegalStateException if this {@code ModuleDefinition} has
- * already been disabled.
+ * already been disabled in the module system.
+ * @see ModuleSystem#getModule(ModuleDefinition)
*/
public final Module getModuleInstance() throws ModuleInitializationException {
return getModuleSystem().getModule(this);
@@ -326,13 +346,13 @@ public abstract class ModuleDefinition {
public abstract List<Annotation> getAnnotations();
/**
- * Checks if the entire content of this {@code ModuleDefinition} is stored
- * locally.
- *
- * @return true if the entire content of this {@code ModuleDefinition} is
- * stored locally; otherwise, returns false.
- */
- public boolean isDownloaded() {
+ * Returns true if this {@code ModuleDefinition} is local;
+ * otherwise, returns false.
+ *
+ * @return true if this {@code ModuleDefinition} is local; otherwise,
+ * returns false.
+ */
+ public boolean isLocal() {
Boolean local = java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Boolean>() {
public Boolean run() {
@@ -344,8 +364,10 @@ public abstract class ModuleDefinition {
}
/**
- * Check if the {@code Module} instances instantiated from this
- * {@code ModuleDefinition} can be released from its {@code ModuleSystem}.
+ * Returns true if the {@code ModuleSystem} of this
+ * {@code ModuleDefinition} can release any {@code Module} instance
+ * instantiated from this {@code ModuleDefinition}; otherwise, returns
+ * false.
*
* @return true if {@code Module} instances can be released; otherwise,
* returns false.
--- a/src/share/classes/java/module/ModuleDependency.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/ModuleDependency.java Thu Jul 24 17:30:52 2008 -0700
@@ -32,8 +32,8 @@ import java.util.Set;
/**
- * This interface represents a module-level import dependency in a module
- * definition.
+ * This interface represents an import dependency on a module definition
+ * based on a module's name.
* <p>
* @see java.module.ImportDependency
* @see java.module.VersionConstraint
@@ -45,9 +45,9 @@ public interface ModuleDependency extend
public interface ModuleDependency extends ImportDependency {
/**
- * Returns the name of the module to import.
+ * Returns the module's name.
*
- * @return the name of the module to import.
+ * @return the module's name.
*/
public String getName();
@@ -59,16 +59,20 @@ public interface ModuleDependency extend
public VersionConstraint getVersionConstraint();
/**
- * Returns true if the imported module is re-exported; otherwise, returns false.
+ * Returns true if this {@code ModuleDependency} is re-exported;
+ * otherwise, returns false.
*
- * @return true if the imported module is re-exported; otherwise, returns false.
+ * @return true if this {@code ModuleDependency} is re-exported;
+ * otherwise, returns false.
*/
public boolean isReexported();
/**
- * Returns true if this {@code ModuleDependency} is optional; otherwise, returns false.
+ * Returns true if this {@code ModuleDependency} is optional;
+ * otherwise, returns false.
*
- * @return true if the {@code ModuleDependency} is optional; otherwise, returns false.
+ * @return true if this {@code ModuleDependency} is optional;
+ * otherwise, returns false.
*/
public boolean isOptional();
--- a/src/share/classes/java/module/ModuleInitializer.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/ModuleInitializer.java Thu Jul 24 17:30:52 2008 -0700
@@ -65,13 +65,7 @@ public interface ModuleInitializer {
* undeterministic.
* <p>
* Note that the module instance passed as the argument of this method has
- * not been fully initialized. The only methods in {@code Module} that the
- * implementation of this method could invoke reliably are
- * {@code Module}'s
- * {@link Module#getModuleDefinition() <tt>getModuleDefinition</tt>},
- * {@link Module#hashCode() <tt>hashCode</tt>}, and
- * {@link Module#toString() <tt>toString</tt>} methods.
- * Otherwise, the result is undeterministric.
+ * not been fully initialized.
*
* @param module the {@code Module} instance to be initialized.
* @throws ModuleInitializationException if this {@code ModuleInitializer}
--- a/src/share/classes/java/module/ModuleSystem.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/ModuleSystem.java Thu Jul 24 17:30:52 2008 -0700
@@ -26,6 +26,7 @@ package java.module;
package java.module;
import java.util.List;
+import java.util.WeakHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
@@ -33,26 +34,98 @@ import java.util.concurrent.ThreadFactor
/**
* This class represents a module system.
* <p>
- * A {@code ModuleSystem} is responsible for creating and initializing
- * module instances from module definitions, and managing their lifetimes.
- * <p>
- * A {@code ModuleSystem} object is used to instantiate and
- * initialize a {@link Module}
- * instance from a {@link ModuleDefinition} using the
- * {@link getModule(ModuleDefinition) <tt>getModule</tt>} method or the
- * {@link getModules(ModuleDefinition, List) <tt>getModules</tt>} method.
- * The {@code ModuleSystem} object manages the lifetime of each
- * {@code Module} instance it creates, until the
- * {@code Module} instance is released using the
- * {@link releaseModule(ModuleDefinition) <tt>releaseModule</tt>} method.
- * <p>
- * A {@code ModuleDefinition} can be disabled in its {@code ModuleSystem}
- * using the
- * {@link disableModuleDefinition(ModuleDefinition)
- * <tt>disableModuleDefinition</tt>} method;
- * the module system must not instantiate any new {@code Module} instance
- * from a disabled {@code ModuleDefinition}.
- * <p>
+ * A module system within the Java Module System is responsible for the
+ * creation, management, and release of
+ * {@linkplain Module module instances}. A module system creates
+ * module instances from {@linkplain ModuleDefinition module definitions},
+ * and a module system must
+ * <a href="#Initialization">initialize</a> the module instances it creates.
+ *
+ * <a name="Initialization"><h3>Module initialization</h3></a>
+ *
+ * A module system implementation involves performing two tasks on a module
+ * instance during module initialization:
+ * <a href="#Resolution"><i>resolution</i></a> and
+ * <a href="#ShallowValidation"><i>type consistency validation</i></a>.
+ * A module instance is <i>fully initialized</i> if the module
+ * initialization completes successfully.
+ *
+ * <a name="Resolution"><h4>Resolution</h4></a>
+ * <i>Resolution</i> is the process of resolving the imports of a module instance.
+ * During resolution, a module system implementation must select a list of
+ * imported module definitions, based on the
+ * {@linkplain ModuleDefinition#getImportDependencies() import dependencies}
+ * of the module instance, and the module definitions available from the
+ * repositories. The selection policy is module system specific. A module
+ * system implementation must use the repository which the
+ * initializing module belongs to search candidate modules for the imports.
+ * <p>
+ * Module system implementations must be able to resolve
+ * {@linkplain ModuleDependency module dependencies} in a module instance.
+ * A module system implementation may be able to resolve other types
+ * of import dependency, e.g.
+ * {@linkplain PackageDependency package dependency}.
+ * A module system implementation must cause the initialization
+ * to fail if it can not recognize the type of import dependency in a
+ * module instance.
+ * <p>
+ * Support for cyclic dependencies is module systems specific.
+ * Module system implementations may be able to resolve cyclic dependencies
+ * between module definitions only in the same repository. A module system
+ * implementation may be able to resolve cyclic dependencies between
+ * module definitions only from the same module system. A module system
+ * implementation may be able to resolve cyclic dependencies
+ * between module definitions from different module systems.
+ * <p>
+ * Module system implementations must support
+ * {@linkplain ImportDependency#isOptional() optional} dependencies; a
+ * module system implementation must ignore an optional dependency if no
+ * module definition in the repository can satisfy the dependency.
+ * <p>
+ * Module system implementations must support
+ * {@linkplain ModuleDependency#isReexported() re-exported} module
+ * dependencies. If module <i>M</i> imports module <i>N</i> which
+ * imports module <i>O</i> through module dependency and
+ * <i>N</i> re-exports <i>O</i>, the module system implementation
+ * of <i>M</i> must automatically import <i>O</i> in <i>M</i>.
+ *
+ * <a name="TypeConsistencyValidation"><h4>Type consistency validation</h4></a>
+ * <i>Type consistency validation</i> is the process by which a module system
+ * checks the type consistency requirement with a module instane and its
+ * imported modules. There are two kinds:
+ * <i>shallow validation</i> and <i>deep validation</i>.
+ * <p>
+ * <i>Shallow validation</i> is the process that enforces the
+ * minimal type consistency requirement with a module instance and its
+ * imported modules. The minimal type consistency requirement is module
+ * system specific. This process examines the member types in module instance
+ * <i>M</i> and the exported types from all the module instances imported by
+ * <i>M</i> to ensure that <i>M</i> maintains the minimal type consistency
+ * requirement as defined by <i>M</i>'s module system.
+ * <p>
+ * <a name="DeepValidation">
+ * <i>Deep validation</i></a> is the process that enforces the maximum type
+ * consistency requirement with a module instance and its imported modules.
+ * This process examines the member types in the module instance and all the
+ * member types from the module instances imported transitively by this
+ * module instance. The maximum type consistency requirement is
+ * that the sets of the member types in all these module instances must be
+ * mutually disjoint. A module instance passing <i>deep validation</i>
+ * must always pass <i>shallow validation</i>.
+ * <p>
+ * <pre>
+ * </pre>
+ * Module system implementations must support <i>resolution</i> and
+ * <i>shallow validation</i>. Module system implementations may support
+ * <i>deep validation</i>.
+ * <p>
+ * Module system implementations must perform <i>resolution</i>, and
+ * one of the <i>type consistency validations</i> during
+ * module initialization. A module system implementation may perform
+ * <i>resolution</i> and <i>type consistency validation</i>
+ * in different order or in one or more iterations during module
+ * initialization.
+ *
* @see java.module.Module
* @see java.module.ModuleDefinition
* @see java.module.ModuleSystemListener
@@ -63,6 +136,10 @@ import java.util.concurrent.ThreadFactor
@java.util.Service
public abstract class ModuleSystem {
+ // Module definitions that have been disabled.
+ private final WeakHashMap<ModuleDefinition, Boolean> disabledModuleDefs = new WeakHashMap<ModuleDefinition, Boolean>();
+
+
/**
* Creates a {@code ModuleSystem} instance.
* <p>
@@ -82,16 +159,33 @@ public abstract class ModuleSystem {
}
}
-
/**
* Returns a {@code Module} instance for the specified
- * {@code ModuleDefinition} in this {@code ModuleSystem}. The returned
- * {@code Module} is fully initialized and ready to use.
- * <p>
- * If there is an existing, unreleased {@code Module} instance for the
- * specified {@code ModuleDefinition}, that instance is returned.
- * Otherwise, a new {@code Module} instance is instantiated, initialized,
- * and returned.
+ * {@code ModuleDefinition} in this {@code ModuleSystem}.
+ * Module system implementations must return a {@code Module}
+ * instance which is fully initialized.
+ * <p>
+ * Module system implementations may instantiate, initialize,
+ * and return a new {@code Module} instance. Module
+ * system implementations must ensure that this new {@code Module}
+ * instance is strongly reachable from the module system.
+ * Module system implementations must also fire a
+ * {@link ModuleSystemEvent.Type#MODULE_INITIALIZED
+ * <tt>MODULE_INITIALIZED</tt>} event for this {@code Module}
+ * instance.
+ * <p>
+ * Module system implementations may instantiate a new
+ * {@code Module} instance but fail to initialize it.
+ * Module system implementations must fire a
+ * {@link ModuleSystemEvent.Type#MODULE_INITIALIZATION_EXCEPTION
+ * <tt>MODULE_INITIALIZATION_EXCEPTION</tt>} event for this {@code Module}
+ * instance.
+ * <p>
+ * Module system implementations may return an existing
+ * {@code Module} instance to maximize sharing if the
+ * {@code Module} instance has not been
+ * {@linkplain #releaseModule(ModuleDefinition) released}
+ * from the module system.
*
* @param moduleDef the {@code ModuleDefinition} which designates the
* {@code Module} to be returned
@@ -100,14 +194,46 @@ public abstract class ModuleSystem {
* @throws ModuleInitializationException if the {@code Module} instance
* cannot be initialized.
* @throws IllegalStateException if the specified {@code ModuleDefinition}
- * has already been disabled.
+ * has been disabled.
+ * @throws IllegalArgumentException if the specified
+ * {@code ModuleDefinition} is associated with another
+ * module system, or with a repository which this
+ * module system does not support.
*/
public abstract Module getModule(ModuleDefinition moduleDef) throws ModuleInitializationException;
/**
* Returns a list of {@code Module} instances for the specified
- * {@code ModuleDefinition}s in this {@code ModuleSystem}. The returned
- * {@code Module}s are fully initialized and ready to use.
+ * {@code ModuleDefinition}s in this {@code ModuleSystem}.
+ * Module system implementations must return a list of
+ * {@code Module} instances which are fully initialized.
+ * Each {@code Module} instance in the returned list must be
+ * a module instance of the corresponding {@code ModuleDefinition} in the
+ * specified {@code moduleDefs}.
+ * <p>
+ * For each {@code ModuleDefinition} in the specified {@code moduleDefs},
+ * a module system implementation
+ * may instantiate, initialize and return a new {@code Module} instance
+ * in the returned list. The module system implementation must ensure that
+ * this new {@code Module} instance is strongly reachable from the module
+ * system. The module system implementation must also fire a
+ * {@link ModuleSystemEvent.Type#MODULE_INITIALIZED
+ * <tt>MODULE_INITIALIZED</tt>} event for this {@code Module}
+ * instance.
+ * <p>
+ * For each {@code ModuleDefinition} in the specified {@code moduleDefs},
+ * a module system implementation
+ * may instantiate a new {@code Module} instance but fail to initialize it.
+ * The module system implementation must fire a
+ * {@link ModuleSystemEvent.Type#MODULE_INITIALIZATION_EXCEPTION
+ * <tt>MODULE_INITIALIZATION_EXCEPTION</tt>} event for this {@code Module}
+ * instance.
+ * <p>
+ * For each {@code ModuleDefinition} in the specified {@code moduleDefs},
+ * a module system implementation
+ * may return an existing {@code Module} instance in the returned list if
+ * the {@code Module} instance has not been
+ * {@linkplain #releaseModule(ModuleDefinition) released} from the module system.
*
* @param importer the {@code ModuleDefinition} which imports
* @param moduleDefs the {@code ModuleDefinition} which designates the
@@ -116,30 +242,44 @@ public abstract class ModuleSystem {
* {@code ModuleDefinition}s.
* @throws ModuleInitializationException if a {@code Module} instance
* cannot be initialized.
- * @throws IllegalStateException if one of the {@code ModuleDefinition}s
- * has already been disabled.
+ * @throws IllegalStateException if one or more {@code ModuleDefinition}s
+ * in {@code moduleDefs} have been disabled.
+ * @throws IllegalArgumentException if one or more
+ * {@code ModuleDefinition}s in {@code moduleDefs} are
+ * associated with another module system, or with a
+ * repository which this module system does not support.
*/
public abstract List<Module> getModules(ModuleDefinition importer, List<ModuleDefinition> moduleDefs) throws ModuleInitializationException;
/**
- * Releases an existing {@code Module} instance corresponding to the
+ * Releases all existing {@code Module} instance(s) corresponding to the
* specified {@code ModuleDefinition} in this {@code ModuleSystem}.
* <p>
- * If this {@code ModuleSystem} has a {@code Module} instance for the
- * specified {@code ModuleDefinition}, it will never be returned by this
- * {@code ModuleSystem} after this method returns. Further, if that
- * {@code Module} instance is imported by other {@code Module}
- * instances, each of these importing {@code Module} instance will
- * also be released.
- * <p>
- * If there is no {@code Module} instance corresponding to the
- * {@code ModuleDefinition}, calling this method has no effect.
- * <p>
- * {@code Module} instances corresponding to the {@code ModuleDefinition}
- * with name that begins with "java.", or from the bootstrap repository
- * cannot be released. {@code Module} instances corresponding to
- * {@code ModuleDefinition} that their {@code isModuleReleasable} method
- * returns {@code false} also cannot be released.
+ * A module system implementation may have one or more existing
+ * {@code Module} instances corresponding to the specified
+ * {@code ModuleDefinition} in the module system.
+ * <p>
+ * A module system implementation must release an existing {@code Module}
+ * instance of the specified {@code ModuleDefinition} if the
+ * {@code Module} instance is
+ * {@link ModuleDefinition#isModuleReleasable() releasable}.
+ * The module system implementation must ensure that a released
+ * {@code Module} instance is not strongly reachable from the
+ * module system.
+ * <p>
+ * A module system implementation releasing an existing
+ * {@code Module} instance must also release the importing module instances
+ * transitively from the importers' module systems.
+ * <p>
+ * A module system implementation releasing an existing
+ * {@code Module} instance must fire a
+ * {@link ModuleSystemEvent.Type#MODULE_RELEASED
+ * <tt>MODULE_RELEASED</tt>} event for this {@code Module} instance.
+ * <p>
+ * {@linkplain Module#getClassLoader() Module class loader} of this
+ * {@code Module} must continue to make all classes and resources in
+ * this {@code Module} visible to its importing module instances
+ * after this {@code Module} instance is released.
* <p>
* If a security manager is present, this method calls the security
* manager's {@code checkPermission} method with a
@@ -153,7 +293,11 @@ public abstract class ModuleSystem {
* {@code Module} instance of the specified
* {@code ModuleDefinition}.
* @throws UnsupportedOperationException if the existing module
- * instance cannot be released.
+ * instance is not releasable.
+ * @throws IllegalArgumentException if the specified
+ * {@code ModuleDefinition} is associated with another
+ * module system, or with a repository which this
+ * module system does not support.
*/
public abstract void releaseModule(ModuleDefinition moduleDef);
@@ -161,22 +305,23 @@ public abstract class ModuleSystem {
* Disables the specified {@code ModuleDefinition} in this
* {@code ModuleSystem}.
* <p>
- * The {@code ModuleDefinition} is {@link #releaseModule released} and
- * marked to disallow creation of new {@code Module} instances. Subsequent
- * calls to {@link #getModule getModule} with this
- * {@code ModuleDefinition} throw an {@code IllegalStateException}.
- * <p>
- * {@code ModuleDefinition} instances with name that begins with "java.",
- * or from the bootstrap repository cannot be disabled.
- * <p>
- * If a security manager is present, this method calls the security
- * manager's {@code checkPermission} method with a
- * {@code ModuleSystemPermission("disableModuleDefinition")} permission to
- * ensure it's ok to disable the specified {@code ModuleDefinition} in this
- * {@code ModuleSystem}.
- *
- * @param moduleDef the {@code ModuleDefinition} which specifies the module
- * to be disabled.
+ * A module system implementation must not instantiate any
+ * new {@code Module} instance from the {@code ModuleDefinition}
+ * after the {@code ModuleDefinition} is disabled.
+ * <p>
+ * A module system implementation disabling a {@code ModuleDefinition}
+ * must fire a
+ * {@link ModuleSystemEvent.Type#MODULE_DEFINITION_DISABLED
+ * <tt>MODULE_DEFINITION_DISABLED</tt>} event for the
+ * {@code ModuleDefinition}.
+ * <p>
+ * If a security manager is present, this method calls the
+ * security manager's {@code checkPermission} method with a
+ * {@code ModuleSystemPermission("disableModuleDefinition")}
+ * permission to ensure it's ok to disable the specified
+ * {@code ModuleDefinition} in this {@code ModuleSystem}.
+ *
+ * @param moduleDef the {@code ModuleDefinition} to be disabled.
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method denies access to disable the
* specified {@code ModuleDefinition} in this {@code ModuleSystem}.
@@ -184,8 +329,53 @@ public abstract class ModuleSystem {
* {@code ModuleDefinition} cannot be disabled.
* @throws IllegalStateException if the specified {@code ModuleDefinition}
* has already been disabled.
- */
- public abstract void disableModuleDefinition(ModuleDefinition moduleDef);
+ * @throws IllegalArgumentException if the specified
+ * {@code ModuleDefinition} is associated with another
+ * module system, or with a repository which this
+ * module system does not support.
+ */
+ public void disableModuleDefinition(ModuleDefinition moduleDef) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new ModuleSystemPermission("disableModuleDefinition"));
+ }
+ if (moduleDef.getModuleSystem() != this) {
+ throw new IllegalArgumentException("Module definition is associated with another module system.");
+ }
+ synchronized(disabledModuleDefs) {
+ if (disabledModuleDefs.containsKey(moduleDef)) {
+ throw new IllegalStateException("Module definition has already been disabled.");
+ }
+ disabledModuleDefs.put(moduleDef, Boolean.TRUE);
+ }
+
+ // Send MODULE_DEFINITION_DISABLED event
+ ModuleSystemEvent evt = new ModuleSystemEvent(this,
+ ModuleSystemEvent.Type.MODULE_DEFINITION_DISABLED,
+ null, moduleDef, null);
+ this.processEvent(evt);
+ }
+
+ /**
+ * Returns true if the specified {@code ModuleDefinition} is disabled in this
+ * {@code ModuleSystem}; otherwise, returns false.
+ *
+ * @param moduleDef the {@code ModuleDefinition}.
+ * @return true if the specified {@code ModuleDefinition} is disabled in this
+ * {@code ModuleSystem}; otherwise, returns false.
+ * @throws IllegalArgumentException if the specified
+ * {@code ModuleDefinition} is associated with another
+ * module system, or with a repository which this
+ * module system does not support.
+ */
+ public boolean isModuleDefinitionDisabled(ModuleDefinition moduleDef) {
+ if (moduleDef.getModuleSystem() != this) {
+ throw new IllegalArgumentException("Module definition is associated with another module system.");
+ }
+ synchronized(disabledModuleDefs) {
+ return disabledModuleDefs.containsKey(moduleDef);
+ }
+ }
// Module system listener(s)
private static ModuleSystemListener moduleSystemListener = null;
@@ -287,8 +477,9 @@ public abstract class ModuleSystem {
private static ExecutorService executorService = null;
/**
- * Processes module system event occuring in this {@code ModuleSystem} by
- * dispatching them to any registered {@code ModuleSystemListener} objects.
+ * Processes module system event occurring in this {@code ModuleSystem} by
+ * dispatching them to any registered {@code ModuleSystemListener} objects
+ * asynchronously.
*
* @param event the module system event
*/
--- a/src/share/classes/java/module/Modules.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/Modules.java Thu Jul 24 17:30:52 2008 -0700
@@ -30,7 +30,6 @@ import java.net.URL;
import java.net.URL;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.Callable;
import sun.module.core.JamModuleDefinition;
import sun.module.config.DefaultImportOverridePolicy;
import sun.module.config.DefaultVisibilityPolicy;
@@ -40,90 +39,126 @@ import sun.module.repository.URLReposito
/**
* This class consists exclusively of static methods that are specifically for
- * the JAM (JAva Module) modules in the JAM module system.
- * <p>
- * <h3> ModuleSystem implementation</h3>
+ * the JAM modules in the JAM module system.
+ * <p>
+ * <h2> JAM Module System</h2>
+ *
+ * The JAM module system is a concrete module system
+ * implementation and is the default module system within the Java Module
+ * System. See the JAM Module System Specification for more details.
+ *
+ * <h3> ModuleSystem</h3>
* The JAM module system provides a concrete {@link ModuleSystem}
* implementation for JAM modules. Applications can obtain the
* {@code ModuleSystem} objects by calling the
- * {@link getModuleSystem() <tt>getModuleSystem</tt>} method.
- * <p>
- * <h3> ModuleDefinition implementation</h3>
+ * {@link #getModuleSystem() <tt>getModuleSystem</tt>} method.
+ * <p>
+ * <h3> ModuleDefinition</h3>
* The JAM module system provides a concrete {@link ModuleDefinition}
* implementation for JAM modules. Applications can obtain the
- * {@code ModuleDefinition} objects by calling one of the
+ * {@code ModuleDefinition} objects by calling the
* {@link #newModuleDefinition(byte[], ModuleContent,Repository,boolean)
- * <tt>newModuleDefinition</tt>} factory methods.
- * <p>
- * <h3> Repository implementations</h3>
+ * <tt>newModuleDefinition</tt>} factory method.
+ * <p>
+ * <h3> Repository</h3>
* The JAM module system provides two concrete repository implementations:
- * <i>Local repository</i> and <i>URL repository</i>.
- * <p>
+ * <i>Local repository</i> and <i>URL repository</i>. Both repository
+ * implementations must support the JAM file format as described in the JAM
+ * Module System Specification. Both repository implementations must also
+ * validate the integrity of a JAM file when the file is installed.
+ * <p>
+ * <A NAME="SelectionPolicy"></A><h5>Selection policy for JAM modules</h5>
+ *
+ * Local repository and URL repository have both platform-neutral and
+ * <a href="package-summary.html#PlatformSpecificModules">platform-specific modules</a>
+ * installed. Implementations of these repositories must use the following
+ * policy to select the set of JAM modules appropriate for the platform and
+ * architecture of the system:
+ * <ul>
+ * <li><p>JAM module with platform binding which does not match
+ * the platform and architecture of the system is ignored.
+ * </p></li>
+ *
+ * <li><p>JAM module with platform binding which matches
+ * the system's platform and architecture is preferred
+ * over the JAM module of the same name and version with no
+ * platform binding.</p></li>
+ * </ul>
+ *
* <h4>Local Repository</h4>
- * A <i>local repository</i> loads module definitions whose module archives
- * are stored in a directory in the file system. This allows deployers to
- * easily deploy module definitions into the repository by copying, ftp-ing,
- * or dragging-and-dropping the module archives into a directory. This also
- * facilitates sharing between different repositories if they process the
- * module archives from the same directory. Hence, this directory is also
- * called a <i>repository interchange directory</i>.
- * <p>
- * The policy for processing the module archives in the repository
- * interchange directory is as follows:
+ * <i>Local repository</i> supports loading JAM modules from a directory on
+ * a file system. Different repository instances in the same or different
+ * Java virtual machines can process the
+ * JAM modules from the same directory for sharing purposes. Hence, the
+ * directory is also called <i>repository interchange directory</i>.
+ * <p>
+ * A local repository must follow the policy below to
+ * process JAM modules in the repository interchange directory, when the
+ * {@link Repository#initialize() <tt>initialize</tt>} or
+ * {@link Repository#reload() <tt>reload</tt>} method is called:
* <ul>
- * <li><p>Files whose names end in {@code .jam} that follow the naming
- * convention scheme defined in Section 4.1 of the JAM Module
- * System specification will be processed. Files whose names end
- * in {@code .jam} but do not follow the naming convention scheme
- * will be ignored. Files whose names end in
- * {@code .jam.pack.gz}, {@code .jar}, {@code .zip} or other
- * filename extensions would also be ignored.</p></li>
- *
- * <li><p>Files would be considered regardless of whether or not they
- * are "hidden" in the UNIX sense, i.e., the files are stored
- * under a directory and the name of the directory begins with
- * {@code '.'}.</p></li>
- *
- * <li><p>Subdirectories would not be searched recursively, i.e.,
- * if the directory is foo, the repository implementation should
- * only looks for JAM files in {@code foo}, not in {@code foo/bar},
- * {@code foo/baz}, etc.</p></li>
- *
- * <li><p>The order in which the JAM files are enumerated is not specified
- * and may vary from platform to platform and even from invocation
- * to invocation on the same machine. If there is more than one JAM
- * file containing the same version of the module definition, the
- * repository implementation should only load the first enumerated
- * one, and ignore the others.</p></li>
+ * <li><p>A local repository must process JAM file which
+ * has {@code .jam} extension and follows the naming convention
+ * defined in Section 3.1 of the JAM Module System Specification.
+ * A local repository must ignore JAM file which
+ * has {@code .jam} extension but does not follow the naming
+ * convention.
+ * A local repository must ignore JAM file which
+ * has {@code .jam.pack.gz}, {@code .jar}, {@code .zip} or other
+ * filename extensions.
+ *
+ * <li><p>A local repository must support a
+ * "hidden" (in the UNIX sense) repository interchange directory.
+ * </p></li>
+ *
+ * <li><p>A local repository must ignore subdirectories
+ * under the repository interchange directory.
+ * </p></li>
+ *
+ * <li><p>Local repository implementations may enumerate the JAM files in
+ * any order.</p></li>
+ *
+ * <li><p>Local repository implementations must ignore the duplicates
+ * if there is more than one JAM file containing the same JAM module.
+ * </p></li>
* </ul>
+ * <p>
+ * A local repository must follow the
+ * <a href="#SelectionPolicy">selection policy</a> to determine a
+ * selected set of JAM modules, from the set of JAM modules available
+ * in the repository interchange directory. Local repository
+ * implementations must only create {@code ModuleDefinition}s for the
+ * selected set of JAM modules.
+ * <p>
+ * Local repository implementations must support the
+ * {@link Repository#reload() <tt>reload</tt>} operation. During reload,
+ * a local repository must compare the set of JAM
+ * modules in the repository interchange directory against
+ * the set of JAM modules which was last recognized by the local
+ * repository.
+ * See
+ * {@link Repository#reload()} for more details.
+ * <p>
+ * Local repository implementations must become
+ * {@linkplain Repository#isReadOnly() read-only}
+ * if the repository interchange directory is read-only as determined
+ * when the repository is initialized and reloaded.
+ * Local repository implementations must support the
+ * {@link Repository#install(URI) <tt>install</tt>} and
+ * {@link Repository#uninstall(ModuleArchiveInfo) <tt>uninstall</tt>} operations.
* <p>
* Instances of this {@code Repository} can be constructed using one of the
* {@link #newLocalRepository(String, File, Map, Repository)
- * <tt>newLocalRepository</tt>} factory methods, and the factory methods
+ * <tt>newLocalRepository</tt>} factory methods; the factory methods
* also invokes the {@code Repository}'s
* {@link Repository#initialize() <tt>initialize</tt>} method automatically.
- * <p>
- * Instance of this {@code Repository} is read-only if its <i>repository
- * interchange directory</i> is read-only during repository
- * initialization. Instance of this {@code Repository} also supports the
- * {@link Repository#install(URI) <tt>install</tt>} and
- * {@link Repository#uninstall(ModuleArchiveInfo) <tt>uninstall</tt>} operations
- * if the {@code Repository} is not read-only.
- * <p>
- * Instance of this {@code Repository} supports reload. When the
- * {@code Repository} instance is reloaded, the set of module archives
- * in the <i>repository interchange directory</i> are checked against
- * the set of module archives that were recognized during repository
- * initialization to determine if the set of module archives and the
- * set of module definitions should be changed. See
- * {@link Repository#reload()} for more details.
* <p>
* Below is an example showing how to construct a <i>local repository</i> to
* search for a specific module definition:
* <pre>
* // Create a local repository instance. The source location is
* // interpreted by the repository implementation as a local directory
- * // where the module definitions are stored. The local repository
+ * // where the JAM files are stored. The local repository
* // instance is automatically initialized during construction.
* File file = new File("/home/wombat/repository");
* Repository repo = Modules.newLocalRepository("wombat", file, null);
@@ -132,88 +167,101 @@ import sun.module.repository.URLReposito
* ModuleDefinition moduleDef = repo.find("org.foo.xml", VersionConstraint.valueOf("1.0.0"));</pre>
*
* <h4>URL Repository</h4>
- * A <i>URL repository</i> loads module definitions whose module archives
- * are stored in a codebase URL, and it is designed to optimize loading
- * through specific files and directories layout. <i>URL repository</i>
- * is typically used to download module definitions from server, but it
- * could also be used with a file-based URL.
+ * <i>URL repository</i> supports loading JAM modules
+ * from a codebase URL. URL repository is typically used to
+ * download JAM modules from server, but it can also be used with a
+ * file-based URL.
+ * <p>
+ * URL repository must have a <i>repository metadata file</i>
+ * (i.e. repository-metadata.xml) which describes the JAM modules in
+ * the repository. The <i>repository metadata file</i> must exist
+ * directly under the codebase URL, and it must conform to the
+ * <a href="RepositoryMetadata.xml">repository metadata schema</a>.
+ * <pre>
+ * {codebase}/repository-metadata.xml</pre>
+ *
+ * A JAM module in the URL repository is identified by placing an entry
+ * in the <i>repository metadata file</i>. Each entry has a
+ * module name, module version, path (relative path to a location
+ * where the module is stored under the codebase URL), and platform
+ * binding. URL repository implementations must ignore the duplicates
+ * if there is more than one entry for the JAM module with the
+ * same name, version, and platform binding.
+ * For a given JAM module in the URL repository, its module
+ * metadata file {@code MODULE.METADATA} must exist under the path, and
+ * its module archive (i.e. either {@code .jam} file,
+ * {@code .jam.pack.gz} file, or both} must also exist under the path.
+ * <h5>Platform-neutral JAM module</h5>
+ * <pre>
+ * {codebase}/{path}/MODULE.METADATA
+ * {codebase}/{path}/&lt;module-name&gt;-&lt;module-version&gt;.jam
+ * {codebase}/{path}/&lt;module-name&gt;-&lt;module-version&gt;.jam.pack.gz</pre>
+ *
+ * <h5>Platform-specific JAM module</h5>
+ * <pre>
+ * {codebase}/{path}/MODULE.METADATA
+ * {codebase}/{path}/&lt;module-name&gt;-&lt;module-version&gt;[&lt;platform&gt;-&lt;arch&gt;].jam
+ * {codebase}/{path}/&lt;module-name&gt;-&lt;module-version&gt;[&lt;platform&gt;-&lt;arch&gt;].jam.pack.gz</pre>
+ *
+ * URL repository implementations must follow the
+ * <a href="#SelectionPolicy">selection policy</a> to determine a
+ * selected set of JAM modules, from the set of JAM modules available
+ * in the repository as described in the repository metadata file.
+ * URL repository implementations must only create
+ * {@code ModuleDefinition}s for the selected set of JAM modules.
+ * <p>
+ * For each JAM module in the selected set,
+ * <ul>
+ * <li><p>URL repository implementations must either download the
+ * {@code .jam} file or {@code .jam.pack.gz} file for the given
+ * JAM module. URL repository implementations must prefer
+ * the {@code .jam.pack.gz} file over the {@code .jam} file
+ * if the codebase URL is not file-based.</p></li>
+ *
+ * <li><p>URL repository implementations must ignore the JAM module
+ * if the module's name, version, and platform binding specified
+ * in the repository metadata file do not match the information
+ * in the module metadata file
+ * (i.e. {@code MODULE.METADATA file}).</p></li>
+ *
+ * <li><p>A URL repository implementation must throw exception in
+ * methods of {@link ModuleContent} in the
+ * {@link ModuleDefinition}s the URL repository creates, if
+ * the module metadata file (i.e. {@code MODULE.METADATA
+ * file}) is not bit-wise equal to the module metadata file
+ * inside the {@code .jam} file or {@code .jam.pack.gz} file
+ * which the URL repository has downloaded.
+ * </p></li>
+ * </ul>
+ * URL repository is {@linkplain Repository#isReadOnly() read-only}
+ * if the codebase is a non-file-based URL or it is a file-based URL
+ * which represents a read-only directory on the file system.
+ * URL repository implementations must support the
+ * {@link Repository#install(java.net.URI) <tt>install</tt>} and
+ * {@link Repository#uninstall(ModuleArchiveInfo) <tt>uninstall</tt>}
+ * operations for JAM files.
+ * <p>
+ * A URL repository must support the
+ * {@linkplain Repository#reload() reload}
+ * operation; it must compare the timestamp of the
+ * <i>repository metadata file</i> against the timestamp of the same file
+ * which was last downloaded. If the timestamps are different, a URL
+ * repository must do the following:
+ * <ol>
+ * <li><p>Download the repository metadata file and determine
+ * the set of JAM modules based on the selection policy.</p></li>
+ * <li><p>Remove all existing module archives and module definitions
+ * from the repository.</p></li>
+ * <li><p>Add new module archives and module definitions to the
+ * repository.</p></li>
+ * </ol>
+ * See {@link Repository#reload()} for more details.
* <p>
* Instance of this {@code Repository} can be constructed using one of the
* {@link #newURLRepository(String, URL, Map, Repository)
- * <tt>newURLRepository</tt>} factory methods, and the factory methods also
+ * <tt>newURLRepository</tt>} factory methods; the factory methods also
* invokes the newly constructed {@code Repository}'s
* {@link Repository#initialize() <tt>initialize</tt>} method automatically.
- * <p>
- * Information about the module definitions available from the
- * codebase URL must be published in a <i>repository metadata file</i>
- * (i.e. {@code repository-metadata.xml}. The contents of the file must
- * follow the schema of the URL Repository metadata described in the
- * JAM Module System specification.
- * <p>
- * When this {@code Repository}is initialized, the repository metadata file
- * (i.e. repository-metadata.xml) is downloaded from the codebase URL.
- * <pre>
- * {codebase}/repository-metadata.xml</pre>
- * In the repository metadata file, each module definition is described
- * with a name, a version, a platform binding, and a path (relative to
- * the codebase URL where the JAM module metadata file, the module
- * archive, and/or the packed module archive are located). If no path
- * and no platform binding is specified, the default path is
- * {@code "{name}/{version}"}. If the path is not specified and the
- * module definition has platform binding, the default path is
- * {@code "{name}/{version}/{platform}-{arch}"}.
- * <p>
- * After the {@code Repository} successfully downloads the repository
- * metadata file, the JAM module metadata file of each module definition
- * (i.e. {@code MODULE.METADATA file}) in the repository is downloaded
- * based on the information in the <i>repository metadata file</i>:
- * <pre>
- * {codebase}/{path}/MODULE.METADATA</pre>
- * If a module definition is platform-specific, its JAM module metadata file
- * is downloaded if and only if the platform binding described in the
- * <i>repository metadata file</i> matches the platform and the architecture
- * of the system.
- * <p>
- * Module definitions are available for searches using one of the
- * {@link Repository#find(Query) <tt>find</tt>} methods after the
- * {@code Repository} instance is initialized. If a module instance is
- * instantiated from a module definition that has no platform binding, the
- * module archive is downloaded by probing in the following order:
- * <pre>
- * {codebase}/{path}/{name}-{version}.jam.pack.gz
- * {codebase}/{path}/{name}-{version}.jam</pre>
- * On the other hand, if a module instance is instantiated from a
- * platform-specific module definition, the module archive is
- * downloaded by probing in the following order:
- * <pre>
- * {codebase}/{path}/{name}-{version}-{platform}-{arch}.jam.pack.gz
- * {codebase}/{path}/{name}-{version}-{platform}-{arch}.jam</pre>
- * To ensure the integrity of the separately-hosted JAM module metadata
- * file is in sync with that in the module archive of the same module
- * definition, they are compared bit-wise against each other after the
- * module archive is downloaded when the module instance is
- * instantiated from the module definition. If these JAM module metadata
- * files are not in sync, the instantiation of the module definition
- * will fail.
- * <p>
- * Instance of this {@code Repository} is read-only unless the codebase
- * URL is a file-based URL which represents a writable directory on the
- * file system. Instance of this {@code Repository}
- * supports the {@link Repository#install(java.net.URI) <tt>install</tt>} and
- * {@link Repository#uninstall(ModuleArchiveInfo) <tt>uninstall</tt>} operations
- * when the {@code Repository} is not read-only.
- * <p>
- * Instance of this {@code Repository} supports reload. When the
- * {@code Repository} instance is reloaded, the timestamp of the
- * <i>repository metadata file</i> is checked against the timestamp of
- * the same file that was downloaded during repository initialization.
- * If the timestamps are identical, there is no change in the set of
- * module archives and the set of module definitions in the repository.
- * Otherwise, all existing module archives and module definitions in
- * the repository are removed, the repository metadata file is downloaded,
- * and the module definitions described in the <i>repository metadata file</i>
- * are downloaded and are available for subsequent searches.
- * See {@link Repository#reload()} for more details.
* <p>
* Below is an example showing how to construct a <i>URL repository</i> to
* search for a specific module definition:
@@ -230,7 +278,7 @@ import sun.module.repository.URLReposito
* // Search org.foo.xml version 1.3.0 from the repository instance.
* ModuleDefinition moduleDef = repo.find("org.foo.xml", VersionConstraint.valueOf("1.3.0"));</pre>
*
- * <h3> Module dependency and package dependency implementations</h3>
+ * <h3> Module dependency and package dependency</h3>
* The JAM module system provides a concrete implementation for
* {@link ModuleDependency} and another concrete implementation for
* {@link PackageDependency}. Instances of the {@code ModuleDependency}
@@ -248,9 +296,9 @@ import sun.module.repository.URLReposito
* initialization.
* <p>
* The system's import override policy can be obtained using the
- * {@link getImportOverridePolicy()
+ * {@link #getImportOverridePolicy()
* <tt>getImportOverridePolicy</tt>} method. The system's import override policy
- * can be changed using the {@link setImportOverridePolicy(ImportOverridePolicy)
+ * can be changed using the {@link #setImportOverridePolicy(ImportOverridePolicy)
* <tt>setImportOverridePolicy</tt>} method.
* <p>
* @see java.module.ImportOverridePolicy
@@ -301,7 +349,7 @@ public class Modules {
}
/**
- * Constructs a new {@code ModuleDependency} instance.
+ * Returns a new {@code ModuleDependency} instance.
*
* @param name the name of the imported module.
* @param constraint the version constraint.
@@ -318,7 +366,7 @@ public class Modules {
}
/**
- * Constructs a new {@code PackageDependency} instance.
+ * Returns a new {@code PackageDependency} instance.
*
* @param name the name of the package.
* @param constraint the version constraint.
@@ -335,11 +383,13 @@ public class Modules {
}
/**
- * Constructs a new {@code Repository} instance that loads module
- * archives from a directory on the file system, and initializes
- * using information from the given {@code config}.
+ * Returns a a new {@code Repository} instance which supports
+ * JAM modules in a directory, using the given
+ * {@code config}. The newly created {@code Repository}
+ * instance is initialized automatically.
* <p>
* If {@code config} is null, the configuration is ignored.
+ * The configuration is implementation dependent.
* <p>
* If a security manager is present, this method calls the security
* manager's {@code checkPermission} method with
@@ -379,13 +429,14 @@ public class Modules {
}
/**
- * Constructs a new {@code Repository} instance that loads module
- * definitions from a directory on the file system, and initializes
- * the repository using information from the given {@code config}.
- * Equivalent to:
+ * Returns a a new {@code Repository} instance which supports
+ * JAM modules in a directory, using
+ * the given {@code config}. The newly created {@code Repository}
+ * instance is initialized automatically. Equivalent to:
* <pre>
- * newLocalRepository(name, codebase, config, Repository.getSystemRepository());</pre>
+ * newLocalRepository(name, codebase, config, Repository.getApplicationRepository());</pre>
* If {@code config} is null, the configuration is ignored.
+ * The configuration is implementation dependent.
* <p>
* If a security manager is present, this method calls the security
* manager's {@code checkPermission} method with
@@ -414,12 +465,17 @@ public class Modules {
}
return new LocalRepository(name, source.toURI(), config,
- Repository.getSystemRepository());
- }
-
- /**
- * Constructs and initializes a new {@code Repository} instance that loads
- * module definitions from a codebase URL.
+ Repository.getApplicationRepository());
+ }
+
+ /**
+ * Returns a a new {@code Repository} instance which supports
+ * JAM modules from a codebase URL, using
+ * the given {@code config}. The newly created {@code Repository}
+ * instance is initialized automatically.
+ * <p>
+ * If {@code config} is null, the configuration is ignored.
+ * The configuration is implementation dependent.
* <p>
* If a security manager is present, this method calls the security
* manager's {@code checkPermission} method with a
@@ -427,7 +483,7 @@ public class Modules {
* it's ok to create a repository.
*
* @param name the repository name.
- * @param codebase the source location.
+ * @param codebase the code base of the repository.
* @param config Map of configuration names to their values
* @param parent the parent repository for delegation.
* @return a new {@code Repository} instance.
@@ -462,18 +518,22 @@ public class Modules {
}
/**
- * Constructs a new {@code Repository} instance that loads module
- * definitions from a codebase URL, and initializes using information
- * from the given {@code config}. Equivalent to:
+ * Returns a a new {@code Repository} instance which supports
+ * JAM modules from a codebase URL, using
+ * the given {@code config}. The newly created {@code Repository}
+ * instance is initialized automatically. Equivalent to:
* <pre>
- * newURLRepository(name, codebase, config, Repository.getSystemRepository());</pre>
+ * newURLRepository(name, codebase, config, Repository.getApplicationRepository());</pre>
+ * If {@code config} is null, the configuration is ignored.
+ * The configuration is implementation dependent.
+ * <p>
* If a security manager is present, this method calls the
* security manager's {@code checkPermission} method with
* a {@code ModuleSystemPermission("createRepository")}
* permission to ensure it's ok to create a repository.
*
* @param name the repository name.
- * @param codebase the source location.
+ * @param codebase the code base of the repository.
* @param config Map of configuration names to their values
* @return a new repository instance.
* @throws SecurityException if a security manager exists and
@@ -486,7 +546,7 @@ public class Modules {
public static Repository newURLRepository(String name, URL codebase,
Map<String, String> config)
throws IOException {
- return newURLRepository(name, codebase, config, Repository.getSystemRepository());
+ return newURLRepository(name, codebase, config, Repository.getApplicationRepository());
}
/**
@@ -620,7 +680,7 @@ public class Modules {
}
/**
- * Constructs a new {@code ModuleDefinition} instance for a JAM module.
+ * Returns a new {@code ModuleDefinition} instance for a JAM module.
*
* <p>This method will typically be called by repository implementations
* and not by applications.
@@ -654,48 +714,4 @@ public class Modules {
(getModuleSystem(),
null, null, metadata, null, content, repository, moduleReleasable);
}
-
- /**
- * Constructs a new {@code ModuleDefinition} instance for a JAM module.
- *
- * <p>This method will typically be called by repository implementations
- * and not by applications. It is useful in case the metadata has not
- * yet been retrieved but the module name and version are available.
- *
- * @param name the name of the {@code ModuleDefinition}
- * @param version the version of the {@code ModuleDefinition}
- * @param metadataHandle a Callable from which the contents of the
- * {@code MODULE-INF/METADATA.MODULE} file can be retrieved
- * as an array of bytes
- * @param content the {@code ModuleContent} to be used to access the
- * contents of the module definition
- * @param repository the {@code Repository} in which the module definition
- * is associated with
- * @param moduleReleasable true if the module instance instantiated from
- * this {@code ModuleDefinition} is releasable from the module
- * system
- * @return a new {@code ModuleDefinition}.
- */
- public static ModuleDefinition newModuleDefinition(String name, Version version,
- Callable<byte[]> metadataHandle, ModuleContent content,
- Repository repository, boolean moduleReleasable) {
- if (name == null) {
- throw new NullPointerException("name must not be null.");
- }
- if (version == null) {
- throw new NullPointerException("version must not be null.");
- }
- if (metadataHandle == null) {
- throw new NullPointerException("metadata handle must not be null.");
- }
- if (content == null) {
- throw new NullPointerException("content must not be null.");
- }
- if (repository == null) {
- throw new NullPointerException("repository must not be null.");
- }
- return new JamModuleDefinition
- (getModuleSystem(), name, version, null,
- metadataHandle, content, repository, moduleReleasable);
- }
}
--- a/src/share/classes/java/module/PackageDependency.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/PackageDependency.java Thu Jul 24 17:30:52 2008 -0700
@@ -32,8 +32,8 @@ import java.util.Set;
/**
- * This interface represents a package-level import dependency in a module
- * definition.
+ * This interface represents an import dependency on a module definition
+ * based on an exported package's name.
* <p>
* @see java.module.ImportDependency
* @see java.module.VersionConstraint
@@ -45,9 +45,9 @@ public interface PackageDependency exten
public interface PackageDependency extends ImportDependency {
/**
- * Returns the name of the package to import.
+ * Returns the exported package's name.
*
- * @return the name of the package to import.
+ * @return the exported package's name.
*/
public String getName();
@@ -59,9 +59,11 @@ public interface PackageDependency exten
public VersionConstraint getVersionConstraint();
/**
- * Returns true if the imported package is re-exported; otherwise, returns false.
+ * Returns true if this {@code PackageDependency} is re-exported;
+ * otherwise, returns false.
*
- * @return true if the imported package is re-exported; otherwise, returns false.
+ * @return true if this {@code PackageDependency} is re-exported;
+ * otherwise, returns false.
*/
public boolean isReexported();
@@ -69,7 +71,8 @@ public interface PackageDependency exten
* Returns true if this {@code PackageDependency} is optional;
* otherwise, returns false.
*
- * @return true if this {@code PackageDependency} is optional; otherwise, returns false.
+ * @return true if this {@code PackageDependency} is optional;
+ * otherwise, returns false.
*/
public boolean isOptional();
--- a/src/share/classes/java/module/Repository.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/Repository.java Thu Jul 24 17:30:52 2008 -0700
@@ -41,11 +41,11 @@ import sun.module.repository.RepositoryC
import sun.module.repository.RepositoryConfig;
/**
- * This class represents a repository. A repository is responsible for
- * storing, discovering, and retrieving {@linkplain ModuleDefinition module
- * definitions}.
+ * This class represents a repository. A repository is responsible
+ * for storing, discovering, and retrieving {@linkplain
+ * ModuleDefinition module definitions}.
* <p>
- * A {@code Repository} is {@linkplain #isActive active} when it has been
+ * A repository is {@linkplain #isActive active} when it has been
* {@linkplain #initialize() initialized} but not {@linkplain #shutdown()
* shutdown}. When a repository is no longer needed, a program should
* shutdown the repository to release the resources.
@@ -57,24 +57,25 @@ import sun.module.repository.RepositoryC
* module definition to its parent repository before attempting to find
* the module definition itself. The virtual machine's built-in repository,
* called the <i>bootstrap repository</i>, does not itself have a parent
- * but may serve as the parent of a {@code Repository} instance.
+ * but may serve as the parent of a {@code Repository} instance. The second
+ * built-in repository, called the <i>system repository</i>, is the
+ * repository for installed modules in the system, and it may also serve
+ * as the parent of a {@code Repository} instance. The third built-in
+ * repository, called the <i>application repository</i>,
+ * is the default parent for new {@code Repository} instances.
* <p>
* The system's {@linkplain #getVisibilityPolicy visibility policy} controls
- * which module definitions be visible in a repository.
+ * which module definitions are visible in a repository.
* <p>
* Applications implement subclasses of {@code Repository} in order to
* extend the manner in which the Java virtual machine dynamically
- * finds module definitions. Typically, repository implementors
- * should override the
- * {@link #doInitialize()} and {@link #doShutdown()} methods.
- * <p>
- * There are two default repositories provided by the Java platform: the
- * <i>bootstrap repository</i> and the <i>system repository</i>. The
- * <i>bootstrap repository</i> exposes the standard module definitions
- * for the Java platform and is the only repository that does not have
- * a parent. All module definitions whose name begins with "java." must
- * be exposed by the <i>bootstrap repository</i>. The <i>system
- * repository</i> is the default parent for new {@code Repository} instances.
+ * finds module definitions. This specification does not require that a
+ * repository be implemented by a file system, a web server, or even a
+ * database. As long as the requirements of this specification are met,
+ * repository implementors can implement the functionalites however they
+ * see fit. Typically, repository implementations should override the
+ * {@link #doInitialize() doInitialize} and
+ * {@link #doShutdown() doShutdown} methods.
*
* @see java.module.ModuleDefinition
* @see java.module.ModuleSystemPermission
@@ -90,7 +91,6 @@ public abstract class Repository {
private final Repository parent;
private final String name;
- private final URI source;
/**
* Internal data structures for the repository.
@@ -132,7 +132,6 @@ public abstract class Repository {
* it's ok to create a repository.
*
* @param name the repository name.
- * @param source the source location.
* @param parent the parent repository for delegation.
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method denies access to create a new
@@ -140,13 +139,10 @@ public abstract class Repository {
* @throws IllegalArgumentException if a circularity among the same
* repsoitory is detected.
*/
- protected Repository(String name, URI source, Repository parent) {
+ protected Repository(String name, Repository parent) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new ModuleSystemPermission("createRepository"));
- }
- if (source == null && !(this instanceof BootstrapRepository)) {
- throw new NullPointerException("source must not be null.");
}
if (name == null) {
throw new NullPointerException("name must not be null.");
@@ -165,12 +161,11 @@ public abstract class Repository {
this.parent = parent;
this.name = name;
- this.source = source;
}
/**
* Creates a {@code Repository} instance with the
- * {@linkplain #getSystemRepository system repository} as the
+ * {@linkplain #getApplicationRepository application repository} as the
* parent for delegation.
* <p>
* If a security manager is present, this method calls the security
@@ -179,13 +174,12 @@ public abstract class Repository {
* it's ok to create a repository.
*
* @param name the repository name.
- * @param source the source location.
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method denies access to create a new
* instance of repository.
*/
- protected Repository(String name, URI source) {
- this(name, source, getSystemRepository());
+ protected Repository(String name) {
+ this(name, getApplicationRepository());
}
/**
@@ -198,15 +192,6 @@ public abstract class Repository {
}
/**
- * Returns the source location of this {@code Repository}.
- *
- * @return the source location.
- */
- public final URI getSourceLocation() {
- return source;
- }
-
- /**
* Returns the parent repository for delegation. This method will return
* {@code null} if this repository is the bootstrap repository.
*
@@ -220,7 +205,7 @@ public abstract class Repository {
* Returns the bootstrap repository.
* <p>
* The bootstrap repository is an implementation-dependent instance of
- * this class , and it is provided by the Java Runtime.
+ * this class, and it is provided by the Java Runtime.
*
* @return the bootstrap repository.
*/
@@ -229,9 +214,7 @@ public abstract class Repository {
}
/**
- * Returns the system repository for delegation. This is the default
- * delegation parent for new {@code Repository} instances, and is
- * typically the repository used to start the application.
+ * Returns the system repository.
* <p>
* The system repository is an implementation-dependent instance of
* this class, and it is provided by the Java Runtime.
@@ -240,6 +223,22 @@ public abstract class Repository {
*/
public static Repository getSystemRepository() {
return RepositoryConfig.getSystemRepository();
+ }
+
+ /**
+ * Returns the application repository for delegation. This is the default
+ * delegation parent for new {@code Repository} instances, and is
+ * typically the repository used to start the application. If no
+ * repository was used, the application repository is the same as the
+ * {@linkplain #getSystemRepository() system repository}.
+ * <p>
+ * The application repository is an implementation-dependent instance of
+ * this class, and it is provided by the Java Runtime.
+ *
+ * @return the application repository.
+ */
+ public static Repository getApplicationRepository() {
+ return RepositoryConfig.getApplicationRepository();
}
/**
@@ -287,13 +286,13 @@ public abstract class Repository {
* {@linkplain #shutdown() shutdown},
* throws an {@code IllegalStateException}.</p></li>
*
- * <li><p> Invoke the {@link #doInitialize()} method.</p></li>
+ * <li><p> Invoke the {@link #doInitialize} method.</p></li>
*
* <li><p> Fire a {@link RepositoryEvent.Type#REPOSITORY_INITIALIZED
* <tt>REPOSITORY_INITIALIZED</tt>} event.</p></li>
* </ol>
*
- * <p> Subclasses of <tt>Repository</tt> are encouraged to override {@link
+ * <p> Subclasses of {@code Repository} are encouraged to override {@link
* #doInitialize()} method, rather than this method.</p>
*
* @throws IllegalStateException if this {@code Repository} has been
@@ -323,26 +322,26 @@ public abstract class Repository {
* Initializes this {@code Repository}. This method should be overridden
* by repository implementations to initialize the repository by load
* module archives and construct module definitions, and will be invoked
- * by the {@link #initialize()} method.
+ * by the {@link #initialize() initialize} method.
* <p>
* If the module archives are loaded successfully by this method,
- * the implementation should return the information of the module archives
- * as a list of {@code ModuleArchiveInfo}s. The implementation should NOT
- * invoke the {@link #addModuleArchiveInfo(ModuleArchiveInfo)} method with
- * the information of the module archives.
+ * the implementation must return the information of the module archives
+ * as a list of {@code ModuleArchiveInfo}s. The implementation must not
+ * invoke the {@link #addModuleArchiveInfo(ModuleArchiveInfo) addModuleArchiveInfo}
+ * method with the information of the module archives.
* <p>
* If new module definition(s) are constructed successfully by this method,
- * the implementation should add the module definitions to this
+ * the implementation must add the module definitions to this
* {@code Repository} by invoking the
- * {@link #addModuleDefinitions(Set)} method or the
- * {@link #addModuleDefinition(ModuleDefinition)} method.
+ * {@link #addModuleDefinitions(Set) addModuleDefinitions} method or the
+ * {@link #addModuleDefinition(ModuleDefinition) addModuleDefinition}
+ * method.
* <p>
* The default implementation of this method throws an {@code IOException}.
*
* @return a list of {@code ModuleArchiveInfo}s that represents the module
* archives loaded during initialization.
* @throws IOException if an I/O error occurs.
- * @see #initialize()
*/
protected List<ModuleArchiveInfo> doInitialize() throws IOException {
throw new IOException("Repository's initialization is not yet implemented.");
@@ -369,15 +368,15 @@ public abstract class Repository {
* <li><p> For each module definition in this {@code Repository}, invoke
* its module system's
* {@link ModuleSystem#disableModuleDefinition(ModuleDefinition)
- * <tt>disableModuleDefinition(ModuleDefinition)</tt>}
+ * disableModuleDefinition}
* method and {@link ModuleSystem#releaseModule(ModuleDefinition)
- * <tt>releaseModule(ModuleDefinition)</tt>} method.</p></li>
+ * releaseModule} method.</p></li>
*
* <li><p> Fire a single {@link RepositoryEvent.Type#MODULE_DEFINITION_REMOVED
* <tt>MODULE_DEFINITION_REMOVED</tt>} event if there is one or
* more module definitions in this {@code Repository}.</p></li>
*
- * <li><p> Fire a {@link RepositoryEvent.Type#REPOSITORY_SHUTDOWN
+ * <li><p> Fire a {@linkplain RepositoryEvent.Type#REPOSITORY_SHUTDOWN
* <tt>REPOSITORY_SHUTDOWN</tt>} event.</p></li>
* </ol>
*
@@ -395,7 +394,7 @@ public abstract class Repository {
*
* <li><p> Invoke the {@link #doShutdown()} method.</p></li>
*
- * <li><p> Invoke the {@link #removeModuleDefinitions(Set)}
+ * <li><p> Invoke the {@link #removeModuleDefinitions(Set) removeModuleDefinitions}
* method with the set of module definitions in this
* {@code Repository}.</p></li>
*
@@ -403,7 +402,7 @@ public abstract class Repository {
* <tt>REPOSITORY_SHUTDOWN</tt>} event.</p></li>
* </ol>
*
- * <p> Subclasses of <tt>Repository</tt> are encouraged to override {@link
+ * <p> Subclasses of {@code Repository} are encouraged to override {@link
* #doShutdown()}, rather than this method.</p>
*
* @throws SecurityException if a security manager exists and its
@@ -441,20 +440,24 @@ public abstract class Repository {
/**
* Shutdown this {@code Repository}. This method should be overridden
* by repository implementations, and will be invoked by the
- * {@link #shutdown()} method. The default implementation is a no-op.
+ * {@link #shutdown shutdown} method. The default implementation is a no-op.
*
* @throws IOException if an I/O error occurs.
- * @see #shutdown()
*/
protected void doShutdown() throws IOException {
// no-op
}
/**
- * Enable or disable that this {@code Repository} is shutdown when the
- * Java Module System terminates. Shutdown will be attempted only during
- * the normal termination of the virtual machine, as defined by the Java
- * Language Specification. By default, shutdown on exit is disabled.
+ * Enables or disables that this {@code Repository} is
+ * {@link #shutdown() shutdown} when the virtual machine
+ * terminates. By default, shutdown on exit is disabled.
+ * <p>
+ * The virtual machine will only attempt to shutdown the repositories
+ * during normal termination, as defined by the Java Language
+ * Specification. The virtual machine imposes no order on
+ * {@link #shutdown() shutdown} method calls among {@code Repository}
+ * instances. Shutdown may be called in any order or even concurrently.
* <p>
* If a security manager is present, this method calls the security
* manager's {@code checkPermission} method with a
@@ -510,13 +513,12 @@ public abstract class Repository {
* {@code Repository} is active when it has been
* {@linkplain #initialize() initialized} but not
* {@linkplain #shutdown() shutdown}. This method should be overridden
- * by subclasses of {@code Repository} if the {@link initialize()} and
- * {@link shutdown()} methods are also overridden.
+ * by subclasses of {@code Repository} if the
+ * {@link #initialize() initialize} and
+ * {@link #shutdown() shutdown} methods are also overridden.
*
* @return true if this {@code Repository} is active; otherwise, returns
* false.
- * @see #initialize()
- * @see #shutdown()
*/
public synchronized boolean isActive() {
return active;
@@ -548,7 +550,7 @@ public abstract class Repository {
}
/**
- * Find a module definition across multiple repositories through
+ * Finds a module definition across multiple repositories through
* the delegation model. Equivalent to:
* <pre>
* find(name, VersionConstraint.DEFAULT);</pre>
@@ -564,7 +566,7 @@ public abstract class Repository {
}
/**
- * Find a module definition across multiple repositories through the
+ * Finds a module definition across multiple repositories through the
* delegation model. Equivalent to:
* <pre>
* find(Query.module(name, versionConstraint))</pre>
@@ -601,7 +603,7 @@ public abstract class Repository {
}
/**
- * Find all module definitions across multiple repositories through the
+ * Finds all module definitions across multiple repositories through the
* delegation model. Equivalent to:
* <pre>
* find(Query.ANY);</pre>
@@ -616,49 +618,44 @@ public abstract class Repository {
}
/**
- * Find all matching module definitions across multiple repositories
+ * Finds all matching module definitions across multiple repositories
* through the delegation model. This method performs the following:
* <p><ol>
- * <li><p> Invoke the {@link #getParent()} method to determine the
- * parent repository.</p></li>
- *
- * <li><p> If the parent repository is {@code null}, invoke
- * the {@link #findModuleDefinitions(Query)} method to obtain
- * the set of module definitions and return.</p></li>
+ * <li><p> If the {@linkplain #getParent() parent repository} is
+ * {@code null}, invoke the
+ * {@link #findModuleDefinitions(Query) findModuleDefinitions}
+ * method to obtain the set of module definitions and return.</p></li>
*
* <li><p> Invoke the {@link #find(Query)} method of the parent
* repository to obtain the set of module definitions
* <i>P</i>.</p></li>
*
- * <li><p> Invoke the {@link #findModuleDefinitions(Query)} method
+ * <li><p> Invoke the {@link #findModuleDefinitions(Query) findModuleDefinitions} method
* to obtain the set of module definitions <i>C</i>.</p></li>
*
* <li><p> If the name of any module definition in <i>C</i> begins with
* "java.", throw a {@code SecurityException}.</p></li>
*
* <li><p> For each module definition in <i>C</i>, invoke the
- * {@link VisibilityPolicy#isVisible(ModuleDefinition)
- * <tt>isVisible()</tt>} method of the {@link VisibilityPolicy}
+ * {@linkplain VisibilityPolicy#isVisible(ModuleDefinition)
+ * isVisible} method of the {@link VisibilityPolicy}
* object returned from {@link #getVisibilityPolicy()} to
* determine if the module definition is visible. If not,
* remove the module definition from <i>C</i>.</p></li>
*
* <li><p> Determine the set of module definitions <i>R</i> as
- * follows:</p></li>
+ * follows and return <i>R</i>:</p></li>
* <ul>
* <li><p> All module definitions in <i>P</i> are in <i>R</i>.</p></li>
* <li><p> For each module definition in <i>C</i>, it is in
* <i>R</i> if and only if the module definition with the
- * same name and version is not present in <i>P</i>.</p></li>
+ * same name and version does not exist in <i>P</i>.</p></li>
* </ul>
- *
- * <li><p> Return <i>R</i> as the result.</p></li>
* </ol></p>
*
* @param constraint the constraint.
* @return the list of matching module definitions.
* @throws IllegalStateException if this {@code Repository} is not active.
- * @see #findModuleDefinitions(Query)
*/
public final List<ModuleDefinition> find(Query constraint) {
assertActive();
@@ -710,17 +707,21 @@ public abstract class Repository {
}
/**
- * Find all matching module definitions in this {@code Repository}. This
- * method should be overridden by repository implementations only for
+ * Finds all matching module definitions in this {@code Repository}. This
+ * method should be overridden by repository implementations for
* optimization, and will be invoked by the {@link #find(Query)} method.
- * The default implementation determines the result by matching each
+ * Implementation of this method must not return any module definition with
+ * name beginning with "java." in the result unless this
+ * {@code Repository} is the
+ * {@linkplain #getBootstrapRepository() bootstrap repository}.
+ * <p>
+ * The default implementation returns the result by matching each
* module definition in this {@code Repository} with the specified
* constraint.
*
* @param constraint the constraint.
* @return the list of matching module definitions.
* @throws IllegalStateException if this {@code Repository} is not active.
- * @see find(Query)
*/
protected synchronized List<ModuleDefinition> findModuleDefinitions(Query constraint) {
assertActive();
@@ -753,8 +754,8 @@ public abstract class Repository {
* {@linkplain #isActive() active},
* throws an {@code IllegalStateException}.</p></li>
*
- * <li><p> Invoke the {@link #getModuleArchiveInfos()} method to
- * determine the list of {@code ModuleArchiveInfo}s, and return
+ * <li><p> Invoke the {@link #getModuleArchiveInfos() getModuleArchiveInfos}
+ * method to determine the list of {@code ModuleArchiveInfo}s, and return
* the result.</p></li>
* </ul>
* The default implementation of this method throws an
@@ -773,7 +774,7 @@ public abstract class Repository {
}
/**
- * Install a module archive into this {@code Repository}. This method
+ * Installs a module archive into this {@code Repository}. This method
* should be overridden by repository implementations as follows:
* <p><ol>
* <li><p> If a security manager is present, calls the security
@@ -789,31 +790,33 @@ public abstract class Repository {
* {@linkplain #isActive() active},
* throws an {@code IllegalStateException}.</p></li>
*
- * <li><p> Invoke the {@link #isReadOnly()} method to check if this
- * {@code Repository} is read-only. If it returns {@code false},
+ * <li><p> If this {@code Repository} is
+ * {@linkplain #isReadOnly() read only},
* throws an {@code UnsupportedOperationException}.</p></li>
*
* <li><p> Perform the actual installation of the module archive and this
* is repository implementation specific.</p></li>
*
* <li><p> If the module archive is installed successfully, invoke the
- * {@link #addModuleArchiveInfo(ModuleArchiveInfo)} method.
+ * {@link #addModuleArchiveInfo(ModuleArchiveInfo) addModuleArchiveInfo} method.
* </p></li>
* </ol>
- *
- * <p> If the repository implementations change the set of module
- * definitions after the installation of the module archive, they should
- * perform the following:
+ * <p> A repository implementation may check additional conditions beyond
+ * what are required in this method before installing a module archive.
+ *
+ * <p> A repository implementation may change the set of module definitions
+ * in the repository after the installation of the module archive. The
+ * repository implementation must do the following if such a change occurs:
* <p><ul>
* <li><p> If a new module definition is added, invoke the
- * {@link #addModuleDefinition(ModuleDefinition)} method with
- * that module definition.
+ * {@link #addModuleDefinition(ModuleDefinition) addModuleDefinition}
+ * method with that module definition.
* </p></li>
*
* <li><p> If an existing module definition is replaced, invoke the
- * {@link #removeModuleDefinition(ModuleDefinition)}
+ * {@link #removeModuleDefinition(ModuleDefinition) removeModuleDefinition}
* method with the old module definition, and invoke the
- * {@link #addModuleDefinition(ModuleDefinition)}
+ * {@link #addModuleDefinition(ModuleDefinition) addModuleDefinition}
* method with the new module definition.</p></li>
* </ul>
* The default implementation of this method throws an
@@ -840,7 +843,7 @@ public abstract class Repository {
}
/**
- * Uninstall a module archive from this {@code Repository}. This method
+ * Uninstalls a module archive from this {@code Repository}. This method
* should be overridden by repository implementations as follows:
* <p><ol>
* <li><p> If a security manager is present, calls the security
@@ -856,31 +859,34 @@ public abstract class Repository {
* {@linkplain #isActive active},
* throws an {@code IllegalStateException}.</p></li>
*
- * <li><p> Invoke the {@link #isReadOnly()} method to check if this
- * {@code Repository} is read-only. If it returns {@code false},
+ * <li><p> If this {@code Repository} is
+ * {@linkplain #isReadOnly() read only},
* throws an {@code UnsupportedOperationException}.</p></li>
*
* <li><p> Perform the actual uninstallation of the module archive and
* this is repository implementation specific.</p></li>
*
* <li><p> If the module archive is uninstalled successfully, invoke the
- * {@link #removeModuleArchiveInfo(ModuleArchiveInfo)} method.
+ * {@link #removeModuleArchiveInfo(ModuleArchiveInfo) removeModuleArchiveInfo}
+ * method.
* </p></li>
* </ol>
- *
- * <p> If the repository implementations change the set of module
- * definitions after the uninstallation of the module archive, they
- * should perform the following:
+ * <p> A repository implementation may check additional conditions beyond
+ * what are required in this method before uninstalling a module archive.
+ *
+ * <p> A repository implementation may change the set of module definitions
+ * in the repository after the uninstallation of the module archive. The
+ * repository implementation must do the following if such a change occurs:
* <p><ul>
* <li><p> If an existing module definition is removed, invoke the
- * {@link #removeModuleDefinition(ModuleDefinition)} method
- * with that module definition.
+ * {@link #removeModuleDefinition(ModuleDefinition) removeModuleDefinition}
+ * method with that module definition.
* </p></li>
*
* <li><p> If an existing module definition is replaced, invoke the
- * {@link #removeModuleDefinition(ModuleDefinition)}
+ * {@link #removeModuleDefinition(ModuleDefinition) removeModuleDefinition}
* method with the old module definition, and invoke the
- * {@link #addModuleDefinition(ModuleDefinition)}
+ * {@link #addModuleDefinition(ModuleDefinition) addModuleDefinition}
* method with the new module definition.</p></li>
* </ul>
* The default implementation of this method throws an
@@ -903,7 +909,7 @@ public abstract class Repository {
}
/**
- * Reload the module archives in this {@code Repository}. This method
+ * Reloads the module archives in this {@code Repository}. This method
* should be overridden and implemented by repository implementations
* as follows:
* <p><ol>
@@ -917,49 +923,51 @@ public abstract class Repository {
* {@linkplain #isActive active},
* throws an {@code IllegalStateException}.</p></li>
*
- * <li><p> Invoke the {@link #supportsReload()} method to check if this
- * {@code Repository} supports reload. If it returns {@code false},
+ * <li><p> If this {@code Repository} does not
+ * {@linkplain #supportsReload() support reload},
* throws an {@code UnsupportedOperationException}.</p></li>
*
* <li><p> Perform the actual reload of module definitions and this is
* repository implementation specific.</p></li>
* </ol>
- * <p> If the repository implementations change the set of module archives
- * after reload, they should perform the following:
+ * <p> A repository implementation may change the set of module archives
+ * in the repository after reload. The repository implementation must do
+ * the following if such a change occurs:
* <p><ul>
* <li><p> If a new module archive is added, invoke the
- * {@link #addModuleArchiveInfo(ModuleArchiveInfo)}
+ * {@link #addModuleArchiveInfo(ModuleArchiveInfo) addModuleArchiveInfo}
* method with that module archive's information.
* </p></li>
*
* <li><p> If an existing module archive is removed, invoke the
- * {@link #removeModuleArchiveInfo(ModuleArchiveInfo)} method
- * with that module archive's information.
+ * {@link #removeModuleArchiveInfo(ModuleArchiveInfo) removeModuleArchiveInfo}
+ * method with that module archive's information.
* </p></li>
*
* <li><p> If an existing module archive is replaced, invoke the
- * {@link #removeModuleArchiveInfo(ModuleArchiveInfo)}
+ * {@link #removeModuleArchiveInfo(ModuleArchiveInfo) removeModuleArchiveInfo}
* method with the old module archive's information, and invoke the
- * {@link #addModuleArchiveInfo(ModuleArchiveInfo)}
+ * {@link #addModuleArchiveInfo(ModuleArchiveInfo) addModuleArchiveInfo}
* method with the new module archive's information.</p></li>
* </ul>
- * <p> If the repository implementations change the set of module
- * definitions after reload, they should perform the following:
+ * <p> A repository implementation may change the set of module definitions
+ * in the repository after the installation of the module archive. The repository
+ * implementation must do the following if such a change occurs:
* <p><ul>
* <li><p> If a new module definition is added, invoke the
- * {@link #addModuleDefinition(ModuleDefinition)}
+ * {@link #addModuleDefinition(ModuleDefinition) addModuleDefinition}
* method with that module definition.
* </p></li>
*
* <li><p> If an existing module definition is removed, invoke the
- * {@link #removeModuleDefinition(ModuleDefinition)} method
- * with that module definition.
+ * {@link #removeModuleDefinition(ModuleDefinition) removeModuleDefinition}
+ * method with that module definition.
* </p></li>
*
* <li><p> If an existing module definition is replaced, invoke the
- * {@link #removeModuleDefinition(ModuleDefinition)}
+ * {@link #removeModuleDefinition(ModuleDefinition) removeModuleDefinition}
* method with the old module definition, and invoke the
- * {@link #addModuleDefinition(ModuleDefinition)}
+ * {@link #addModuleDefinition(ModuleDefinition) addModuleDefinition}
* method with the new module definition.</p></li>
* </ul>
* The default implementation of this method throws an
@@ -1010,7 +1018,7 @@ public abstract class Repository {
* if this {@code Repository} already contains
* one of more of the specified module definitions.
*
- * @param moduleDef a set of module definitions to be added
+ * @param mds a set of module definitions to be added
* @return true if the module definitions in this {@code Repository}
* changed as a result of the call.
* @throws IllegalStateException if this {@code Repository} has been
@@ -1055,9 +1063,9 @@ public abstract class Repository {
* If the module definition is removed successfully, this method invokes
* its module system's
* {@link ModuleSystem#disableModuleDefinition(ModuleDefinition)
- * <tt>disableModuleDefinition(ModuleDefinition)</tt>} method and the
+ * disableModuleDefinition} method and the
* {@link ModuleSystem#releaseModule(ModuleDefinition)
- * <tt>releaseModule(ModuleDefinition)</tt>} method.</p></li>
+ * releaseModule} method.</p></li>
*
* @param moduleDef module definition to be removed
* @return true if the module definitions in this {@code Repository}
@@ -1083,10 +1091,10 @@ public abstract class Repository {
* For each module definition that is removed successfully, this method
* invokes its module system's
* {@link ModuleSystem#disableModuleDefinition(ModuleDefinition)
- * <tt>disableModuleDefinition(ModuleDefinition)</tt>}
+ * disableModuleDefinition}
* method and
* {@link ModuleSystem#releaseModule(ModuleDefinition)
- * <tt>releaseModule(MOduleDefinition)</tt>} method.
+ * releaseModule} method.
*
* @param mds the set of module definitions to be removed
* @return true if the module definitions in this {@code Repository}
@@ -1313,8 +1321,9 @@ public abstract class Repository {
}
/**
- * Processes repository event occuring in this {@code Repository} by
- * dispatching them to any registered {@code RepositoryListener} objects.
+ * Processes repository event occurring in this {@code Repository} by
+ * dispatching them to any registered {@code RepositoryListener} objects
+ * asynchronously.
*
* @param event the repository event
*/
@@ -1379,13 +1388,8 @@ public abstract class Repository {
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
- builder.append("repository ");
builder.append(getName());
- if (getSourceLocation() != null) {
- builder.append(" (");
- builder.append(getSourceLocation());
- builder.append(")");
- }
+ builder.append(" repository");
return builder.toString();
}
--- a/src/share/classes/java/module/RepositoryMetadata.xml Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/RepositoryMetadata.xml Thu Jul 24 17:30:52 2008 -0700
@@ -44,24 +44,30 @@ have any questions.
</xs:complexType>
<xs:complexType name="ModuleType">
<xs:sequence>
- <!-- Name of the module. -->
+ <!-- Name of the JAM module. -->
<xs:element name="name" type="xs:string"/>
<!--
- Version of the module. It must follow the version
- format in the module versioning scheme.
+ Version of the JAM module. It must conform to the version
+ format in the versioning scheme in the Java Module System.
-->
<xs:element name="version" type="xs:string"/>
<!--
- Platform binding of the module.
+ Platform binding of the JAM module.
-->
<xs:element name="platform-binding"
type="PlatformBindingType" minOccurs="0" maxOccurs="1"/>
<!--
- Relative path to the files that belong to the specified
- module, including the module file (i.e.
- METADATA.module), the module archive (i.e. .jam file)
+ Relative path to the files which belong to the specified
+ JAM module, including the module file (i.e.
+ MODULE.METADATA), the module archive (i.e. .jam file)
and/or the packed module archive (i.e. .jam.pack.gz
- file).
+ file).
+
+ URL repository implementations must treat the path as
+
+ <name>/<version>[/<platform>-<arch>]
+
+ if this element is missing.
-->
<xs:element name="path" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
@@ -69,13 +75,13 @@ have any questions.
<xs:complexType name="PlatformBindingType">
<xs:sequence>
<!--
- Name of the platform. It should be one of the
- possible values of the system property "os.platform".
+ Name of the platform. It is one of the possible values
+ of the system property "os.platform".
-->
<xs:element name="platform" type="xs:string"/>
<!--
- Architecture of the platform. It should be one of
- the possible values of the system property "os.arch".
+ Architecture of the platform. It is one of the possible values
+ of the system property "os.arch".
-->
<xs:element name="arch" type="xs:string"/>
</xs:sequence>
--- a/src/share/classes/java/module/Version.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/Version.java Thu Jul 24 17:30:52 2008 -0700
@@ -57,6 +57,9 @@ import java.util.regex.Pattern;
* </li></p>
*
* <p><li> If {@code update} is not specified, it is treated as {@code 0}.
+ * </li></p>
+ *
+ * <p><li> If {@code qualifier} is not specified, it is treated as an empty string.
* </li></p>
* </ul></p>
*
@@ -85,14 +88,15 @@ import java.util.regex.Pattern;
* {@code digit} is a decimal digit, {@code 0-9}.
* <p>
* When two versions are compared, {@code major}, {@code minor},
- * {@code micro}, and {@code update} are compared numerically while
- * {@code qualifier} is compared through string comparison lexicographically.
- * Two versions are equivalent if and only if the major numbers, the minor
- * numbers, the micro numbers, the update numbers, and the qualifiers each
- * are equal respectively. If the major numbers, the minor numbers, the
- * micro numbers, and the update numbers of two versions are equal
- * respectively but one version has a qualifier while the other has
- * none, the latter is considered a higher version. For example,
+ * {@code micro}, and {@code update} must be compared numerically while
+ * {@code qualifier} must be compared through string comparison
+ * lexicographically. Two versions are equivalent if and only if the
+ * major numbers, the minor numbers, the micro numbers, the update
+ * numbers, and the qualifiers each are equal respectively. If the
+ * major numbers, the minor numbers, the micro numbers, and the
+ * update numbers of two versions are equal respectively but one
+ * version has a qualifier while the other has none, the latter
+ * must be treated as a higher version. For example,
* <pre>
* 1 < 1.2 < 1.3.1 < 2
*
@@ -164,7 +168,7 @@ public final class Version implements Co
}
// Parse qualifier
- String qualifier = null;
+ String qualifier = "";
int qualifierIndex = version.indexOf('-');
if (qualifierIndex > 0) {
qualifier = version.substring(qualifierIndex + 1);
@@ -192,7 +196,7 @@ public final class Version implements Co
* Returns a {@code Version} object holding the specified version number.
* Equivalent to:
* <pre>
- * valueOf(major, minor, micro, 0, null)</pre>
+ * valueOf(major, minor, micro, 0, "")</pre>
*
* @param major the major version number.
* @param minor the minor version number.
@@ -201,13 +205,13 @@ public final class Version implements Co
* negative.
*/
public static Version valueOf(int major, int minor, int micro) {
- return Version.valueOf(major, minor, micro, 0, null);
+ return Version.valueOf(major, minor, micro, 0, "");
}
/**
* Returns a {@code Version} object holding the specified version number.
- * If the version number has no qualifier, {@code qualifier} is
- * {@code null}. Equivalent to:
+ * If the version number has no qualifier, {@code qualifier} is an
+ * empty string. Equivalent to:
* <pre>
* valueOf(major, minor, micro, 0, qualifier)</pre>
*
@@ -226,7 +230,7 @@ public final class Version implements Co
* Returns a {@code Version} object holding the specified version number.
* Equivalent to:
* <pre>
- * valueOf(major, minor, micro, update, null)</pre>
+ * valueOf(major, minor, micro, update, "")</pre>
*
* @param major the major version number.
* @param minor the minor version number.
@@ -236,13 +240,13 @@ public final class Version implements Co
* negative.
*/
public static Version valueOf(int major, int minor, int micro, int update) {
- return Version.valueOf(major, minor, micro, update, null);
+ return Version.valueOf(major, minor, micro, update, "");
}
/**
* Returns a {@code Version} object holding the specified version number.
* If the version number has no qualifier, {@code qualifier} is
- * {@code null}.
+ * an empty string.
*
* @param major the major version number.
* @param minor the minor version number.
@@ -253,6 +257,10 @@ public final class Version implements Co
* negative, or if qualifier contains illegal characters.
*/
public static Version valueOf(int major, int minor, int micro, int update, String qualifier) {
+ if (qualifier == null) {
+ throw new NullPointerException("qualifier must not be null.");
+ }
+
// we could add a basic caching scheme here to reuse Version objects
int[] components = new int[4];
components[0] = major;
@@ -284,7 +292,7 @@ public final class Version implements Co
if (components[3] < 0)
throw new IllegalArgumentException("Update version number must not be negative: " + components[3]);
- if (qualifier != null && qualifierPattern.matcher(qualifier).matches() == false)
+ if (qualifier.isEmpty() == false && qualifierPattern.matcher(qualifier).matches() == false)
throw new IllegalArgumentException("qualifier must contain only legal character: " + qualifier);
// this constructor is private, and it claims the ownership of
@@ -331,7 +339,7 @@ public final class Version implements Co
/**
* Returns the qualifier. If this {@code Version} has no qualifier, this
- * method returns {@code null}.
+ * method returns an empty string.
*
* @return the qualifier.
*/
@@ -449,20 +457,20 @@ public final class Version implements Co
// Is there a qualifier?
String qualifier2 = version.getQualifier();
- if (qualifier != null) {
- if (qualifier2 == null) {
+ if (qualifier.isEmpty() == false) {
+ if (qualifier2.isEmpty()) {
return -1;
}
return qualifier.compareTo(qualifier2);
}
- return qualifier2 == null ? 0 : 1;
+ return qualifier2.isEmpty() ? 0 : 1;
}
/**
* Returns a {@code Version} instance, with the qualifier omitted.
*/
Version trimQualifier() {
- if (getQualifier() == null)
+ if (getQualifier().isEmpty())
return this;
else
return Version.valueOf(getMajorNumber(), getMinorNumber(),
@@ -500,7 +508,7 @@ public final class Version implements Co
for (int n : components) {
result = 37 * result + n;
}
- result = 37 * result + (qualifier != null ? qualifier.hashCode() : 0);
+ result = 37 * result + (qualifier.isEmpty() == false ? qualifier.hashCode() : 0);
return result;
}
@@ -530,7 +538,7 @@ public final class Version implements Co
}
}
- if (qualifier != null) {
+ if (qualifier.isEmpty() == false) {
buffer.append('-');
buffer.append(qualifier);
}
--- a/src/share/classes/java/module/VersionConstraint.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/VersionConstraint.java Thu Jul 24 17:30:52 2008 -0700
@@ -72,19 +72,20 @@ import java.util.StringTokenizer;
* 1.* ~ [1, 2) ~ 1 <= x < 2
* 1.2.* ~ [1.2, 1.3) ~ 1.2 <= x < 1.3
* 1.2.3.* ~ [1.2.3, 1.2.4) ~ 1.2.3 <= x < 1.2.4</pre>
- * It is possible to group two or more version ranges together as an union of
- * ranges, using the {@code ';'} character as separator.
+ * <p>
+ * <h3>Version constraint</h3>
+ * Version constraint is a mechanism in expressing versioning requirement
+ * in the Java Module System, using versions and version ranges as building
+ * blocks. Version and version range are really shorthands in establishing
+ * compatibility, and they can be used to express more arbitrary range,
+ * version inclusion, or version exclusion if needed.
+ * <p>
+ * A version constraint is either a version, a version range, or combination
+ * of both; versions and version ranges are grouped together using the
+ * {@code ';'} character. For examples,
* <pre>
* [1.2.3.4, 2.0);2.*;3+ ~ 1.2.3.4 <= x < infinity
- * 1.*;[2.0, 2.7.3) ~ 1.0.0 <= x < 2.7.3</pre>
- * <p>
- * <h3>Version constraint</h3>
- * A version constraint is a mechanism in expressing versioning requirement
- * through versions and version ranges. The version and the version range are
- * really shorthands in establishing compatibility. If more arbitrary range,
- * version inclusion, or version exclusion is needed, the version and the
- * version range can be used as building blocks to express the versioning
- * requirement.
+ * 1.*;[3.0, 3.7.3) ~ 1.0.0 <= x < 2.0.0, or 3.0.0 <= x < 3.7.3</pre>
* <p>
* The grammar for the version constraint is as follows:
* <pre>
@@ -107,6 +108,7 @@ import java.util.StringTokenizer;
* where {@code alpha} is an alphabetic character, {@code a-z, A-Z}.
* {@code digit} is a decimal digit, {@code 0-9}.
* <p>
+ *
* Applications can obtain {@code VersionConstraint} objects by calling the
* {@link #valueOf(String) valueOf} factory method.
*
--- a/src/share/classes/java/module/annotation/AllowShadowing.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/AllowShadowing.java Thu Jul 24 17:30:52 2008 -0700
@@ -31,11 +31,12 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.RetentionPolicy;
/**
- * Indicates that the shadowing check is disabled on a module instance when
- * shallow validation is performed during module initialization. If the
- * shadowing check is disabled, it would be possible for classes from the
- * imported modules to shadow classes in the module. This metadata annotation is
- * applied to a Java module. For example,
+ * Indicates that class shadowing is allowed in the module instances of
+ * a module definition. Shallow validation in the JAM module
+ * sytem must permit the member classes in the module instance to be
+ * shadowed by the exported classes of its imported modules, if class
+ * shadowing is explicitly allowed in the module instance. This
+ * metadata annotation is applied to a Java module. For example,
* <blockquote><pre>
* //
* // com/wombat/webservice/module-info.java
@@ -43,7 +44,7 @@ import java.lang.annotation.RetentionPol
* &#064;Version("1.0.0")
* &#064;AllowShadowing
* &#064;ImportModules({
- * // The imported module is optional, but it has classes that could shadow
+ * // The imported module has exported classes that can shadow
* // classes in the module, so shadowing check needs to be disabled.
* &#064;ImportModule(name="opensource.utils", version="[1.0, 2.0)", optional=true)
* })
--- a/src/share/classes/java/module/annotation/Attribute.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/Attribute.java Thu Jul 24 17:30:52 2008 -0700
@@ -31,8 +31,8 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.RetentionPolicy;
/**
- * Indicates an attribute. This metadata annotation is used as nested
- * annotation inside other enclosing annotations. For
+ * Indicates an attribute in a module definition. This metadata annotation
+ * is used as nested annotation inside other enclosing annotations. For
* example,
* <blockquote><pre>
* //
--- a/src/share/classes/java/module/annotation/Attributes.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/Attributes.java Thu Jul 24 17:30:52 2008 -0700
@@ -31,8 +31,8 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.RetentionPolicy;
/**
- * Indicates an array of attributes. This metadata annotation can be applied
- * to a Java module. For example,
+ * Indicates an array of attributes in a module definition. This metadata
+ * annotation is applied to a Java module. For example,
* <blockquote><pre>
* //
* // com/wombat/xyz/module-info.java
--- a/src/share/classes/java/module/annotation/ClassesDirectoryPath.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/ClassesDirectoryPath.java Thu Jul 24 17:30:52 2008 -0700
@@ -50,7 +50,7 @@ public @interface ClassesDirectoryPath {
/**
* The path for searching classes and resources in the module archive. It
* must be a relative path to the root of the module archive, using
- * {@code '/'} as path separator and no leading {@code '/'}.
+ * {@code '/'} as the path separator and with no leading {@code '/'}.
*/
String value();
}
--- a/src/share/classes/java/module/annotation/ExportLegacyClasses.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/ExportLegacyClasses.java Thu Jul 24 17:30:52 2008 -0700
@@ -31,11 +31,10 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.RetentionPolicy;
/**
- * Indicates that the legacy classes are exported from a module definition.
- * A legacy class is a Java class which does not belong to any Java module;
- * a legacy class is exportable from a module definition if that class
- * is public. This metadata annotation is applied to a Java module.
- * For example,
+ * Indicates that the legacy classes in a module definition are exported.
+ * A legacy class is a Java class which does not belong to any Java module.
+ * A legacy class can be exported if it is declared {@code public}.
+ * This metadata annotation is applied to a Java module. For example,
* <blockquote><pre>
* //
* // com/wombat/xyz/module-info.java
--- a/src/share/classes/java/module/annotation/ExportResources.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/ExportResources.java Thu Jul 24 17:30:52 2008 -0700
@@ -32,16 +32,7 @@ import java.lang.annotation.RetentionPol
/**
* Indicates the exported resources in a module definition. This metadata
- * annotation is applied to a Java module.
- * <p>
- * The string that specifies the exported resource may contain wildcard:<p>
- * 1. {@code '?'} matches a single character.<p>
- * 2. {@code '*'} matches zero or more characters.<p>
- * 3. {@code '**'} matches zero or more directories.<p>
- * There is also a shorthand. If the string ends with {@code '/'}, it is
- * treated as if {@code '**'} has been appended.
- * <p>
- * For examples,
+ * annotation is applied to a Java module. For examples,
* <blockquote><pre>
* //
* // com/wombat/xyz/module-info.java
@@ -72,9 +63,17 @@ public @interface ExportResources {
public @interface ExportResources {
/**
- * The exported resources in a module definition. Each exported resource
- * must be a relative path to the root of the module archive, using
- * {@code '/'} as path separator and no leading {@code '/'}.
+ * The exported resources in a module definition. The string that specifies
+ * each exported resource must be a relative path to the root of the module
+ * archive, using {@code '/'} as the path separator and with no leading
+ * {@code '/'}. The string may contain wildcard:<p>
+ * <ol>
+ * <li> {@code '?'} matches a single character.</li>
+ * <li> {@code '*'} matches zero or more characters.</li>
+ * <li> {@code '**'} matches zero or more directories.</li>
+ * </ol><p>
+ * If the string ends with {@code '/'}, it must be treated as if
+ * {@code '**'} has been appended.
*/
String[] value();
}
--- a/src/share/classes/java/module/annotation/ImportModule.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/ImportModule.java Thu Jul 24 17:30:52 2008 -0700
@@ -53,33 +53,29 @@ public @interface ImportModule {
public @interface ImportModule {
/**
- * Name of the imported module definition.
+ * The name of the module definition to import.
*/
String name();
/**
- * Version constraint of the imported module definition. The version
- * constraint is either a version, a version range, or a combination of
- * both, following the format described in the
- * {@link java.module.VersionConstraint} class. If the version constraint
- * is not specified, the default is the highest version available.
+ * The version constraint of the import. The value
+ * must follow the
+ * {@linkplain java.module.VersionConstraint version constraint format}.
*/
String version() default "0.0.0.0+";
/**
- * Optionality of the imported module definition. If optionality is not
- * specified, the default is false.
+ * The optionality of the import.
*/
boolean optional() default false;
/**
- * Re-export the imported module definition. If re-export is not specified,
- * the default is false.
+ * The re-export of the import.
*/
boolean reexport() default false;
/**
- * Other attributes. If no attributes is specified, the default is {}.
+ * Other attributes.
*/
Attribute[] attributes() default {};
}
--- a/src/share/classes/java/module/annotation/ImportPolicyClass.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/ImportPolicyClass.java Thu Jul 24 17:30:52 2008 -0700
@@ -32,9 +32,9 @@ import java.lang.annotation.RetentionPol
/**
* Indicates the import policy class of a module definition. The class must
- * implement {@link java.module.ImportPolicy}; it must also be declared as
- * public, and have a public default constructor. This metadata annotation is
- * applied to a Java module. For example,
+ * implement {@link java.module.ImportPolicy}. The class must be declared
+ * {@code public}, and must have a public constructor which takes no argument.
+ * This metadata annotation is applied to a Java module. For example,
* <blockquote><pre>
* //
* // com/wombat/xyz/module-info.java
@@ -51,7 +51,8 @@ public @interface ImportPolicyClass {
public @interface ImportPolicyClass {
/**
- * The name of the import policy class.
+ * The name of the import policy class. The value must not have the
+ * {@code .class} extension appended.
*/
String value();
}
--- a/src/share/classes/java/module/annotation/JarLibraryPath.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/JarLibraryPath.java Thu Jul 24 17:30:52 2008 -0700
@@ -49,9 +49,9 @@ public @interface JarLibraryPath {
public @interface JarLibraryPath {
/**
- * The path for searching JAR files in the module archive. It must be a
- * relative path to the root of the module archive, using {@code '/'} as
- * path separator and no leading {@code '/'}.
+ * The path for searching JAR files in the module archive. The value must
+ * be specified as a relative path to the root of the module archive, using
+ * {@code '/'} as the path separator and with no leading {@code '/'}.
*/
String value();
}
--- a/src/share/classes/java/module/annotation/MainClass.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/MainClass.java Thu Jul 24 17:30:52 2008 -0700
@@ -31,9 +31,11 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.RetentionPolicy;
/**
- * Indicates the main class of a module definition. The main class name must
- * not have the {@code .class} extension appended. This metadata annotation is
- * applied to a Java module. For example,
+ * Indicates the main class of a module definition. The main class must be
+ * declared {@code public}. The main class must have a {@code main} method
+ * which is declared {@code public}, {@code static}, and {@code void}; the
+ * {@code main} method must accept a single argument that is an array of
+ * strings. This metadata annotation is applied to a Java module. For example,
* <blockquote><pre>
* //
* // com/wombat/xyz/module-info.java
@@ -42,9 +44,6 @@ import java.lang.annotation.RetentionPol
* &#064;MainClass("com.wombat.xyz.Main")
* module com.wombat.xyz;
* </pre></blockquote>
- * The main class must have a {@code main} method which is declared public,
- * static, and void; the method must accept a single argument that is an array
- * of strings.
*
* @since 1.7
*/
@@ -52,7 +51,8 @@ import java.lang.annotation.RetentionPol
@Retention(RetentionPolicy.RUNTIME)
public @interface MainClass {
/**
- * The name of the main class.
+ * The name of the main class. The value must not have the
+ * {@code .class} extension appended.
*/
String value();
}
--- a/src/share/classes/java/module/annotation/ModuleInitializerClass.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/ModuleInitializerClass.java Thu Jul 24 17:30:52 2008 -0700
@@ -32,9 +32,9 @@ import java.lang.annotation.RetentionPol
/**
* Indicates the class of the initializer of a module definition. The class
- * must implement {@link java.module.ModuleInitializer}; it must also be
- * declared as public, and have a public constructor. This metadata annotation
- * is applied to a Java module. For example,
+ * must implement {@link java.module.ModuleInitializer}. The class must be
+ * declared {@code public}, and must have a public constructor which takes no
+ * argument. This metadata annotation is applied to a Java module. For example,
* <blockquote><pre>
* //
* // com/wombat/xyz/module-info.java
@@ -51,7 +51,8 @@ public @interface ModuleInitializerClass
public @interface ModuleInitializerClass {
/**
- * The name of the initializer class.
+ * The name of the initializer class. The value must not have the
+ * {@code .class} extension appended.
*/
String value();
}
--- a/src/share/classes/java/module/annotation/NativeLibraryPath.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/NativeLibraryPath.java Thu Jul 24 17:30:52 2008 -0700
@@ -54,21 +54,21 @@ public @interface NativeLibraryPath {
public @interface NativeLibraryPath {
/**
- * The name of the platform. It should be one of the possible values of the
- * system property {@code "os.platform"}.
+ * The name of the platform. The value must be one of the possible values
+ * of the system property {@code "os.platform"}.
*/
String platform();
/**
- * The name of the architecture. It should be one of the possible values of
- * the system property {@code "os.arch"}.
+ * The name of the architecture. The value must be one of the possible
+ * values of the system property {@code "os.arch"}.
*/
String arch();
/**
- * The path for searching native libraries in the module archive. It must
- * be a relative path to the root of the module archive, using {@code '/'}
- * as path separator and no leading {@code '/'}.
+ * The path for searching native libraries in the module archive. The
+ * value must be a relative path to the root of the module archive,
+ * using {@code '/'} as the path separator and with no leading {@code '/'}.
*/
String path();
}
--- a/src/share/classes/java/module/annotation/NativeLibraryPaths.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/NativeLibraryPaths.java Thu Jul 24 17:30:52 2008 -0700
@@ -32,7 +32,7 @@ import java.lang.annotation.RetentionPol
/**
* Indicates the paths for searching native libraries in the module archive for
- * different platforms and architectures. This metadata annotation is applied
+ * multiple platforms and architectures. This metadata annotation is applied
* to a Java module. For example,
* <blockquote><pre>
* //
@@ -55,7 +55,7 @@ public @interface NativeLibraryPaths {
/**
* An array of paths for searching native libraries in the module archive
- * for different platforms and architectures.
+ * for multiple platforms and architectures.
*/
NativeLibraryPath[] value();
}
--- a/src/share/classes/java/module/annotation/PlatformBinding.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/PlatformBinding.java Thu Jul 24 17:30:52 2008 -0700
@@ -62,14 +62,14 @@ public @interface PlatformBinding {
public @interface PlatformBinding {
/**
- * The name of the platform. It should be one of the possible values of the
- * system property {@code "os.platform"}.
+ * The name of the platform. The value must be one of the possible values
+ * of the system property {@code "os.platform"}.
*/
String platform();
/**
- * The name of the architecture. It should be one of the possible values of
- * the system property {@code "os.arch"}.
+ * The name of the architecture. The value must be one of the possible
+ * values of the system property {@code "os.arch"}.
*/
String arch();
}
--- a/src/share/classes/java/module/annotation/ResourceModuleConstraint.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/ResourceModuleConstraint.java Thu Jul 24 17:30:52 2008 -0700
@@ -31,11 +31,10 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.RetentionPolicy;
/**
- * Indicates the version constraint that a <i>target module</i> requires its
- * <i>resource modules</i> to satisfy. The version constraint is either a
- * version, a version range, or a combination of both, following the format
- * described in the {@link java.module.VersionConstraint} class. This metadata
- * annotation is applied to a Java module. For example,
+ * Indicates the version constraint which a
+ * <a href="../../../java/util/ResourceBundle.html"><i>target module</i></a>
+ * requires its <i>resource modules</i> to satisfy. This metadata annotation
+ * is applied to a Java module which is a <i>target module</i>. For example,
* <blockquote><pre>
* //
* // org/foo/xml/module-info.java
@@ -52,8 +51,11 @@ import java.lang.annotation.RetentionPol
@Retention(RetentionPolicy.RUNTIME)
public @interface ResourceModuleConstraint {
/**
- * The version constraint that this <i>target module</i> requires its
- * <i>resource modules</i> to satisfy.
+ * The version constraint which this
+ * <a href="../../../java/util/ResourceBundle.html"><i>target module</i></a>
+ * requires its <i>resource modules</i> to satisfy. The value must
+ * follow the
+ * {@linkplain java.module.VersionConstraint version constraint format}.
*/
String value() default "0.0.0.0+";
}
--- a/src/share/classes/java/module/annotation/ResourceTargetConstraint.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/ResourceTargetConstraint.java Thu Jul 24 17:30:52 2008 -0700
@@ -31,11 +31,10 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.RetentionPolicy;
/**
- * Indicates the version constraint that a <i>resource module</i> requires its
- * <i>target module</i> to satisfy. The version constraint is either a
- * version, a version range, or a combination of both, following the format
- * described in the {@link java.module.VersionConstraint} class. This metadata
- * annotation is applied to a Java module. For example,
+ * Indicates the version constraint which a
+ * <a href="../../../java/util/ResourceBundle.html"><i>resource module</i></a>
+ * requires its <i>target module</i> to satisfy. This metadata annotation is
+ * applied to a Java module which is a <i>resource module</i>. For example,
* <blockquote><pre>
* //
* // org/foo/xml/locale_fr/module-info.java
@@ -52,8 +51,10 @@ import java.lang.annotation.RetentionPol
@Retention(RetentionPolicy.RUNTIME)
public @interface ResourceTargetConstraint {
/**
- * The version constraint that this <i>resource module</i> requires its
- * <i>target module</i> to satisfy.
+ * The version constraint which this
+ * <a href="../../../java/util/ResourceBundle.html"><i>resource module</i></a>
+ * requires its <i>target module</i> to satisfy. The value must follow the
+ * {@linkplain java.module.VersionConstraint version constraint format}.
*/
String value() default "0.0.0.0+";
}
--- a/src/share/classes/java/module/annotation/ServiceProvider.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/ServiceProvider.java Thu Jul 24 17:30:52 2008 -0700
@@ -31,15 +31,13 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.RetentionPolicy;
/**
- * Indicates a service-provider that a module definition defines.
- * A service is a well-known set of interfaces and (usually abstract) classes.
- * A service-provider is a specific implementation of a service. The classes
- * in a service-provider typically implement the interfaces and subclass the
- * classes defined in the service itself. If a module definition defines a
- * service-provider, it should import the module definition which defines
- * the service. It should also contain and export the set of interfaces and
- * classes that are part of the service-provider. This metadata annotation is
- * used as nested annotation inside other enclosing annotations. For example,
+ * Indicates a
+ * <a href="../../../java/util/ServiceLoader.html"><i>service provider</i></a>
+ * which is defined in a module definition. The module definition must export the
+ * <i>service provider</i>'s types, and must import a module definition
+ * which defines the <i>service</i> implemented by the <i>service provider</i>.
+ * This metadata annotation is used as nested annotation inside other
+ * enclosing annotations. For example,
* <blockquote><pre>
* //
* // com/xyz/xmlparser/module-info.java
@@ -59,6 +57,7 @@ import java.lang.annotation.RetentionPol
* </pre></blockquote>
* @see java.module.annotation.ServiceProviders
* @see java.module.annotation.Services
+ * @see java.util.ServiceLoader
* @since 1.7
*/
@Target({})
@@ -66,12 +65,13 @@ public @interface ServiceProvider {
public @interface ServiceProvider {
/**
- * The name of the service that the service-provider implements.
+ * The name of the <i>service</i> implemented by the
+ * <i>service provider</i>.
*/
String service();
/**
- * The name of the service-provider class.
+ * The name of the <i>service provider</i> class.
*/
String providerClass();
}
--- a/src/share/classes/java/module/annotation/ServiceProviders.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/ServiceProviders.java Thu Jul 24 17:30:52 2008 -0700
@@ -31,15 +31,12 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.RetentionPolicy;
/**
- * Indicates an array of service-providers that a module definition defines.
- * A service is a well-known set of interfaces and (usually abstract) classes.
- * A service-provider is a specific implementation of a service. The classes
- * in a service-provider typically implement the interfaces and subclass the
- * classes defined in the service itself. If a module definition defines a
- * service-provider, it should import the module definition which defines the
- * service. It should also contain and export the set of interfaces and classes
- * that are part of the service-provider. This metadata annotation is applied
- * to a Java module. For example,
+ * Indicates an array of
+ * <a href="../../../java/util/ServiceLoader.html"><i>service providers</i></a>
+ * which are defined in a module definition. The module definition must export the
+ * <i>service providers</i>' types; it must import the module definitions which
+ * define the <i>services</i> implemented by the <i>service providers</i>.
+ * This metadata annotation is applied to a Java module. For example,
* <p>
* <blockquote><pre>
* //
@@ -60,6 +57,7 @@ import java.lang.annotation.RetentionPol
* </pre></blockquote>
* @see java.module.annotation.ServiceProvider
* @see java.module.annotation.Services
+ * @see java.util.ServiceLoader
* @since 1.7
*/
@Target({ElementType.MODULE})
@@ -67,7 +65,7 @@ public @interface ServiceProviders {
public @interface ServiceProviders {
/**
- * An array of service-providers.
+ * An array of <i>service providers</i>.
*/
ServiceProvider[] value();
}
--- a/src/share/classes/java/module/annotation/Services.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/Services.java Thu Jul 24 17:30:52 2008 -0700
@@ -31,14 +31,11 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.RetentionPolicy;
/**
- * Indicates an array of services that a module definition defines.
- * A service is a well-known set of interfaces and (usually abstract) classes.
- * A service-provider is a specific implementation of a service. The classes
- * in a service-provider typically implement the interfaces and subclass the
- * classes defined in the service itself. If a module definition defines a
- * service, it should contain and export the set of interfaces and classes
- * that are part of the service. This metadata annotation is applied to a
- * Java module. For example,
+ * Indicates an array of
+ * <a href="../../../java/util/ServiceLoader.html"><i>services</i></a>
+ * which are defined in a module definition.
+ * The module definition must export the <i>services</i>' types.
+ * This metadata annotation is applied to a Java module. For example,
* <blockquote><pre>
* //
* // javax/xml/parsers/module-info.java
@@ -52,6 +49,7 @@ import java.lang.annotation.RetentionPol
* </pre></blockquote>
* @see java.module.annotation.ServiceProvider
* @see java.module.annotation.ServiceProviders
+ * @see java.util.ServiceLoader
* @since 1.7
*/
@Target({ElementType.MODULE})
@@ -59,7 +57,7 @@ public @interface Services {
public @interface Services {
/**
- * An array of the names of the services.
+ * An array of the names of the <i>services</i>.
*/
String[] value();
}
--- a/src/share/classes/java/module/annotation/Version.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/Version.java Thu Jul 24 17:30:52 2008 -0700
@@ -31,9 +31,8 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.RetentionPolicy;
/**
- * Indicates the version of a module definition. The version format must
- * follow the one described in the {@link java.module.Version} class. This
- * metadata annotation can be applied to a Java module. For examples,
+ * Indicates the version of a module definition. This metadata annotation
+ * is applied to a Java module. For examples,
* <blockquote><pre>
* //
* // com/wombat/xyz/module-info.java
@@ -62,7 +61,8 @@ public @interface Version {
public @interface Version {
/**
- * The version.
+ * The version. The value must follow the
+ * {@linkplain java.module.Version version format}.
*/
String value();
}
--- a/src/share/classes/java/module/annotation/package-info.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/annotation/package-info.java Thu Jul 24 17:30:52 2008 -0700
@@ -24,7 +24,7 @@
*/
/**
- * Provides metadata annotations for modules in the JAM (JAva Module) module system.
+ * Provides metadata annotations for the modules in the JAM (JAva Module) module system.
*
* @since 1.7
*/
--- a/src/share/classes/java/module/package-info.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/module/package-info.java Thu Jul 24 17:30:52 2008 -0700
@@ -24,9 +24,252 @@
*/
/**
- * Provides classes and interfaces for the Java Module System and the JAM (JAva
- * Module) module system.
- *
+ * Provides classes and interfaces for the Java Module System framework and
+ * the JAM (JAva Module) module system.
+ *
+ * <h2>Java Module System</h2>
+ *
+ * The Java Module System defines a framework for <i>deployment modules</i>
+ * that enables one or more concrete <i>module systems</i> to run and
+ * interoperate in a running Java virtual machine (JVM). A
+ * {@linkplain java.module.ModuleSystem <i>module system</i>}
+ * is responsible for creating, managing, and releasing
+ * instances of its <i>deployment modules</i>.
+ * <p>
+ * In the context of the <i>deployment module</i>, there is a further
+ * distinction between
+ * {@linkplain java.module.ModuleDefinition <i>module definitions</i>} and
+ * {@linkplain java.module.Module <i>module instances</i>}.
+ * <p>
+ * A <i>module definition</i> identifies a logical module in a
+ * <i>module system</i>, and specifies which classes and resources are
+ * provided by the module, and what the module
+ * {@linkplain java.module.ModuleDefinition#getImportDependencies() imports}
+ * and {@linkplain java.module.ModuleDefinition#isClassExported exports}.
+ * The classes in the <i>module definition</i> are from one or more Java
+ * packages. The Java Module System allows <i>module definitions</i> from
+ * one or more <i>module systems</i> to coexist in the same Java virtual
+ * machine (JVM) instance. A <i>module definition</i> is stateless
+ * by definition, and the identity of a <i>module definition</i> is
+ * represented by its name and version.
+ * <p>
+ * A <i>module system</i> may
+ * {@linkplain java.module.ModuleSystem#getModule instantiate}
+ * a <i>module definition</i> creating
+ * a <i>module instance</i> at runtime. Each <i>module instance</i> has
+ * its own copies of the classes defined by its
+ * {@linkplain java.module.Module#getClassLoader module class loader}.
+ * Each <i>module instance</i> is also
+ * interconnected with instances of the modules it imports. Hence, each
+ * <i>module instance</i> creates a distinct namespace at runtime. A useful
+ * intuition is that <i>module definitions</i> are analogous to classes, and
+ * <i>module instances</i> to objects.
+ * <p>
+ * A <i>module archive</i> identifies a physical module in a
+ * <i>module system</i> for distribution. It contains metadata, classes, and
+ * resources that are part of the module. The metadata carries the information
+ * about the module itself, including the name, the version, the imports that
+ * define its dependencies upon other modules, the exports that define what
+ * classes and resources are visible to other modules, etc. The distribution
+ * format of the <i>module archive</i> and the file format of the metadata
+ * are module system specific.
+ * <p>
+ * The relationship between physical module (i.e. <i>module archive</i>) and
+ * logical module (i.e. <i>module definition</i>) varies in each module system.
+ * In some <i>module systems</i>, one <i>module archive</i> may yield one
+ * <i>module definition</i> at runtime, while some other <i>module systems</i>
+ * may combine multiple <i>module archives</i> to yield a single
+ * <i>module definition</i>.
+ * <p>
+ * A {@linkplain java.module.Repository <i>repository</i>} is responsible for
+ * storing, discovering, and retrieving <i>module definitions</i>. All
+ * <i>module definitions</i> in a <i>repository</i> are associated with one
+ * or more <i>module systems</i>, and a <i>module system</i> can be tied to
+ * <i>module definitions</i> in one or more <i>repositories</i>. A
+ * <i>repository</i> can have multiple versions of <i>module definitions</i>,
+ * and it is the basis in enabling side-by-side deployment.
+ * <p>
+ * The <i>module definitions</i>, <i>module instances</i>,
+ * <i>module systems</i>, and <i>repositories</i>
+ * are reified via a reflective API:
+ * {@link java.module.ModuleDefinition ModuleDefinition},
+ * {@link java.module.Module Module},
+ * {@link java.module.ModuleSystem ModuleSystem}, and
+ * {@link java.module.Repository}.
+ * This allows modules to be manipulated using the full power of a
+ * general purpose programming language. This API constitutes a lingua
+ * franca for tools and JVMs to manage modules.
+ *
+ * <blockquote>
+ * <table cellspacing=1 summary="Description of the Java Module System">
+ * <tr>
+ * <th><p align="left">Java Module System API</p></th>
+ * <th><p align="left">Description</p></th>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.ImportDependency}</tt> </td>
+ * <td> Generic import dependency on a module definition in the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.Module}</tt> </td>
+ * <td> Module instance in a module system within the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.ModuleArchiveInfo}</tt> </td>
+ * <td> Information of an installed module archive in a repository in the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.ModuleContent}</tt> </td>
+ * <td> Content of a module definition in the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.ModuleDefinition}</tt> </td>
+ * <td> Module definition in a module system within the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.ModuleSystem}</tt> </td>
+ * <td> Module system within the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.ModuleSystemEvent}</tt> </td>
+ * <td> Event that occurs in a module system within the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.ModuleSystemPermission}</tt> </td>
+ * <td> Permission which the SecurityManager will check when code that is running with a SecurityManager calls methods defined in the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.ModuleDependency}</tt> </td>
+ * <td> Import dependency on a module definition in the Java Module System based on a module's name.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.ModuleSystemListener}</tt> </td>
+ * <td> Listener interface for receiving module system events in the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.PackageDependency}</tt> </td>
+ * <td> Import dependency on a module definition in the Java Module System based on an exported package's name.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.PackageDefinition}</tt> </td>
+ * <td> Package definition in a module definition in the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.Query}</tt> </td>
+ * <td> Query that determines whether or not a particular module definition in the Java Module System matches some criteria.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.Repository}</tt> </td>
+ * <td> Repository in the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.RepositoryEvent}</tt> </td>
+ * <td> Event that occurs in a repository.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.RepositoryListener}</tt> </td>
+ * <td> Listener interface for receiving repository events in the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.Version}</tt> </td>
+ * <td> Version in the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.VersionConstraint}</tt> </td>
+ * <td> Version constraint in the Java Module System.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.VisibilityPolicy}</tt> </td>
+ * <td> Visibility policy for the module definitions in the Java Module System.</td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <h2>JAM Module System</h2>
+ *
+ * The JAM (JAva Module) module system is a concrete module system
+ * implementation and the default module system within the Java Module System.
+ * <p>
+ * <h3> JAM modules</h3>
+ * Modules in the JAM module system are called JAM modules. The distribution
+ * format of a JAM module is also called JAM. Each JAM file
+ * is self-contained by definition, and it does not reference any resource
+ * externally. See the JAM Module System Specification for more details.
+ * <p>
+ * <A NAME="PlatformSpecificModules"></A><h4> Platform-specific modules</h4>
+ * JAM modules are <i>platform-neutral</i> by default. A JAM module is
+ * <i>platform-specific</i> if it has
+ * {@link java.module.annotation.PlatformBinding platform binding}
+ * for a specific platform and architecture.
+ * <p>
+ * <h4> Resource modules</h4>
+ * Resources of different locales can be placed in different
+ * {@linkplain java.util.ResourceBundle resource modules}. A JAM module
+ * can load resources of a specific locale from the resource module
+ * through the {@link java.util.ResourceBundle ResourceBundle}, and the
+ * {@code ResourceBundle} is able to find the appropriate
+ * <i>resource module</i> from the repositories in the Java Module System.
+ *
+ * <p>
+ * <h4> Service modules and service provider modules</h4>
+ * {@linkplain java.util.ServiceLoader Services} and
+ * {@linkplain java.util.ServiceLoader service providers} can be packaged in
+ * the form of <i>service modules</i> and <i>service provider modules</i>
+ * for deployment. A JAM module can request <i>service provider</i>
+ * of a specific <i>service</i> through
+ * the {@link java.util.ServiceLoader ServiceLoader}, and the
+ * {@code ServciceLoader} is able to find service providers from the
+ * repositories in the Java Module System.
+ *
+ * <h3>Modules factory class</h3>
+ * The {@link java.module.Modules Modules} class is the factory class for the
+ * JAM module system. This class provides a set of static factory methods to
+ * obtain the {@code ModuleSystem},
+ * {@code ModuleDefinition}, and {@code Repository} for JAM modules.
+ * <p>
+ * Applications can obtain the
+ * {@code ModuleSystem} object of the JAM module system by calling the
+ * {@link java.module.Modules#getModuleSystem() <tt>getModuleSystem</tt>} method.
+ * Applications can obtain the
+ * {@code ModuleDefinition} objects of the JAM modules by calling the
+ * {@link java.module.Modules#newModuleDefinition(byte[], ModuleContent,Repository,boolean)
+ * <tt>newModuleDefinition</tt>} factory method.
+ * <p>
+ * The JAM module system provides two concrete repository implementations:
+ * <i>Local repository</i> and <i>URL repository</i>. The former can be
+ * obtained by calling one of the
+ * {@link java.module.Modules#newLocalRepository(String, File, Map, Repository)
+ * <tt>newLocalRepository</tt>} factory methods, while the latter can be
+ * obtained by calling one of the
+ * {@link java.module.Modules#newURLRepository(String, URL, Map, Repository)
+ * <tt>newURLRepository</tt>} factory methods.
+ * <p>
+ * <blockquote>
+ * <table cellspacing=1 summary="Description of the JAM Module System">
+ * <tr>
+ * <th><p align="left">JAM module system API</p></th>
+ * <th><p align="left">Description</p></th>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.ImportOverridePolicy}</tt> </td>
+ * <td> Import override policy in the JAM module system.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.ImportPolicy}</tt> </td>
+ * <td> Import policy of a module definition in the JAM module system.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.ModuleInitializer}</tt> </td>
+ * <td> Module initializer of a module instance in the JAM module system.</td>
+ * </tr>
+ * <tr>
+ * <td> <tt>{@link java.module.Modules}</tt> </td>
+ * <td> Factory methods which are specifically for the JAM module system.</td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ * <p> Except these APIs above, all the other APIs defined in the java.module package are for the framework.
+
* <p> Unless otherwise noted, passing a <tt>null</tt> argument to a
* constructor or method in any class or interface in this package will cause
* a {@link java.lang.NullPointerException NullPointerException} to be thrown.
--- a/src/share/classes/java/util/ResourceBundle.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/util/ResourceBundle.java Thu Jul 24 17:30:52 2008 -0700
@@ -256,6 +256,102 @@ import java.util.jar.JarEntry;
* (<code>ExceptionResources_fr</code>, <code>ExceptionResources_de</code>, ...),
* and one for widgets, <code>WidgetResource</code> (<code>WidgetResources_fr</code>,
* <code>WidgetResources_de</code>, ...); breaking up the resources however you like.
+ *
+ * <span style="color: rgb(204, 0, 0);">
+ * <h4>Resource modules</h4>
+ *
+ * Resource bundles can be packaged in a separate <i>resource module</i>. Each
+ * resource module contains resources of a specific locale for a module
+ * which is called its <i>target module</i>. If a {@code getBundle()} call
+ * is issued from an application module, it will look for resource bundles,
+ * if any, in the resource modules provided by the application. A resource
+ * module cannot be a target module for other resource modules.
+ *
+ * <h5>Module search strategy</h5>
+ *
+ * Modules are examined in the order specified in
+ * {@code Control.getCandidateLocales()}.
+ * The default search strategy for locating resource modules is as follows:
+ * {@code getBundle} uses the target module name, the specified locale, and
+ * the default locale (obtained from {@code Locale.getDefault}) to generate
+ * a sequence of candidate resource module names. If the specified locale's
+ * language, country, and variant are all empty strings, then the target
+ * module's name is the only candidate resource module name. Otherwise,
+ * the following sequence is generated from the attribute values of the
+ * specified locale (language1, country1, and variant1)
+ * and of the default locale (language2, country2, and variant2):
+ *
+ * <ul>
+ * <li>&lt;target-module-name&gt;.locale_&lt;language1&gt;_&lt;country1&gt;_&lt;variant1&gt;</li>
+ * <li>&lt;target-module-name&gt;.locale_&lt;language1&gt;_&lt;country1&gt;</li>
+ * <li>&lt;target-module-name&gt;.locale_&lt;language1&gt;</li>
+ * <li>&lt;target-module-name&gt;.locale_&lt;language2&gt;_&lt;country2&gt;_&lt;variant2&gt;</li>
+ * <li>&lt;target-module-name&gt;.locale_&lt;language2&gt;_&lt;country2&gt;</li>
+ * <li>&lt;target-module-name&gt;.locale_&lt;language2&gt;</li>
+ * <li>&lt;target-module-name&gt;</li>
+ * </ul>
+ *
+ * Candidate resource module names where the final component is an empty string
+ * are omitted. For example, if country1 is an empty string, the second candidate
+ * resource module name is omitted. getBundle then iterates over the candidate
+ * resource module names to find the first one for which it can instantiate an
+ * actual resource bundle. For each candidate resource module name, it will find
+ * the highest version of the resource module in the repository that:
+ *
+ * <ul>
+ * <li>The version of the target module is within the version constraint that
+ * is specified in the resource module, and</li>
+ * <li>The version of the resource module is within the version constraint that
+ * is specified in the target module.</li>
+ * </ul>
+ *
+ * If such a resource module is found, it will attempt to create the resource bundle
+ * from that resource module using a candidate bundle name. The candidate bundle
+ * name is generated as using the package name in the base name, the locale,
+ * and the class name in the base name:
+ * <pre>
+ * packageName + ".locale" + &lt;locale&gt; + "." + className + "_" + &lt;locale&gt;
+ * </pre>
+ *
+ * <h5>Precedence of each resource bundle</h5>
+ *
+ * If there are multiple instances of the same resource bundle exist in multiple
+ * modules (e.g. the target module and its resource modules), one in the most
+ * restrictive module is loaded. For example, {@code x.y.z.CoolResourceBundle} bundle
+ * exists in {@code org.foo.bar}, {@code org.foo.bar.locale_fr}, and
+ * {@code org.foo.bar.locale_fr_CH}, then the one in
+ * {@code org.foo.bar.locale_fr_CH} is loaded in {@code fr_CH} locale.
+ *
+ * <h5>Package resources for locales in less restrictive locale's resource module</h5>
+ *
+ * Resources for locales can be packaged in less restrictive locale's resource
+ * module, for example, the {@code x.y.z.CoolResourceBundle} bundle could
+ * reside in the {@code org.foo.bar.locale_fr} and {@code org.foo.bar.locale_de}
+ * resource module. However, the {@code x.y.z.CoolResourceBundle} bundle in the
+ * {@code org.foo.bar.locale_fr} resource module will never be loaded in
+ * {@code de} locale.
+ *
+ * <h5>Class loader for resource module</h5>
+ *
+ * Resource modules are loaded with the different class loaders from the
+ * target module. This implies that a {@code getBundle()} call can cause a
+ * {@code Control.newBundle()} call with a class loader which is not the
+ * one specified in the originating {@code getBundle()} call.
+ *
+ * <h5>Definiting class loader for resource bundle</h5>
+ *
+ * If the resource bundle from the resource module is a
+ * {@code PropertyResourceBundle}, the resource bundle property file is
+ * retrieved through the {@code getResource} method of the resource
+ * module's classloader, and it will converted into a
+ * {@code PropertyResourceBundle} class and defined in the
+ * class loader of the target module.
+ * <p>
+ * If the resource bundle from the resource module is a
+ * {@code ListResourceBundle}, the resource bundle is loaded and defined
+ * through the {@code loadClass} method of the resource module's
+ * class loader.
+ * </span>
*
* @see ListResourceBundle
* @see PropertyResourceBundle
--- a/src/share/classes/java/util/ServiceLoader.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/java/util/ServiceLoader.java Thu Jul 24 17:30:52 2008 -0700
@@ -55,9 +55,12 @@ import sun.module.repository.RepositoryC
* and subclass the classes defined in the service itself. Service providers
* can be installed in an implementation of the Java platform in the form of
* extensions, that is, jar files placed into any of the usual extension
- * directories. Providers can also be made available by adding them to the
- * application's class path, by installing them as service-provider modules
- * in repositories, or by some other platform-specific means.
+ * directories. <span style="color: rgb(204, 0, 0);">
+ * In addition, service providers can be installed in an
+ * implementation of the Java platform in the form of
+ * <a href="../../java/module/package-summary.html">JAM modules</a>
+ * in the repositories.</span> Providers can also be made available by adding them
+ * to the application's class path, or by some other platform-specific means.
*
* <p> For the purpose of loading, a service is represented by a single type,
* that is, a single interface or abstract class. (A concrete class can be
@@ -73,6 +76,8 @@ import sun.module.repository.RepositoryC
* provider classes must have a zero-argument constructor so that they can be
* instantiated during loading.
*
+ * <span style="color: rgb(204, 0, 0);"><h4>Service providers and JAR files</h4></span>
+ *
* <p><a name="format"> A service provider is identified by placing a
* <i>provider-configuration file</i> in the resource directory
* <tt>META-INF/services</tt>. The file's name is the fully-qualified <a
@@ -93,6 +98,41 @@ import sun.module.repository.RepositoryC
* note that this is not necessarily the class loader from which the file was
* actually loaded.
*
+ * <span style="color: rgb(204, 0, 0);"><h4>Service providers and JAM modules</h4>
+ *
+ * A <i>service module</i> is a JAM module which contains one or more
+ * service's types. A service is identified by placing a
+ * {@code ModuleServiceTable} attribute in the metadata of the service module.
+ * The attribute contains a list of fully-qualified
+ * <a href="../lang/ClassLoader.html#name">binary name</a> of the
+ * service's types. If a particular service is named
+ * in the attribute more than once, then the duplicates are ignored.
+ * <p>
+ * A <i>service provider module</i> is a JAM module which contains one or more
+ * provider classes for one or more services. A service provider module may
+ * have more than one provider classes for the same service. A service
+ * provider module may have the same provider class for more than one service.
+ * A service provider is identified by placing a
+ * {@code ModuleServiceProviderTable} attribute in the metadata
+ * of the service provider module. The attribute contains a list of
+ * fully-qualified binary name of the service's types and concrete
+ * provider classes. If a particular pair of service and concrete provider
+ * class is named in the attribute more than once, then the duplicates
+ * are ignored.
+ * <p>
+ * A service module which contains provider classes as the default
+ * implementations for its services is also a service provider module.
+ * A service provider module must import a service module for the service
+ * types either directly or transitively (through module re-exports),
+ * except if the service provider module is also a service module.
+ * <p>
+ * For more information about the {@code ModuleServiceTable}
+ * and {@code ModuleServiceProviderTable} attributes, see the
+ * {@link java.lang.ModuleInfo ModuleInfo} API.
+ * </span>
+ *
+ * <pre>
+ * </pre>
* <p> Providers are located and instantiated lazily, that is, on demand. A
* service loader maintains a cache of the providers that have been loaded so
* far. Each invocation of the {@link #iterator iterator} method returns an
@@ -100,46 +140,6 @@ import sun.module.repository.RepositoryC
* instantiation order, and then lazily locates and instantiates any remaining
* providers, adding each one to the cache in turn. The cache can be cleared
* via the {@link #reload reload} method.
- *
- * <p> Services and providers can be placed into service and service-provider
- * modules, and installed into a repository. Service and service-provider
- * modules can be versioned independently. A service module can have a number
- * of default providers in the same module, thus being both a service module
- * and a service-provider module.
- *
- * <p> Conceptually, when providers are loaded from repositories,
- * the following strategy for locating service-provider modules is used:
- *
- * <ul>
- * <li> Query the repository for all
- * service-provider modules, ignoring those which do not provide for the
- * requested {@code service}.</li>
- *
- * <li> Service-providers which have the same name as the {@code
- * service}'s module, but have a different version, are ignored.</li>
- *
- * <li> Service-providers which have the same name and same version as the
- * {@code service}'s module, but have a different module instance than the
- * {@code service}'s module, are ignored.</li>
- *
- * <li> Service-providers which import directly (or transitively via module
- * re-exports) a service module with the same name as the {@code service}'s
- * module, but of a different version, are ignored.</li>
- *
- * <li> Service-providers which import directly (or transitively via module
- * re-exports) a service module with the same name and version as the {@code
- * service}'s module, but have a different module instance than the {@code
- * service}'s module, are ignored.</li>
- *
- * <li> Of the remaining service-providers, for each service-provider module
- * name, only the service-provider module with the highest version is
- * retained.</li>
- * </ul>
- *
- * <p> The provider classes are returned from an iterator in the following
- * order: first, any default providers, in the order provided by the module to
- * which they belong. Then, non-default providers, sorted alphabetically by
- * module name.
*
* <p> Service loaders always execute in the security context of the caller.
* Trusted system code should typically invoke the methods in this class, and
@@ -962,10 +962,29 @@ public final class ServiceLoader<S>
}
/**
+ * <span style="color: rgb(204, 0, 0);"><B>[UPDATED]</B></span>
* Creates a new service loader for the given service type and class
- * loader. If both the service and loader are in modules, the loader's
- * module's repository will be used to lookup provider-configuration files
- * and provider classes.
+ * loader.
+ * <p>
+ * <span style="color: rgb(204, 0, 0);">
+ * The service loader first uses the class loader to search for providers
+ * for the given service type; the service loader then uses the following
+ * repository in the Java Module System to search for service provider
+ * modules for the given service type if the service type is from a
+ * module module:
+ * <p>
+ * <ul>
+ * <li> {@linkplain java.module.Repository#getApplicationRepository Application repository}
+ * if the class loader or an ancestor of the class loader is the system class loader.</li>
+ *
+ * <li> {@linkplain java.module.Repository#getSystemRepository System repository}
+ * if the class loader or an ancestor of the class loader is the extension class loader.</li>
+ *
+ * <li> The repository associated with the module which the class loader
+ * belongs if the class loader is a
+ * {@linkplain java.module.Module#getClassLoader module class loader}.</li>
+ * </ul>
+ * </span>
*
* @param service
* The interface or abstract class representing the service
@@ -991,9 +1010,9 @@ public final class ServiceLoader<S>
service, Repository.getBootstrapRepository(), m);
} else if (loader == ClassLoader.getSystemClassLoader()) {
- // Use system repository and system class loader
+ // Use application repository and system class loader
return new ServiceLoader<S>(
- service, Repository.getSystemRepository(), loader, m);
+ service, Repository.getApplicationRepository(), loader, m);
} else if (loader.getModule() != null) {
// Use loader's respository
@@ -1033,8 +1052,16 @@ public final class ServiceLoader<S>
}
/**
+ * <span style="color: rgb(204, 0, 0);"><B>[NEW]</B></span>
* Creates a new service loader for the given service type, using the
- * given {@link java.module.Repository} to locate providers.
+ * given {@link java.module.Repository}.
+ * <p>
+ * This method uses the repository to search for service provider modules
+ * for the given service type; the service provider module must
+ * import (either directly or transitively through module reexports)
+ * the same instance of the service module which the given service
+ * type belongs, unless the provider is a default provider
+ * in the same service module instance.
*
* @param repository
* The repository from which service provider modules will be
@@ -1074,13 +1101,13 @@ public final class ServiceLoader<S>
}
/**
+ * <span style="color: rgb(204, 0, 0);"><B>[UPDATED]</B></span>
* Creates a new service loader for the given service type, using the
- * extension class loader or system repository.
- *
- * <ul>
- * <li>If the service type is in a module, use the system repository.</li>
- * <li>Otherwise, use the extension class loader.</li>
- * </ul>
+ * <span style="color: rgb(204, 0, 0);">
+ * the extension class loader, and using the
+ * {@linkplain java.module.Repository#getSystemRepository system repository}
+ * if the service type is from a service module.
+ * </span>
*
* <p> This convenience method simply locates the extension class loader,
* call it <tt><i>extClassLoader</i></tt>, and then returns
@@ -1095,7 +1122,10 @@ public final class ServiceLoader<S>
* <p> This method is intended for use when only installed providers are
* desired. The resulting service will only find and load providers that
* have been installed into the current Java virtual machine; providers on
- * the application's class path will be ignored.
+ * the application's class path
+ * <span style="color: rgb(204, 0, 0);">
+ * and providers in the application repository will be ignored.
+ * </span>
*
* @param service
* The interface or abstract class representing the service
@@ -1106,7 +1136,7 @@ public final class ServiceLoader<S>
ClassLoader cl = service.getClassLoader();
if (cl != null && cl.getModule() != null) {
return ServiceLoader.load(
- RepositoryConfig.getLastRepository(), service);
+ Repository.getSystemRepository(), service);
} else {
// If the class is in the bootstrap module, it might represent a
// service defined in that module.
--- a/src/share/classes/sun/module/ModuleLauncher.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/ModuleLauncher.java Thu Jul 24 17:30:52 2008 -0700
@@ -192,7 +192,7 @@ public final class ModuleLauncher {
+ jamFileName + " not found");
}
- // The directory which houses the jam becomes the system repository.
+ // The directory which houses the jam becomes the application repository.
File baseDir = new File(jamFileName).getAbsoluteFile().getParentFile();
repository = Modules.newLocalRepository(
"application",
@@ -213,7 +213,7 @@ public final class ModuleLauncher {
if (definition == null) {
throw new Exception("could not find module for " + jamFileName);
}
- RepositoryConfig.setSystemRepository(repository);
+ RepositoryConfig.setApplicationRepository(repository);
return definition;
}
@@ -235,7 +235,7 @@ public final class ModuleLauncher {
// Repository processing
if (repositoryName == null) {
- // Assume the current directory as the system repository.
+ // Assume the current directory as the application repository.
repository = Modules.newLocalRepository(
"application",
new File(".").getAbsoluteFile(), null,
@@ -267,7 +267,7 @@ public final class ModuleLauncher {
RepositoryConfig.getSystemRepository());
}
}
- RepositoryConfig.setSystemRepository(repository);
+ RepositoryConfig.setApplicationRepository(repository);
ModuleDefinition definition = getModuleDefinition(repository, moduleName);
if (definition == null) {
throw new IllegalArgumentException("Module not found: " + moduleName);
--- a/src/share/classes/sun/module/bootstrap/BootstrapModuleSystem.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/bootstrap/BootstrapModuleSystem.java Thu Jul 24 17:30:52 2008 -0700
@@ -28,6 +28,7 @@ import java.module.ImportDependency;
import java.module.ImportDependency;
import java.module.Module;
import java.module.ModuleDefinition;
+import java.module.ModuleDependency;
import java.module.ModuleInitializationException;
import java.module.ModuleSystem;
import java.module.ModuleSystemEvent;
@@ -55,11 +56,11 @@ public final class BootstrapModuleSystem
public Module getModule(ModuleDefinition moduleDef) throws ModuleInitializationException {
if (moduleDef.getModuleSystem() != this) {
throw new IllegalArgumentException
- ("Cannot instantiate new module instance from module definition in a different module system.");
+ ("Module definition is associated with another module system.");
}
if (moduleDef.getRepository() != Repository.getBootstrapRepository()) {
throw new IllegalArgumentException
- ("Cannot instantiate new module instance from module definition in a non-bootstrap repository.");
+ ("Module definition is not associated with the bootstrap repository.");
}
return getModuleInternal(moduleDef);
@@ -69,12 +70,12 @@ public final class BootstrapModuleSystem
public List<Module> getModules(ModuleDefinition importer, List<ModuleDefinition> moduleDefs) throws ModuleInitializationException {
for (ModuleDefinition moduleDef : moduleDefs) {
if (moduleDef.getModuleSystem() != this) {
- throw new IllegalArgumentException
- ("Cannot instantiate new module instance from module definition in a different module system.");
+ throw new IllegalArgumentException(
+ "Module definition is associated with another module system.");
}
if (moduleDef.getRepository() != Repository.getBootstrapRepository()) {
throw new IllegalArgumentException
- ("Cannot instantiate new module instance from module definition in a non-bootstrap repository.");
+ ("Module definition is not associated with the bootstrap repository.");
}
}
@@ -107,9 +108,10 @@ public final class BootstrapModuleSystem
// Based on the import dependency, set up the appropriate imported
// modules for a virtual module.
for (ImportDependency dep : moduleDef.getImportDependencies()) {
+ ModuleDependency moduleDep = (ModuleDependency) dep;
// Find the imported module only through the bootstrap repository.
- ModuleDefinition md = Repository.getBootstrapRepository().find(dep.getName(), dep.getVersionConstraint());
+ ModuleDefinition md = Repository.getBootstrapRepository().find(moduleDep.getName(), moduleDep.getVersionConstraint());
// Instantiate a new module instance of the imported module
Module importedModule = getModuleInternal(md);
@@ -133,17 +135,16 @@ public final class BootstrapModuleSystem
if (sm != null) {
sm.checkPermission(new ModuleSystemPermission("releaseModule"));
}
- if (moduleDef.getName().startsWith("java.")) {
- throw new UnsupportedOperationException("Cannot release module instances with name begins with \"java.\".");
+ if (moduleDef.getModuleSystem() != this) {
+ throw new IllegalArgumentException
+ ("Module definition is associated with another module system.");
}
- if (moduleDef.getRepository() == Repository.getBootstrapRepository()) {
- throw new UnsupportedOperationException("Cannot release module instances instantiated from module definitions in the bootstrap repository.");
- }
- if (moduleDef.getModuleSystem() != this) {
- throw new UnsupportedOperationException("Cannot release module instances instantiated from module definitions in a different module system.");
+ if (moduleDef.getRepository() != Repository.getBootstrapRepository()) {
+ throw new IllegalArgumentException
+ ("Module definition is not associated with the bootstrap repository.");
}
if (moduleDef.isModuleReleasable() == false) {
- throw new UnsupportedOperationException("Cannot release module instances instantiated from a module definition which is not releasable.");
+ throw new UnsupportedOperationException("Module instance is not releasable.");
}
// The MODULE_RELEASED event is never sent because virtual module
@@ -156,14 +157,16 @@ public final class BootstrapModuleSystem
if (sm != null) {
sm.checkPermission(new ModuleSystemPermission("disableModuleDefinition"));
}
- if (moduleDef.getName().startsWith("java.")) {
- throw new UnsupportedOperationException("Cannot disable module definition with name begins with \"java.\".");
+ if (moduleDef.getModuleSystem() != this) {
+ throw new IllegalArgumentException
+ ("Module definition is associated with another module system.");
}
- if (moduleDef.getRepository() == Repository.getBootstrapRepository()) {
- throw new UnsupportedOperationException("Cannot disable module definition in the bootstrap repository.");
- }
- if (moduleDef.getModuleSystem() != this) {
- throw new UnsupportedOperationException("Cannot disable module definition in a different module system..");
+ if (moduleDef.getRepository() != Repository.getBootstrapRepository()) {
+ throw new IllegalArgumentException
+ ("Module definition is not associated with the bootstrap repository.");
+ } else {
+ throw new UnsupportedOperationException
+ ("Module definition in the bootstrap repository cannot be disabled.");
}
}
--- a/src/share/classes/sun/module/bootstrap/BootstrapRepository.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/bootstrap/BootstrapRepository.java Thu Jul 24 17:30:52 2008 -0700
@@ -56,7 +56,7 @@ public final class BootstrapRepository e
}
private BootstrapRepository() {
- super("bootstrap", null, null);
+ super("bootstrap", null);
}
/**
--- a/src/share/classes/sun/module/bootstrap/VirtualModuleDefinitions.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/bootstrap/VirtualModuleDefinitions.java Thu Jul 24 17:30:52 2008 -0700
@@ -43,6 +43,7 @@ import java.module.annotation.ServicePro
import java.module.annotation.ServiceProviders;
import java.module.annotation.Services;
import java.module.annotation.Version;
+import java.net.URL;
import java.security.CodeSigner;
import java.util.ArrayList;
import java.util.Collections;
@@ -505,6 +506,11 @@ public final class VirtualModuleDefiniti
}
@Override
+ public URL getLocation() {
+ return null;
+ }
+
+ @Override
public boolean isDownloaded() {
return true;
}
--- a/src/share/classes/sun/module/config/ImportOverridePolicyFile.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/config/ImportOverridePolicyFile.java Thu Jul 24 17:30:52 2008 -0700
@@ -203,9 +203,9 @@ public final class ImportOverridePolicyF
String key;
if (dep instanceof ModuleDependency) {
- key = "module:" + dep.getName();
+ key = "module:" + ((ModuleDependency) dep).getName();
} else if (dep instanceof PackageDependency) {
- key = "package:" + dep.getName();
+ key = "package:" + ((PackageDependency) dep).getName();
} else {
// import dependency is not recognized
throw new IllegalArgumentException("The type of import dependency is not supported: " + dep);
--- a/src/share/classes/sun/module/core/ExtensionModuleLoader.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/core/ExtensionModuleLoader.java Thu Jul 24 17:30:52 2008 -0700
@@ -73,7 +73,7 @@ public final class ExtensionModuleLoader
List<ModuleDefinition> extensionModuleDefs = new ArrayList<ModuleDefinition>();
final Repository bootstrapRepository = Repository.getBootstrapRepository();
- Repository extensionRepository = RepositoryConfig.getSystemRepository(false);
+ Repository extensionRepository = RepositoryConfig.getApplicationRepository(false);
if (extensionRepository != bootstrapRepository) {
@@ -90,7 +90,7 @@ public final class ExtensionModuleLoader
} else {
// Locating the system extension repository by looking up the immediate child
// of the extension repository, starting from the system repository.
- Repository systemExtensionRepository = RepositoryConfig.getSystemRepository(false);
+ Repository systemExtensionRepository = RepositoryConfig.getApplicationRepository(false);
while (systemExtensionRepository.getParent() != extensionRepository) {
systemExtensionRepository = systemExtensionRepository.getParent();
--- a/src/share/classes/sun/module/core/ModuleImpl.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/core/ModuleImpl.java Thu Jul 24 17:30:52 2008 -0700
@@ -145,7 +145,7 @@ final class ModuleImpl extends Module {
}
if (loader == null) {
- throw new NullPointerException("Classloader has not been created yet in module " + moduleString);
+ throw new IllegalStateException("Classloader has not been created yet in module " + moduleString);
}
return loader;
@@ -154,7 +154,7 @@ final class ModuleImpl extends Module {
@Override
public List<Module> getImportedModules() {
if (importedModules == null) {
- throw new NullPointerException("Imported modules list has not been created yet in module " + moduleString);
+ throw new IllegalStateException("Imported modules list has not been created yet in module " + moduleString);
}
return Collections.unmodifiableList(importedModules);
@@ -166,7 +166,7 @@ final class ModuleImpl extends Module {
*/
Set<Module> getImportingModules() {
if (importingModules == null) {
- throw new NullPointerException("Importing modules list has not been created yet in module " + moduleString);
+ throw new IllegalStateException("Importing modules list has not been created yet in module " + moduleString);
}
return Collections.unmodifiableSet(importingModules);
}
@@ -176,7 +176,7 @@ final class ModuleImpl extends Module {
*/
void addImportingModule(Module module) {
if (importingModules == null) {
- throw new NullPointerException("Importing modules list has not been created yet in module " + moduleString);
+ throw new IllegalStateException("Importing modules list has not been created yet in module " + moduleString);
}
importingModules.add(module);
}
@@ -481,8 +481,8 @@ final class ModuleImpl extends Module {
Map<ImportDependency,VersionConstraint> versionConstraints = new HashMap<ImportDependency,VersionConstraint>();
for (ImportDependency dep : importDependencies) {
if (versionConstraints.put(dep, dep.getVersionConstraint()) != null) {
- fail(null, "Module " + moduleString + " imports module "
- + dep.getName() + " more than once.");
+ fail(null, "Module " + moduleString + " has duplicate import dependency: "
+ + dep);
}
}
versionConstraints = Collections.unmodifiableMap(versionConstraints);
@@ -502,6 +502,8 @@ final class ModuleImpl extends Module {
+ ": " + dep.toString());
}
+ ModuleDependency moduleDep = (ModuleDependency) dep;
+
// Retreives overriden version constraint for the dependency
VersionConstraint vc = result.get(dep);
@@ -510,7 +512,7 @@ final class ModuleImpl extends Module {
continue;
}
- ModuleDefinition importedMD = repository.find(dep.getName(), vc);
+ ModuleDefinition importedMD = repository.find(moduleDep.getName(), vc);
ModuleSystem importedModuleSystem = importedMD.getModuleSystem();
if (importedModuleSystem == moduleSystem) {
// Get the raw module instance from the module system.
@@ -554,13 +556,13 @@ final class ModuleImpl extends Module {
if (newConstraint == null) {
fail(null, "Import override policy error in module " + moduleString
+ ": overridden version constraint missing in the "
- + "returned map for module"
- + " dependency " + dep.getName());
+ + "returned map for import"
+ + " dependency " + dep);
}
if (constraint.contains(newConstraint) == false) {
fail(null, "Import override policy error in module " + moduleString
+ ": overridden version constraint " + newConstraint
- + " for module dependency " + dep.getName()
+ + " for import dependency " + dep
+ " is outside the boundary of the original "
+ "version constraint "+ constraint);
}
@@ -617,19 +619,21 @@ final class ModuleImpl extends Module {
}
for (ImportDependency dep : importDependencies) {
+ ModuleDependency moduleDep = (ModuleDependency) dep;
+
VersionConstraint vc = result.get(dep);
if (vc == null) {
if (dep.isOptional() == false) {
fail(null, "Import policy error in module " + moduleString
+ ": non-optional import dependency is missing in the returned map: "
- + dep.getName() + " " + dep.getVersionConstraint());
+ + moduleDep.getName() + " " + moduleDep.getVersionConstraint());
}
continue;
}
if (dep.getVersionConstraint().contains(vc) == false) {
fail(null, "Import policy error in module " + moduleString
- + ": module dependency " + dep.getName()
- + " in the returned map does not satisfy version constraint " + dep.getVersionConstraint());
+ + ": module dependency " + moduleDep.getName()
+ + " in the returned map does not satisfy version constraint " + moduleDep.getVersionConstraint());
}
}
@@ -658,8 +662,10 @@ final class ModuleImpl extends Module {
if ((dep instanceof ModuleDependency) == false) {
continue;
}
- String name = dep.getName();
- VersionConstraint constraint = constraints.get(dep);
+ ModuleDependency moduleDep = (ModuleDependency) dep;
+
+ String name = moduleDep.getName();
+ VersionConstraint constraint = constraints.get(moduleDep);
if (constraint == null) {
throw new ModuleInitializationException
("Default import policy error in module " + moduleString
@@ -668,19 +674,19 @@ final class ModuleImpl extends Module {
ModuleDefinition importedMD = rep.find(name, constraint);
if (DEBUG) System.out.println("Imported module definition: " + importedMD);
if (importedMD == null) {
- if (dep.isOptional() == false) {
+ if (moduleDep.isOptional() == false) {
throw new ModuleInitializationException
("Default import policy error in module " + moduleString
+ ": imported module " + dep.getName() + " "
- + dep.getVersionConstraint() + " is not found");
+ + moduleDep.getVersionConstraint() + " is not found");
}
if (DEBUG) {
System.out.println("Optional import is not satisfied: "
- + dep.getName() + " " + dep.getVersionConstraint());
+ + moduleDep.getName() + " " + moduleDep.getVersionConstraint());
}
continue;
}
- result.put(dep, importedMD.getVersion().toVersionConstraint());
+ result.put(moduleDep, importedMD.getVersion().toVersionConstraint());
}
return Collections.unmodifiableMap(result);
}
--- a/src/share/classes/sun/module/core/ModuleLoader.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/core/ModuleLoader.java Thu Jul 24 17:30:52 2008 -0700
@@ -95,9 +95,9 @@ final class ModuleLoader extends SecureC
StringBuilder sb = new StringBuilder();
sb.append("module:");
sb.append(moduleDef.getRepository().getName());
- if (moduleDef.getRepository().getSourceLocation() != null) {
+ if (content.getLocation() != null) {
sb.append("/");
- sb.append(moduleDef.getRepository().getSourceLocation().toString());
+ sb.append(content.getLocation().toString());
}
sb.append("!/");
sb.append(moduleDef.getName());
--- a/src/share/classes/sun/module/core/ModuleSystemImpl.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/core/ModuleSystemImpl.java Thu Jul 24 17:30:52 2008 -0700
@@ -61,9 +61,6 @@ public final class ModuleSystemImpl exte
// Modules that just moved into error state
private final List<ModuleImpl> newErrorModules;
-
- // Module definitions that have been disabled.
- private final WeakHashMap<ModuleDefinition, Boolean> disabledModuleDefs = new WeakHashMap<ModuleDefinition, Boolean>();
private ModuleSystemImpl() {
modules = new IdentityHashMap<ModuleDefinition,ModuleImpl>();
@@ -84,17 +81,11 @@ public final class ModuleSystemImpl exte
if (sm != null) {
sm.checkPermission(new ModuleSystemPermission("releaseModule"));
}
- if (moduleDef.getName().startsWith("java.")) {
- throw new UnsupportedOperationException("Cannot release module instances with name begins with \"java.\".");
- }
- if (moduleDef.getRepository() == Repository.getBootstrapRepository()) {
- throw new UnsupportedOperationException("Cannot release module instances instantiated from module definitions in the bootstrap repository.");
- }
if (moduleDef.getModuleSystem() != this) {
- throw new UnsupportedOperationException("Cannot release module instances instantiated from module definitions in a different module system.");
+ throw new IllegalArgumentException("Module definition is associated with another module system.");
}
if (moduleDef.isModuleReleasable() == false) {
- throw new UnsupportedOperationException("Cannot release module instances instantiated from a module definition which is not releasable.");
+ throw new UnsupportedOperationException("Module instance is not releasable.");
}
Module moduleToRelease = modules.get(moduleDef);
if (moduleToRelease == null) {
@@ -169,42 +160,14 @@ public final class ModuleSystemImpl exte
}
@Override
- public void disableModuleDefinition(ModuleDefinition moduleDef) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new ModuleSystemPermission("disableModuleDefinition"));
- }
- if (moduleDef.getName().startsWith("java.")) {
- throw new UnsupportedOperationException("Cannot disable module definition with name begins with \"java.\".");
- }
- if (moduleDef.getRepository() == Repository.getBootstrapRepository()) {
- throw new UnsupportedOperationException("Cannot disable module definition in the bootstrap repository.");
- }
+ public Module getModule(ModuleDefinition moduleDef) throws ModuleInitializationException {
if (moduleDef.getModuleSystem() != this) {
- throw new UnsupportedOperationException("Cannot disable module definition in a different module system..");
- }
- synchronized(disabledModuleDefs) {
- if (disabledModuleDefs.containsKey(moduleDef)) {
- throw new IllegalStateException("Cannot disable module definition which has already been disabled.");
- }
- disabledModuleDefs.put(moduleDef, Boolean.TRUE);
- }
-
- // Send MODULE_DEFINITION_DISABLED event
- ModuleSystemEvent evt = new ModuleSystemEvent(this,
- ModuleSystemEvent.Type.MODULE_DEFINITION_DISABLED,
- null, moduleDef, null);
- this.sendEvent(evt);
- }
-
- @Override
- public Module getModule(ModuleDefinition moduleDef) throws ModuleInitializationException {
+ throw new IllegalArgumentException("Module definition is associated with another module system.");
+ }
// Check if the module definition has been disabled.
//
- synchronized(disabledModuleDefs) {
- if (disabledModuleDefs.containsKey(moduleDef)) {
- throw new IllegalStateException("Cannot instantiate new module instance from a disabled module definition.");
- }
+ if (isModuleDefinitionDisabled(moduleDef)) {
+ throw new IllegalStateException("Module definition has been disabled.");
}
return getModuleInternal(moduleDef);
}
@@ -212,11 +175,12 @@ public final class ModuleSystemImpl exte
@Override
public List<Module> getModules(ModuleDefinition importer, List<ModuleDefinition> moduleDefs) throws ModuleInitializationException {
for (ModuleDefinition moduleDef : moduleDefs) {
+ if (moduleDef.getModuleSystem() != this) {
+ throw new IllegalArgumentException("Module definition is associated with another module system.");
+ }
// Check if the module definition has been disabled.
- synchronized(disabledModuleDefs) {
- if (disabledModuleDefs.containsKey(moduleDef)) {
- throw new IllegalStateException("Cannot instantiate new module instance from a disabled module definition.");
- }
+ if (isModuleDefinitionDisabled(moduleDef)) {
+ throw new IllegalStateException("Module definition has been disabled.");
}
}
@@ -264,10 +228,6 @@ public final class ModuleSystemImpl exte
}
synchronized ModuleImpl getModuleInstance(ModuleDefinition moduleDef) {
- if (moduleDef.getModuleSystem() != this) {
- throw new IllegalArgumentException
- ("Cannot instantiate new module instance from module definition in a different module system.");
- }
ModuleImpl module = modules.get(moduleDef);
if (module == null) {
module = new ModuleImpl(this, moduleDef);
--- a/src/share/classes/sun/module/core/ModuleUtils.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/core/ModuleUtils.java Thu Jul 24 17:30:52 2008 -0700
@@ -28,6 +28,7 @@ import java.module.ImportDependency;
import java.module.ImportDependency;
import java.module.Module;
import java.module.ModuleDefinition;
+import java.module.ModuleDependency;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -50,7 +51,8 @@ public final class ModuleUtils {
*/
public static void expandReexports(Module m, List<Module> modules, boolean includeAll) {
for (ImportDependency dep : m.getModuleDefinition().getImportDependencies()) {
- if ((includeAll == false) && (dep.isReexported() == false)) {
+ ModuleDependency moduleDep = (ModuleDependency) dep;
+ if ((includeAll == false) && (moduleDep.isReexported() == false)) {
continue;
}
// Find the actual module that imported via 'dep'
@@ -58,7 +60,7 @@ public final class ModuleUtils {
// name, just comparing names is fine.
// Note that due to optional imports, we cannot assume
// that module[i] corresponds to import[i]
- String name = dep.getName();
+ String name = moduleDep.getName();
for (Module importedModule : m.getImportedModules()) {
if (!importedModule.getModuleDefinition().getName().equals(name)) {
continue;
--- a/src/share/classes/sun/module/osgi/OSGiRepository.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/osgi/OSGiRepository.java Thu Jul 24 17:30:52 2008 -0700
@@ -59,6 +59,8 @@ public class OSGiRepository extends Repo
private Map<String, Map<ModuleArchiveInfo, OSGiModuleDefinition>> contentMapping =
new HashMap<String, Map<ModuleArchiveInfo, OSGiModuleDefinition> >();
+ private URI source;
+
/**
* Returns the OSGi repository.
*
@@ -67,8 +69,18 @@ public class OSGiRepository extends Repo
*/
public OSGiRepository(String name, URI source, Repository parent,
Map<String, String> config) throws IOException {
- super(name, source, parent);
+ super(name, parent);
+ this.source = source;
this.config = config;
+ }
+
+ /**
+ * Returns the source location of this {@code Repository}.
+ *
+ * @return the source location.
+ */
+ public final URI getSourceLocation() {
+ return source;
}
@Override
--- a/src/share/classes/sun/module/repository/AbstractRepository.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/repository/AbstractRepository.java Thu Jul 24 17:30:52 2008 -0700
@@ -86,6 +86,8 @@ abstract class AbstractRepository extend
protected Map<String, String> config = DEFAULT_CONFIG;
+ private URI source;
+
/**
* Creates a new <code>AbstractRepository</code> instance, and initializes it
* using information from the given {@code config}.
@@ -107,9 +109,19 @@ abstract class AbstractRepository extend
protected AbstractRepository(String name, URI source,
Map<String, String> config,
Repository parent) throws IOException {
- super(name, source, parent);
+ super(name, parent);
this.config = config;
+ this.source = source;
initialize();
+ }
+
+ /**
+ * Returns the source location of this {@code Repository}.
+ *
+ * @return the source location.
+ */
+ public final URI getSourceLocation() {
+ return source;
}
//
@@ -261,7 +273,7 @@ abstract class AbstractRepository extend
protected final ModuleArchiveInfo addModuleArchiveInternal(File file)
throws IOException {
// Put the jam file into the repository cache and cook it
- ModuleDefInfo mdInfo = repositoryCache.getModuleDefInfo(file);
+ ModuleDefInfo mdInfo = repositoryCache.getModuleDefInfo(getSourceLocation().toURL(), file);
// Constructs a module archive info
ModuleArchiveInfo mai = new JamModuleArchiveInfo(
@@ -463,6 +475,7 @@ abstract class AbstractRepository extend
if (contentMapping.get(key) == null) {
// Put the jam file into the repository cache and cook it
ModuleDefInfo mdInfo = repositoryCache.getModuleDefInfo(
+ getSourceLocation().toURL(),
new File(mai.getFileName()));
// Constructs a module definition
--- a/src/share/classes/sun/module/repository/LocalRepository.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/repository/LocalRepository.java Thu Jul 24 17:30:52 2008 -0700
@@ -226,7 +226,7 @@ public final class LocalRepository exten
// XXX Log this action
// Put the jam file into the repository cache and cook it
- ModuleDefInfo mdInfo = repositoryCache.getModuleDefInfo(file);
+ ModuleDefInfo mdInfo = repositoryCache.getModuleDefInfo(getSourceLocation().toURL(), file);
// Constructs a module archive info
JamModuleArchiveInfo mai = new JamModuleArchiveInfo(
@@ -284,7 +284,7 @@ public final class LocalRepository exten
// the module information, e.g. name, version, etc.
//
// No need to shadow copy (if set) because this is a temp file.
- ModuleDefInfo mdInfo = repositoryCache.getModuleDefInfo(tmpFile, false);
+ ModuleDefInfo mdInfo = repositoryCache.getModuleDefInfo(getSourceLocation().toURL(), tmpFile, false);
// Check to see if there exists a module archive that has
// the same name, version, and platform binding.
--- a/src/share/classes/sun/module/repository/RepositoryConfig.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/repository/RepositoryConfig.java Thu Jul 24 17:30:52 2008 -0700
@@ -59,7 +59,7 @@ import sun.security.util.PropertyExpande
* Repositories can be configured automatically via configuration files, or by
* setting a system property to the name of a configuration file.
* <p>
- * The initial call to {@code getSystemRepository} causes repositories to be
+ * The initial call to {@code getApplicationRepository} causes repositories to be
* configured via a configuration file, with the system repository set to the
* configured repository that is most distant (in the parent-child distance of
* repository instances).
@@ -91,14 +91,14 @@ public final class RepositoryConfig
});
}
- /** Application's system repository. */
- private static Repository systemRepository = Repository.getBootstrapRepository();
-
- /**
- * True if setSystemRepository ever completes normally: this allows for
+ /** Application's repository. */
+ private static Repository applicationRepository = Repository.getBootstrapRepository();
+
+ /**
+ * True if setApplicationRepository ever completes normally: this allows for
* it being changed at most once from its default.
*/
- private static boolean systemRepositoryWasSet = false;
+ private static boolean applicationRepositoryWasSet = false;
/** True once configRepositories has completed. */
private static boolean configDone = false;
@@ -106,8 +106,8 @@ public final class RepositoryConfig
/** True once the repositories are all initialized. */
private static boolean initialized = false;
- /** Last repository in the configuration. */
- private static Repository lastRepository;
+ /** System repository in the configuration. */
+ private static Repository systemRepository;
/** Attribute which designates the parent of a repository. */
private static final String parentAttr = "parent";
@@ -140,39 +140,40 @@ public final class RepositoryConfig
new HashMap<String, RepositoryFactory>();
/**
- * Sets the system repository.
- * @param r {@code Repository} that will be the system repository
+ * Sets the application repository.
+ * @param r {@code Repository} that will be the application repository
* SecurityException if a security manager exists and its
* <tt>checkPermission</tt> method denies access to shutdown the
* repository.
- * @throws IllegalArgumentException if the system repository has already
+ * @throws IllegalArgumentException if the application repository has already
* been set via this method.
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method denies access to set the system
* repository.
*/
- public static void setSystemRepository(Repository r) throws IllegalArgumentException {
+ public static void setApplicationRepository(Repository r) throws IllegalArgumentException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkPermission(new ModuleSystemPermission("setSystemRepository"));
- }
- if (systemRepositoryWasSet) {
- throw new IllegalArgumentException("System repository is already set.");
+ sm.checkPermission(new ModuleSystemPermission("setApplicationRepository"));
+ }
+ if (applicationRepositoryWasSet) {
+ throw new IllegalArgumentException("Application repository is already set.");
} else {
- systemRepository = r;
- systemRepositoryWasSet = true;
- }
- }
-
- /**
- * Returns the current system repository, or if one has not been set (for
+ applicationRepository = r;
+ applicationRepositoryWasSet = true;
+ }
+ }
+
+ /**
+ * Returns the current application repository, or if one has not been set (for
* example, by the ModuleLauncher), creates it first.
+ *
* @param initializeAll initialize all repositories
- * @return the system repository
- */
- public static synchronized Repository getSystemRepository(boolean initializeAll) {
+ * @return the application repository
+ */
+ public static synchronized Repository getApplicationRepository(boolean initializeAll) {
if (!configDone) {
- systemRepository = configRepositories();
+ applicationRepository = configRepositories();
}
// XXX: Will revisit the bootstrapping issue
//
@@ -185,7 +186,7 @@ public final class RepositoryConfig
//
if (initializeAll && !initialized) {
initialized = true;
- for (Repository r = systemRepository; r != null; r = r.getParent()) {
+ for (Repository r = applicationRepository; r != null; r = r.getParent()) {
try {
if (!r.isActive()) {
r.initialize();
@@ -195,11 +196,11 @@ public final class RepositoryConfig
}
}
}
- return systemRepository;
- }
-
- public static synchronized Repository getSystemRepository() {
- return getSystemRepository(true);
+ return applicationRepository;
+ }
+
+ public static synchronized Repository getApplicationRepository() {
+ return getApplicationRepository(true);
}
/**
@@ -209,9 +210,9 @@ public final class RepositoryConfig
* @return the repository configured to be farthest from the bootstrap
* repository.
*/
- public static synchronized Repository getLastRepository() {
- getSystemRepository(); // Force initialization
- return lastRepository;
+ public static synchronized Repository getSystemRepository() {
+ getApplicationRepository(); // Force initialization
+ return systemRepository;
}
/**
@@ -307,10 +308,10 @@ public final class RepositoryConfig
if (!configProps.isEmpty()) {
LinkedHashMap<String, Map<String, String>> orderedConfig =
getConfigFromProps(configProps);
- lastRepository = createRepositories(orderedConfig);
+ systemRepository = createRepositories(orderedConfig);
configDone = true;
}
- return lastRepository;
+ return systemRepository;
}
/**
--- a/src/share/classes/sun/module/repository/URLRepository.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/repository/URLRepository.java Thu Jul 24 17:30:52 2008 -0700
@@ -364,7 +364,7 @@ public final class URLRepository extends
// the module information, e.g. name, version, etc.
//
// No need to shadow copy (if set) because this is a temp file.
- ModuleDefInfo mdInfo = repositoryCache.getModuleDefInfo(tmpFile, false);
+ ModuleDefInfo mdInfo = repositoryCache.getModuleDefInfo(getSourceLocation().toURL(), tmpFile, false);
// Check to see if there exists a module archive that has
// the same name, version, and platform binding.
--- a/src/share/classes/sun/module/repository/cache/Cache.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/repository/cache/Cache.java Thu Jul 24 17:30:52 2008 -0700
@@ -82,21 +82,23 @@ import sun.module.repository.RepositoryU
/**
* Returns a module definition info that is created based on the specified jam file.
*
+ * @param source source location
* @param file jam file.
* @throws IOException if there is an I/O error occurred.
*/
- public ModuleDefInfo getModuleDefInfo(File file) throws IOException {
- return getModuleDefInfo(file, RepositoryUtils.shouldShadowCopyFiles());
+ public ModuleDefInfo getModuleDefInfo(URL source, File file) throws IOException {
+ return getModuleDefInfo(source, file, RepositoryUtils.shouldShadowCopyFiles());
}
- /**
- * Returns a module definition info that is created based on the specified jam file.
- *
- * @param file jam file.
- * @param shadowCopyFiles true if the specified jam file should be shadow copied.
- * @throws IOException if there is an I/O error occurred.
- */
- public ModuleDefInfo getModuleDefInfo(File file, boolean shadowCopyFiles) throws IOException {
+ /**
+ * Returns a module definition info that is created based on the specified jam file.
+ *
+ * @param source source location
+ * @param file jam file.
+ * @param shadowCopyFiles true if the specified jam file should be shadow copied.
+ * @throws IOException if there is an I/O error occurred.
+ */
+ public ModuleDefInfo getModuleDefInfo(URL source, File file, boolean shadowCopyFiles) throws IOException {
//
// Creates a module-specific directory under the root directory.
//
@@ -155,7 +157,7 @@ import sun.module.repository.RepositoryU
// Determines if the MODULE.METADATA file is well-formed
ModuleInfo moduleInfo = ModuleInfo.getModuleInfo(metadataBytes);
- return new LocalModuleDefInfo(entryDirectory, metadataBytes, moduleInfo, jamFile, codeSigners);
+ return new LocalModuleDefInfo(entryDirectory, metadataBytes, moduleInfo, jamFile, source, codeSigners);
} catch (ClassFormatError cfe) {
throw new IOException("MODULE.METADATA is malformed in " + file.getName(), cfe);
} finally {
--- a/src/share/classes/sun/module/repository/cache/LocalModuleContent.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/repository/cache/LocalModuleContent.java Thu Jul 24 17:30:52 2008 -0700
@@ -27,6 +27,7 @@ package sun.module.repository.cache;
import java.io.File;
import java.module.ModuleContent;
+import java.net.URL;
import java.util.Set;
import java.security.CodeSigner;
@@ -66,6 +67,11 @@ final class LocalModuleContent extends C
}
@Override
+ public URL getLocation() {
+ return mdInfo.getCodeBase();
+ }
+
+ @Override
public boolean isDownloaded() {
return true;
}
--- a/src/share/classes/sun/module/repository/cache/LocalModuleDefInfo.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/repository/cache/LocalModuleDefInfo.java Thu Jul 24 17:30:52 2008 -0700
@@ -28,6 +28,7 @@ import java.io.File;
import java.io.File;
import java.io.IOException;
import java.module.ModuleContent;
+import java.net.URL;
import java.security.CodeSigner;
import java.util.Set;
import java.util.jar.JarFile;
@@ -42,6 +43,9 @@ final class LocalModuleDefInfo extends M
// Jam file
private final File jamFile;
+ // Origin of the JAM file
+ private final URL origin;
+
// Code signers of the JAM file
private final Set<CodeSigner> codeSigners;
@@ -55,13 +59,15 @@ final class LocalModuleDefInfo extends M
* @param metadataBytes byte array that represents the module metadata
* @param moduleInfo ModuleInfo reified from the module metadata
* @param jamFile jam file
+ * @param origin origin of the module definition
* @param codeSigners an unmodifiable set of code signers who signed the JAM file
*/
LocalModuleDefInfo(File entryDirectory, byte[] metadataBytes,
ModuleInfo moduleInfo, File jamFile,
- Set<CodeSigner> codeSigners) {
+ URL origin, Set<CodeSigner> codeSigners) {
super(entryDirectory, metadataBytes, moduleInfo);
this.jamFile = jamFile;
+ this.origin = origin;
this.codeSigners = codeSigners;
}
@@ -91,4 +97,12 @@ final class LocalModuleDefInfo extends M
Set<CodeSigner> getJamCodeSigners() {
return codeSigners;
}
-}
+
+ /**
+ * Returns the source location.
+ */
+ /* package-private */
+ URL getCodeBase() {
+ return origin;
+ }
+ }
--- a/src/share/classes/sun/module/repository/cache/URLModuleContent.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/repository/cache/URLModuleContent.java Thu Jul 24 17:30:52 2008 -0700
@@ -174,6 +174,11 @@ final class URLModuleContent extends Cac
}
@Override
+ public URL getLocation() {
+ return mdInfo.getCodeBase();
+ }
+
+ @Override
protected Set<CodeSigner> getJamCodeSigners() {
return codeSigners;
}
--- a/src/share/classes/sun/module/tools/JRepo.java Thu Jul 24 08:41:30 2008 -0700
+++ b/src/share/classes/sun/module/tools/JRepo.java Thu Jul 24 17:30:52 2008 -0700
@@ -108,7 +108,7 @@ public class JRepo {
/** Indicates that command output should be verbose. */
private static final Flag verboseFlag = new Flag('v');
- /** Location of repository; if not given uses system repository. */
+ /** Location of repository; if not given uses application repository. */
private static final RepositoryFlag repositoryFlag = new RepositoryFlag();
/** Indicates dependencies command should display info on core modules. */
@@ -188,7 +188,7 @@ public class JRepo {
/**
* Gets the repository based on command line flags.
* @return Reposistory based on the value from {@code repositoryFlag} if
- * that is non-null, else the system repository.
+ * that is non-null, else the application repository.
*/
private Repository getRepository() throws IOException {
Repository rc = null;
@@ -196,20 +196,20 @@ public class JRepo {
String repositoryLocation = repositoryFlag.getLocation();
if (repositoryLocation == null) {
- rc = Repository.getSystemRepository();
+ rc = Repository.getApplicationRepository();
} else {
// If repositoryLocation is a URL use URLRepository else LocalRepository.
try {
URL u = new URL(repositoryLocation);
rc = Modules.newURLRepository(
- "jrepo", u, null, RepositoryConfig.getSystemRepository());
+ "jrepo", u, null, RepositoryConfig.getApplicationRepository());
} catch (MalformedURLException ex) {
File f = new File(repositoryLocation);
if (f.exists() && f.canRead()) {
rc = Modules.newLocalRepository(
"jrepo",
f.getCanonicalFile(), null,
- RepositoryConfig.getSystemRepository());
+ RepositoryConfig.getApplicationRepository());
} else {
throw new IOException("Cannot access repository at " // XXX i18n
+ repositoryLocation);
@@ -287,7 +287,7 @@ public class JRepo {
/** Returns a user-grokkable description of the repository. */
private static String getRepositoryText(Repository repo) {
String rc;
- URI u = repo.getSourceLocation();
+/* URI u = repo.getSourceLocation();
if (u == null) {
rc = "Bootstrap repository";
} else {
@@ -297,6 +297,9 @@ public class JRepo {
rc = "Repository unknown";
}
}
+ */
+ rc = "[" + repo.toString() + "]";
+
return rc;
}
@@ -330,9 +333,10 @@ public class JRepo {
pw.printf(MDFormat, md.getName(), md.getVersion());
if (verboseFlag.isEnabled()) {
pw.printf(MDFormatVerbose,
- md.getRepository() == Repository.getBootstrapRepository()
- ? "bootstrap"
- : md.getRepository().getSourceLocation().toString());
+// md.getRepository() == Repository.getBootstrapRepository()
+// ? "bootstrap"
+// : md.getRepository().getSourceLocation().toString());
+ md.getRepository().getName());
}
return sw.toString();
}
@@ -538,7 +542,7 @@ public class JRepo {
* {@code doit} in each one. The abstract base class provides the recursion;
* each concrete subclass provides the per-repository behavior. The
* recursion is such that the bootstrap repository is visited first,
- * and the system repository is last.
+ * and the application repository is last.
*/
abstract class RepositoryVisitor {
abstract void doit(Repository repo, Messenger msg);
@@ -897,7 +901,7 @@ public class JRepo {
rc = true;
for (ModuleArchiveInfo mai : found) {
if (!uninstall(repo, mai, msg)) {
- if (DEBUG) debug("uninstall failed for " + getMAIText(mai) + " in " + repo.getSourceLocation());
+ if (DEBUG) debug("uninstall failed for " + getMAIText(mai) + " in " + repo.toString());
rc = false;
break;
}
--- a/test/java/module/modinit/RunMTest.java Thu Jul 24 08:41:30 2008 -0700
+++ b/test/java/module/modinit/RunMTest.java Thu Jul 24 17:30:52 2008 -0700
@@ -354,7 +354,7 @@ public class RunMTest {
protected void runTest(RunMTest mTest) throws Exception {
System.out.println("> Running test " + name + "...");
- Repository parent = sun.module.repository.RepositoryConfig.getSystemRepository();
+ Repository parent = Repository.getApplicationRepository();
Repository repository = Modules.newLocalRepository(mTest.getName(), mTest.outputDirectory, null, parent);
ModuleDefinition md = repository.find(name);
try {
--- a/test/java/module/repository/LocalRepositoryTest.java Thu Jul 24 08:41:30 2008 -0700
+++ b/test/java/module/repository/LocalRepositoryTest.java Thu Jul 24 17:30:52 2008 -0700
@@ -84,16 +84,16 @@ public class LocalRepositoryTest {
}
File expandDir = makeTestDir("LocalRepoExpand");
- // Check that getSystemRepository() doesn't return null and is
+ // Check that getApplicationRepository() doesn't return null and is
// configured OK.
- Repository systemRepo = Repository.getSystemRepository();
- check(systemRepo != null);
+ Repository appRepo = Repository.getApplicationRepository();
+ check(appRepo != null);
Map<String, String> config = new HashMap<String, String>();
config.put("sun.module.repository.LocalRepository.cacheDirectory",
expandDir.getAbsolutePath());
Repository repo = Modules.newLocalRepository(
- "test", srcDir, config, systemRepo);
+ "test", srcDir, config, appRepo);
// Only REPOSITORY_INITIALIZED event should be fired.
check(ec.initializeEventExists(repo));
@@ -107,7 +107,7 @@ public class LocalRepositoryTest {
try {
config.put("sun.module.repository.LocalRepository.sourceLocationMustExist", "true");
r2 = Modules.newLocalRepository(
- "test", new File("doesNotExist"), config, systemRepo);
+ "test", new File("doesNotExist"), config, appRepo);
fail();
} catch (IOException ex) {
check(ex.getMessage().contains("does not exist or is not a directory"));
@@ -175,8 +175,9 @@ public class LocalRepositoryTest {
// Verify that we can reload from a read-only location
boolean readOnlyChangeOK = (srcDir.setWritable(false) == true);
repo.reload();