Issue summary ------------- #MoveModuleAndLayerClasses -- Move the `Module` and `Layer` classes, and a related exception class, from the `java.lang.reflect` package up into the `java.lang` package. This will improve conceptual clarity, be consistent with the past, and leave room for the future. [1] Proposal -------- Move and rename these classes as follows: java.lang.reflect.Module -> java.lang.Module java.lang.reflect.Layer -> java.lang.ModuleLayer java.lang.reflect.LayerInstantiationException -> java.lang.ModuleLayerInstantiationException The `Layer` class is renamed to `ModuleLayer` so that it's easy for readers to skip over that class by name rather than have to read its Javadoc in order to learn that it's not what they're looking for. The related exception is renamed to match. (The `Module` class is not renamed, about which more below.) Motivation ---------- Experience shows that the best high-level shape for a non-trivial API is often not apparent until it's nearly finished. Looking at the totality of classes and interfaces in the draft specification [2] and considering the history and potential future of the platform leads to several reasons for this proposed change. - For explanatory purposes there is a very useful and pleasant high-level conceptual analogy: class : class loader :: module : module layer That is, classes are instantiated via class loaders, and modules are instantiated via layers. The types corresponding to these concepts should all be in the same package. - Existing constructs with keyword declarations in the language already have corresponding types in the `java.lang` package: `Class` for `class` and `interface`, `Package` for `package`, and `Enum` for `enum`. Placing `Module` in the same package is consistent with these past choices. - The concepts of modules and layers will be with us for a very long time, and are just as fundamental as those of classes and class loaders. The core reflection API in `java.lang.reflect` will be with us for a very long time too but it's not as fundamental, and it stands a good chance of being de-emphasized over time as alternatives are developed (e.g., Maurizio Cimadamore's mirror proposal [3]). - Long after `Class` was introduced we extended the language with the concept of class literals (e.g., `Object.class`). Peering into the future, at some point we may want to extend the language to allow modules to be mentioned outside of module declarations, and in ways that relate language-level expressions to run-time `Module` objects. It would be unfortunate if such constructs had to be specified in the JLS to refer to a `Module` type in a legacy, de-emphasized `java.lang.reflect` package. Impact ------ This is a cosmetic change. No functionality will be added or removed. This change is not, however, source-compatible relative to Java SE 8. It adds new types to the `java.lang` package, which is implicitly imported on demand (i.e., `import java.lang.*`). If code in an existing source file imports some other package on demand, and that package declares a `Module` type, and the existing code refers to that type, then the file will not compile without change. This could affect, among others, users of the popular Guice framework, which declares its own `Module` type [4]. The impact of moving these three types from `java.lang.reflect` up into `java.lang` is ameliorated by two factors: - A very common best practice is to use precise, type-specific `import` statements (e.g., `import com.google.inject.Module`) rather than import-on-demand wildcards (e.g., `import com.google.inject.*`). Code that follows this practice, which is well-supported by all the major IDEs, will compile without error [5]. - If you declare a `Module` type in your own package then other code in your package that refers to that type will not be affected by the existence of `java.lang.Module`. That's because an unqualified type name in source code resolves to a type in the same package in preference to a type in an import-on-demand package. It may sometimes be necessary to add or adjust `import` statements in order to compile existing source code for Java SE 9 but, unlike some other kinds of changes required for migration, these kinds of changes will compile on earlier releases. Source compatibility from release to release is, in general, highly desirable. Unlike binary or behavioral compatibility, however, it has never been a total commitment of the Java Platform. Over the years we have from time to time broken it in order to move forward, and this is one of those times. [1] http://openjdk.java.net/projects/jigsaw/spec/issues/#MoveModuleAndLayerClasses [2] http://cr.openjdk.java.net/~mr/jigsaw/spec/api/java.base-summary.html [3] http://cr.openjdk.java.net/~mcimadamore/reflection-manifesto.html [4] https://google.github.io/guice/api-docs/latest/javadoc/com/google/inject/Module.html [5] http://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.4.1