modules all the way down: osgi and the java platform module system
TRANSCRIPT
© 2015 IBM Corporation
Modules all the way downOSGi and the Java Platform Module System
Tim EllisonIBM Runtime Technology Center, Hursley, UK
tellison
@tpellison
© 2015 IBM Corporation2
Modularizing the Java Platform There have been numerous attempts to bring modularity to Java SE
JSR 277 – Java Module System (2005/2006)– Full module system with version support, repository, and SE/EE integration
JSR 291 – Dynamic Component Support for Java SE (2006/2007)– Standardize use of OSGi as a modularity system for Java
JSR 294 - Improved Modularity Support in the Java Programming Language (2006/2007)– Extending the Java language with “super-packages”
OpenJDK Jigsaw project delivery in Java 7 / Java 8 (2008 / 2014)– Attempts to bring together the modularity interests into OpenJDK– Rebooted in 2014 with the creation of modularity JEPs targeted to Java 9– Latest advanced prototype work under way in “Jake” repository
hg clone http://hg.openjdk.java.net/jigsaw/jake/
http://mail.openjdk.java.net/mailman/listinfo/jigsawdev
© 2015 IBM Corporation3
Java 9 Modularity
“Modularity” in Java 9 means many different things to many people
– The public API packages have been assigned to functional areas• The javadoc now tells you which module contains a package
– The source code has been rearranged in the repository• The JDK classes sources are now built as modules
– There are new file formats like JMOD• Containers for module artefacts (class files, resources, DLLs, etc)
– The runtime layout has been changed• There is no longer a JDK/JRE distinction
We are focusing on the actual modulesystem being defined by …
JEP200 JEP201 JEP220 JEP261
Define module structure
Reorganize source layoutinto modules
Reorganize JDK/JRE Runtime binaries to accommodate modules
An actual module system
© 2015 IBM Corporation4
Java Platform Module System – high level goals
Reliable configuration of programs– replace the class-path with a new mechanism allowing program components to
declare explicit dependences upon one another.
Strong encapsulation– enable a component to declare which of its public types are accessible to other
components, and which are not.
© 2015 IBM Corporation5
Basics of the Java Platform Module System
Modules are defined by a new type of program component– The runtime recognizes classes, interfaces, packages, and now modules
There are updates to the Java language and JVM specifications– Introducing new keywords to declare modules, and new behaviors for VM accessibility
Modules are named in a familiar convention, e.g. com.example.app– Modules names starting “java.” provide platform APIs– Module names beginning “jdk.” are supporting code
Practically, modules are created in a source file called moduleinfo.java– Placed in the module root directory (c.f. packageinfo.java)– Compiled to moduleinfo.class by javac– Not designed to be extensible by end users (e.g. no annotations)– Expected to be recognized by a wide variety of tools to provide
and read the module definition
© 2015 IBM Corporation6
Simple module declaration
/** * java.base defines and exports the core * APIs of the Java SE platform. */
module java.base { exports java.io; exports java.lang; exports java.lang.annotation; exports java.lang.invoke; exports java.lang.module; exports java.lang.ref; exports java.lang.reflect; exports java.math; exports java.net; exports java.net.spi; exports java.nio; ...
© 2015 IBM Corporation7
Simple module dependency declaration
/** * java.base defines and exports the core * APIs of the Java SE platform. */
module java.base { exports java.io; exports java.lang; exports java.lang.annotation; exports java.lang.invoke; exports java.lang.module; exports java.lang.ref; exports java.lang.reflect; exports java.math; exports java.net; exports java.net.spi; exports java.nio; ...
module com.example.app { requires java.base; exports com.example.utils; exports com.example.stuff;}
© 2015 IBM Corporation8
Comparison with OSGi module dependency mechanism
Dependencies are declared between named modules, rather than exported packages.
JSR 376
requires moduleName;
is very similar to OSGi
RequireBundle: symbolicName
Where there is a dependency on another module the dependent is readable by the dependency.
– Readability is not transitive. If a module wishes to pass through the dependency it declares
requires public moduleName;
equivalent to
RequireBundle: symbolicName;visibility:=reexport
© 2015 IBM Corporation9
Applications are defined by a module path configuration
A well-formed configuration of JSR 376 modules comprises a directed graph of module dependencies, rooted at java.base.
– All modules ultimately depend upon java.base(it is an implied requires if not made explicit)
These configurations are specified at runtime by amodule path
java mp <dir1>:<dir2>:<dir3> m com.example.app
The responsibility of assembling a coherent and consistentset of modules in the module path is delegated to externaltools
– e.g. Maven, Ivy, Gradle
In particular, JSR376 modules do not require version information– The “works-with” semantics are open to interpretation by configuration tools– A missing dependency, or different modules with the same name is an error
naming
types
jgss types
script'
types
sasl types
sasl types
base type
s
logging
types
sql types
{java.base}
{java.logging}
{java.security.sasl}
{java.security.jgss}{java.naming}
{jdk.security.sasl}
{java.sql}
My Application
{java.scripting}
~53 modules
© 2015 IBM Corporation10
Comparison with OSGi class loader hierarchy
What OSGi accomplishes with ClassLoaders, JSR 376 will accomplish with new platform capabilities.
OSGi bundles have a classloader instance that knows which loader provides an imported package.
JSR 376 preserves the current set, and delegation model of class loaders– The bootstrap and extension class loaders load types from platform modules.– The application class loader loads types from artefacts found on the module path.– Custom class loaders use existing delegation and visibility rules, with new modularity readability constraints.
bootstrap
extension
system
OSGi Environment
System bundle
Bundle A
Bundle B
imported package → classloader
imported package → classloader
imported package → classloader
bootstrap
extension
system
Load platform modules
Load module path modules
© 2015 IBM Corporation11
Comparison with OSGi module layer model
OSGi was designed to allow applications to emerge dynamically from versioned sets of modules providing behavior and services.
Modules have version information inherently part of their definition.
The service registry raises the sematic level of coupling between parts of an application– Dependencies are on capabilities rather than code.– The capabilities are dynamic in non-trivial systems.– Increasingly important in IoT networks.
The runtime is defined by the bundle framework
Build tools can provide assemblies ofmodules
The 'application' is defined by how thespecification assembles sets of modules.
© 2015 IBM Corporation12
Modular JAR files
JSR376 module information can co-exist with MANIFEST metadata
$ jar tf com.example.app1.0.jar‐METAINF/METAINF/MANIFEST.MFmoduleinfo.classcom/example/utils/MyUtil.classcom/example/stuff/MyStuff.classcom/example/internal/MyInternals.class
JAR files can be both JSR376 modules and OSGi bundles
There is some overlap in the metadata that needs synchronizing
© 2015 IBM Corporation13
Reflection and Accessibility
Reflection APIs are enhanced by JSR 376 to allow for testing and adding new module links at runtime
– You can 'export' a package to another module
MyClass.getClass().getModule().addExports(<packageName>, <targetModule>)
– Or add a 'reads' relationship to another module
MyClass.getClass().getModule().addReads(<sourceModule>)
Cannot use reflection to increase accessibility– Types are only accessible if the dependency is readable, and the dependency exports the
public type.– The Java compiler and virtual machine enforce accessibility in the same way as a private
method or field, i.e. an attempt to use an inaccessible type will cause• an error to be reported by the compiler, or• an IllegalAccessError to be thrown by the Java virtual machine, or• an IllegalAccessException to be thrown by reflective run-time APIs.
In OSGi new MyClass() visibility rules apply, but once you have a reference, reflection can ultimately be used to access all the members.
© 2015 IBM Corporation14
JSR 376 Service Model
JSR376 service model is based upon the existing static ServiceLoader architecture
– Service users declare they use a service interface
– Service providers declare they provide an interface by concrete implementation
The runtime matches the users and providers amongst observable modules
– Can be done at compile time, including checks on implementations of services
There is no API for defining services to be broadly discoverable via a runtime registry.
module java.management { requires public java.rmi; requires java.logging; requires java.naming;
exports java.lang.management; exports javax.management; exports javax.management.loading; exports javax.management.modelmbean; exports javax.management.monitor; exports javax.management.openmbean; exports javax.management.relation; exports javax.management.remote; exports javax.management.remote.rmi; exports javax.management.timer; exports sun.management to jdk.jconsole, jdk.management; exports sun.management.spi to jdk.management;
uses javax.management.remote.JMXConnectorProvider; uses javax.management.remote.JMXConnectorServerProvider; uses sun.management.spi.PlatformMBeanProvider;
provides javax.security.auth.spi.LoginModule with com.sun.jmx.remote.security.FileLoginModule;}
© 2015 IBM Corporation15
Opportunities for synchronizing metadata
System architects will continue to have a requirement for version controlled, dynamic application configurations.
The metadata required for JSR376 is likely to be a subset of that required for build tools, and more sophisticated module systems
Tools, such as BND, can be augmented to synchronize module metadata between MANIFEST.MF and module-info.class
– Option 1: Embody non-standard information in specified fields (e.g. groupId-versionId-version coordinates in name)
– Option 2: External metadata has a higher priority than module-info.class, which is emitted as a by-product of tools
module com.example.app_1.3.1 { requires com.example.base_1.5.2; exports com.example.utils; exports com.example.stuff;}
BundleName: ExampleBundleSymbolicName: com.example.appBundleDescription: An example bundleBundleManifestVersion: 2BundleVersion: 1.0.0BundleActivator: com.example.app.ActivatorExportPackage: com.example.utils;version="1.0.0"RequireBundle: com.example.base;version="1.3.0"
module com.example.app { requires com.example.base; exports com.example.utils; exports com.example.stuff;}
v.s.
© 2015 IBM Corporation16
Opportunities for optimized runtime configurations
OSGi Execution Environments must currently conform to standardized platforms.
– These may have more functionality than required by your system
JSR 376 introduces flexibility to the content of the platform runtime.
Opportunity for declaring a finer set of runtime dependencies for OSGi application runtimes
– e.g. OSGi enhancements possible to require specific platform modules rather than a full execution environment
– Jigsaw modules could be interpreted as virtual bundles by framework
© 2015 IBM Corporation17
… and finally
More Java developers will start thinking in terms of modules!– OSGi model a natural place for complex systems to migrate
As Java migrates towards a dynamic Java module repository, this can support dual duty as an OSGi bundle repository