< prev index next >

src/java.base/share/classes/java/lang/module/ModuleReader.java

Print this page




  31 import java.net.URI;
  32 import java.nio.ByteBuffer;
  33 import java.util.Objects;
  34 import java.util.Optional;
  35 import java.util.stream.Stream;
  36 
  37 
  38 /**
  39  * Provides access to the content of a module.
  40  *
  41  * <p> A module reader is intended for cases where access to the resources in a
  42  * module is required, regardless of whether the module has been loaded.
  43  * A framework that scans a collection of packaged modules on the file system,
  44  * for example, may use a module reader to access a specific resource in each
  45  * module. A module reader is also intended to be used by {@code ClassLoader}
  46  * implementations that load classes and resources from modules. </p>
  47  *
  48  * <p> A resource in a module is identified by an abstract name that is a
  49  * '{@code /}'-separated path string. For example, module {@code java.base} may
  50  * have a resource "{@code java/lang/Object.class}" that, by convention, is the
  51  * class file for {@code java.lang.Object}. </p>




  52  *
  53  * <p> A {@code ModuleReader} is {@linkplain ModuleReference#open open} upon
  54  * creation and is closed by invoking the {@link #close close} method.  Failure
  55  * to close a module reader may result in a resource leak.  The {@code
  56  * try-with-resources} statement provides a useful construct to ensure that
  57  * module readers are closed. </p>
  58  *
  59  * <p> A {@code ModuleReader} implementation may require permissions to access
  60  * resources in the module. Consequently the {@link #find find}, {@link #open
  61  * open}, {@link #read read}, and {@link #list list} methods may throw {@code
  62  * SecurityException} if access is denied by the security manager. </p>
  63  *
  64  * @implSpec Implementations of {@code ModuleReader} should take great care
  65  * when translating an abstract resource name to the location of a resource in
  66  * a packaged module or on the file system. Implementations are advised to
  67  * treat resource names with elements such as '{@code .},  '{@code ..}',
  68  * elements containing file separators, or empty elements as "not found". More
  69  * generally, if the resource name is not in the stream of elements that the
  70  * {@code list} method returns then the resource should be treated as "not
  71  * found" to avoid inconsistencies.
  72  *
  73  * @see ModuleReference
  74  * @since 9
  75  * @spec JPMS
  76  */
  77 
  78 public interface ModuleReader extends Closeable {
  79 
  80     /**
  81      * Finds a resource, returning a URI to the resource in the module.
  82      *



  83      * @param  name
  84      *         The name of the resource to open for reading
  85      *
  86      * @return A URI to the resource; an empty {@code Optional} if the resource
  87      *         is not found or a URI cannot be constructed to locate the
  88      *         resource
  89      *
  90      * @throws IOException
  91      *         If an I/O error occurs or the module reader is closed
  92      * @throws SecurityException
  93      *         If denied by the security manager
  94      *
  95      * @see ClassLoader#getResource(String)
  96      */
  97     Optional<URI> find(String name) throws IOException;
  98 
  99     /**
 100      * Opens a resource, returning an input stream to read the resource in
 101      * the module.
 102      *


 123         Optional<URI> ouri = find(name);
 124         if (ouri.isPresent()) {
 125             return Optional.of(ouri.get().toURL().openStream());
 126         } else {
 127             return Optional.empty();
 128         }
 129     }
 130 
 131     /**
 132      * Reads a resource, returning a byte buffer with the contents of the
 133      * resource.
 134      *
 135      * The element at the returned buffer's position is the first byte of the
 136      * resource, the element at the buffer's limit is the last byte of the
 137      * resource. Once consumed, the {@link #release(ByteBuffer) release} method
 138      * must be invoked. Failure to invoke the {@code release} method may result
 139      * in a resource leak.
 140      *
 141      * @apiNote This method is intended for high-performance class loading. It
 142      * is not capable (or intended) to read arbitrary large resources that
 143      * could potentially be 2GB or larger. The rational for using this method
 144      * in conjunction with the {@code release} method is to allow module reader
 145      * implementations manage buffers in an efficient manner.
 146      *
 147      * @implSpec The default implementation invokes the {@link #open(String)
 148      * open} method and reads all bytes from the input stream into a byte
 149      * buffer.
 150      *
 151      * @param  name
 152      *         The name of the resource to read
 153      *
 154      * @return A byte buffer containing the contents of the resource or an
 155      *         empty {@code Optional} if not found
 156      *
 157      * @throws IOException
 158      *         If an I/O error occurs or the module reader is closed
 159      * @throws SecurityException
 160      *         If denied by the security manager
 161      * @throws OutOfMemoryError
 162      *         If the resource is larger than {@code Integer.MAX_VALUE},
 163      *         the maximum capacity of a byte buffer


 178     /**
 179      * Release a byte buffer. This method should be invoked after consuming
 180      * the contents of the buffer returned by the {@code read} method.
 181      * The behavior of this method when invoked to release a buffer that has
 182      * already been released, or the behavior when invoked to release a buffer
 183      * after a {@code ModuleReader} is closed is implementation specific and
 184      * therefore not specified.
 185      *
 186      * @param  bb
 187      *         The byte buffer to release
 188      *
 189      * @implSpec The default implementation doesn't do anything except check
 190      * if the byte buffer is null.
 191      */
 192     default void release(ByteBuffer bb) {
 193         Objects.requireNonNull(bb);
 194     }
 195 
 196     /**
 197      * Lists the contents of the module, returning a stream of elements that
 198      * are the names of all resources in the module.


 199      *
 200      * <p> In lazy implementations then an {@code IOException} may be thrown
 201      * when using the stream to list the module contents. If this occurs then
 202      * the {@code IOException} will be wrapped in an {@link
 203      * java.io.UncheckedIOException} and thrown from the method that caused the
 204      * access to be attempted. {@code SecurityException} may also be thrown
 205      * when using the stream to list the module contents and access is denied
 206      * by the security manager. </p>
 207      *
 208      * <p> The behavior of the stream when used after the module reader is
 209      * closed is implementation specific and therefore not specified. </p>
 210      *
 211      * @return A stream of elements that are the names of all resources
 212      *         in the module
 213      *
 214      * @throws IOException
 215      *         If an I/O error occurs or the module reader is closed
 216      * @throws SecurityException
 217      *         If denied by the security manager
 218      */


  31 import java.net.URI;
  32 import java.nio.ByteBuffer;
  33 import java.util.Objects;
  34 import java.util.Optional;
  35 import java.util.stream.Stream;
  36 
  37 
  38 /**
  39  * Provides access to the content of a module.
  40  *
  41  * <p> A module reader is intended for cases where access to the resources in a
  42  * module is required, regardless of whether the module has been loaded.
  43  * A framework that scans a collection of packaged modules on the file system,
  44  * for example, may use a module reader to access a specific resource in each
  45  * module. A module reader is also intended to be used by {@code ClassLoader}
  46  * implementations that load classes and resources from modules. </p>
  47  *
  48  * <p> A resource in a module is identified by an abstract name that is a
  49  * '{@code /}'-separated path string. For example, module {@code java.base} may
  50  * have a resource "{@code java/lang/Object.class}" that, by convention, is the
  51  * class file for {@code java.lang.Object}. A module reader may treat
  52  * directories in the module content as resources (whether it does or not is
  53  * module reader specific). Where the module content contains a directory
  54  * that can be located as a resource then its name ends with a slash ('/'). The
  55  * directory can also be located with a name that drops the trailing slash. </p>
  56  *
  57  * <p> A {@code ModuleReader} is {@linkplain ModuleReference#open open} upon
  58  * creation and is closed by invoking the {@link #close close} method.  Failure
  59  * to close a module reader may result in a resource leak.  The {@code
  60  * try-with-resources} statement provides a useful construct to ensure that
  61  * module readers are closed. </p>
  62  *
  63  * <p> A {@code ModuleReader} implementation may require permissions to access
  64  * resources in the module. Consequently the {@link #find find}, {@link #open
  65  * open}, {@link #read read}, and {@link #list list} methods may throw {@code
  66  * SecurityException} if access is denied by the security manager. </p>
  67  *
  68  * @implSpec Implementations of {@code ModuleReader} should take great care
  69  * when translating an abstract resource name to the location of a resource in
  70  * a packaged module or on the file system. Implementations are advised to
  71  * treat resource names with elements such as '{@code .},  '{@code ..}',
  72  * elements containing file separators, or empty elements as "not found". More
  73  * generally, if the resource name is not in the stream of elements that the
  74  * {@code list} method returns then the resource should be treated as "not
  75  * found" to avoid inconsistencies.
  76  *
  77  * @see ModuleReference
  78  * @since 9
  79  * @spec JPMS
  80  */
  81 
  82 public interface ModuleReader extends Closeable {
  83 
  84     /**
  85      * Finds a resource, returning a URI to the resource in the module.
  86      *
  87      * <p> If the module reader can determine that the name locates a directory
  88      * then the resulting URI will end with a slash ('/'). </p>
  89      *
  90      * @param  name
  91      *         The name of the resource to open for reading
  92      *
  93      * @return A URI to the resource; an empty {@code Optional} if the resource
  94      *         is not found or a URI cannot be constructed to locate the
  95      *         resource
  96      *
  97      * @throws IOException
  98      *         If an I/O error occurs or the module reader is closed
  99      * @throws SecurityException
 100      *         If denied by the security manager
 101      *
 102      * @see ClassLoader#getResource(String)
 103      */
 104     Optional<URI> find(String name) throws IOException;
 105 
 106     /**
 107      * Opens a resource, returning an input stream to read the resource in
 108      * the module.
 109      *


 130         Optional<URI> ouri = find(name);
 131         if (ouri.isPresent()) {
 132             return Optional.of(ouri.get().toURL().openStream());
 133         } else {
 134             return Optional.empty();
 135         }
 136     }
 137 
 138     /**
 139      * Reads a resource, returning a byte buffer with the contents of the
 140      * resource.
 141      *
 142      * The element at the returned buffer's position is the first byte of the
 143      * resource, the element at the buffer's limit is the last byte of the
 144      * resource. Once consumed, the {@link #release(ByteBuffer) release} method
 145      * must be invoked. Failure to invoke the {@code release} method may result
 146      * in a resource leak.
 147      *
 148      * @apiNote This method is intended for high-performance class loading. It
 149      * is not capable (or intended) to read arbitrary large resources that
 150      * could potentially be 2GB or larger. The rationale for using this method
 151      * in conjunction with the {@code release} method is to allow module reader
 152      * implementations manage buffers in an efficient manner.
 153      *
 154      * @implSpec The default implementation invokes the {@link #open(String)
 155      * open} method and reads all bytes from the input stream into a byte
 156      * buffer.
 157      *
 158      * @param  name
 159      *         The name of the resource to read
 160      *
 161      * @return A byte buffer containing the contents of the resource or an
 162      *         empty {@code Optional} if not found
 163      *
 164      * @throws IOException
 165      *         If an I/O error occurs or the module reader is closed
 166      * @throws SecurityException
 167      *         If denied by the security manager
 168      * @throws OutOfMemoryError
 169      *         If the resource is larger than {@code Integer.MAX_VALUE},
 170      *         the maximum capacity of a byte buffer


 185     /**
 186      * Release a byte buffer. This method should be invoked after consuming
 187      * the contents of the buffer returned by the {@code read} method.
 188      * The behavior of this method when invoked to release a buffer that has
 189      * already been released, or the behavior when invoked to release a buffer
 190      * after a {@code ModuleReader} is closed is implementation specific and
 191      * therefore not specified.
 192      *
 193      * @param  bb
 194      *         The byte buffer to release
 195      *
 196      * @implSpec The default implementation doesn't do anything except check
 197      * if the byte buffer is null.
 198      */
 199     default void release(ByteBuffer bb) {
 200         Objects.requireNonNull(bb);
 201     }
 202 
 203     /**
 204      * Lists the contents of the module, returning a stream of elements that
 205      * are the names of all resources in the module. Whether the stream of
 206      * elements includes names corresponding to directories in the module is
 207      * module reader specific.
 208      *
 209      * <p> In lazy implementations then an {@code IOException} may be thrown
 210      * when using the stream to list the module contents. If this occurs then
 211      * the {@code IOException} will be wrapped in an {@link
 212      * java.io.UncheckedIOException} and thrown from the method that caused the
 213      * access to be attempted. {@code SecurityException} may also be thrown
 214      * when using the stream to list the module contents and access is denied
 215      * by the security manager. </p>
 216      *
 217      * <p> The behavior of the stream when used after the module reader is
 218      * closed is implementation specific and therefore not specified. </p>
 219      *
 220      * @return A stream of elements that are the names of all resources
 221      *         in the module
 222      *
 223      * @throws IOException
 224      *         If an I/O error occurs or the module reader is closed
 225      * @throws SecurityException
 226      *         If denied by the security manager
 227      */
< prev index next >