Modularity in the Java Programming Language: JSR …...5 The modularity landscape in JDK7 JSR 294...
Transcript of Modularity in the Java Programming Language: JSR …...5 The modularity landscape in JDK7 JSR 294...
Modularity in the JavaTM Programming Language: JSR 294 and beyondAlex BuckleySun MicrosystemsComputational Theologist
2
Disclaimer
Change is inevitable(Except from a vending machine)
3
The modularity landscape in JDK7
JSR 294Language and VM features to support module systemsThe OSGi module system is well represented on the EG
4
The modularity landscape in JDK7
JSR 294Language and VM features to support module systemsThe OSGi module system is well represented on the EG
JigsawA module system for JDK7, not part of a JSRUses language and VM features from JSR 294
5
The modularity landscape in JDK7
JSR 294Language and VM features to support module systemsThe OSGi module system is well represented on the EG
JigsawA module system for JDK7, not part of a JSRUses language and VM features from JSR 294
OpenJDK's Project JigsawHosts the Reference Implementation of JSR 294Hosts the design and implementation of Jigsaw
6
What JSR 294 is notJSR 277
7
What JSR 294 is notJSR 277Just the 'module' keyword
8
What JSR 294 is notJSR 277Just the 'module' keywordA module system
9
Modular code
Is clear about what other code it depends on
Is able to evolve without breaking clients
Is able to hide its internals from other modular code
10
Modular code
Is clear about what other code it depends on
By explicitly listing its dependencies on other code
Is able to evolve without breaking clients
Is able to hide its internals from other modular code
11
Modular code
Is clear about what other code it depends on
By explicitly listing its dependencies on other code
Is able to evolve without breaking clients
By explicitly versioning itself and its dependencies
Is able to hide its internals from other modular code
12
Modular code
Is clear about what other code it depends on
By explicitly listing its dependencies on other code
Is able to evolve without breaking clients
By explicitly versioning itself and its dependencies
Is able to hide its internals from other modular code
By explicitly making those classes 'module-private'
13
Modular code is static typing++Explicit dependenciesExplicit versioningExplicit accessibility
} Static type information
14
Modular code is predictableExplicit dependenciesExplicit versioningExplicit accessibility
Static type information allows early detection of errors that would otherwise occur at runtime
} Static type information
15
Modular code is predictableExplicit dependenciesExplicit versioningExplicit accessibility
Static type information allows early detection of errors that would otherwise occur at runtime
Modular code allows the compile-time environment to reflect the runtime environment,so runtime behavior is more predictable
} Static type information
16
Dependencies
17
Take some existing code...
planetjdk/src/ org/planetjdk/aggregator/Main.java
18
Modularize!
planetjdk/src/ org/planetjdk/aggregator/Main.java module-info.java
19
module-info.javamodule org.planetjdk.aggregator {
system jigsaw;requires module jdom;requires module tagsoup;requires module rome;requires module rome-fetcher;requires module joda-time;requires module java-xml;requires module java-base;class org.planetjdk.aggregator.Main;
}
20
module-info.javamodule org.planetjdk.aggregator {
system jigsaw;requires module jdom;requires module tagsoup;requires module rome;requires module rome-fetcher;requires module joda-time;requires module java-xml;requires module java-base;class org.planetjdk.aggregator.Main;
}
} The logical classpath for this module
21
Compiling modular codeplanetjdk/src/
org/planetjdk/aggregator/Main.javamodule-info.java
22
Compiling modular code
javac -sourcepath planetjdk/src-d planetjdk/clsorg/planetjdk/aggregator/*.javamodule-info.java
planetjdk/src/org/planetjdk/aggregator/Main.javamodule-info.java
23
Compiling modular code
javac -sourcepath planetjdk/src-d planetjdk/clsorg/planetjdk/aggregator/*.javamodule-info.java
planetjdk/src/org/planetjdk/aggregator/Main.javamodule-info.java
planetjdk/cls/org/planetjdk/aggregator/Main.classmodule-info.class
24
Questions, questions...
Q: Do you have to recompile module-info.javawhenever you add or remove a dependency?
A: Yes
25
Questions, questions...
Q: Do you have to recompile module-info.javawhenever you add or remove a dependency?
A: Yes
Q: Where did the jdom, tagsoup, rome... modulesactually come from?
A: A module system
26
Questions, questions...
Q: Do you have to recompile module-info.javawhenever you add or remove a dependency?
A: Yes
Q: Where did the jdom, tagsoup, rome... modulesactually come from?
A: A module systemA: javac's modulepath
27
modulepath?
28
Let's compile multiple modules together
ConvenientEfficient
1 compiler invocation may be more efficient than n Necessary for mutual dependencies
Module A requires module B which requires ATo start with, all you have are sources for A and BMust compile A and B at the same time
29
Compiling multiple modules togetherplanetjdk/src/
org/planetjdk/aggregator/Main.java ... org/joda/time/DateTime.java ...
30
Compiling multiple modules togetherplanetjdk/src/
org/planetjdk/aggregator/Main.java ... org/joda/time/DateTime.java ... module-info-for-which-module?.java
31
Put multiple locations on classpath?planetjdk/src/org.planetjdk.aggregator/
module-info.javaorg/...
planetjdk/src/org.planetjdk.aggregator
32
The classpath grows...
planetjdk/src/org.joda.time/ module-info.java org/...
planetjdk/src/org.planetjdk.aggregator/module-info.javaorg/...
planetjdk/src/org.planetjdk.aggregator:planetjdk/src/org.joda.time
33
And grows...
rssutils/rome/com.sun.syndication/ module-info.java com/
planetjdk/src/org.joda.time/ module-info.java org/...
planetjdk/src/org.planetjdk.aggregator/module-info.javaorg/...
planetjdk/src/org.planetjdk.aggregator:planetjdk/src/org.joda.time:
rssutils/rome/com.sun.syndication
34
classpath doesn't scale
35
classpath doesn't scaleat compile-time or runtime
36
classpath recap
rssutils/rome/com.sun.syndication/ module-info.java com/
planetjdk/src/org.joda.time/ module-info.java org/...
planetjdk/src/org.planetjdk.aggregator/module-info.javaorg/...
planetjdk/src/org.planetjdk.aggregator:planetjdk/src/org.joda.time:
rssutils/rome/com.sun.syndication
37
s/classpath/modulepath/g;
planetjdk/src:rssutils/rome
rssutils/rome/com.sun.syndication/ module-info.java com/
planetjdk/src/org.joda.time/ module-info.java org/...
planetjdk/src/org.planetjdk.aggregator/module-info.javaorg/...
38
Compiling modular codejavac -modulepath planetjdk/src:rssutils/rome
org.planetjdk.aggregator/module-info.javaorg.planetjdk.aggregator/org/...com.sun.syndication/module-info.javacom.sun.syndication/com/...
When compiling org.planetjdk.aggregator/* classes,
javac looks for org.planetjdk.aggregator/module-info.java
and infers that the classes belong to the
org.planetjdk.aggregator module
39
Running modular codejava -modulepath planetjdk/cls:rssutils/rome
-m org.planetjdk.aggregator
The java launcher looks for the org.planetjdk.aggregator
module on the modulepath and executes its main class
40
modulepath scalesat compile-time and runtime
41
requires + provides
A provides clause gives information about what the module exports
In Jigsaw, a module can have aliases:module jdk.core {
system jigsaw;provides module java-base;
}This module satisfies requires module java-base
in another module
42
Module-level annotationsimport com.foo.annotations.*;@DefaultNonNullmodule org.planetjdk.aggregator {
...}
module-info.class can hold generated annotationse.g. how dependencies were previously resolved
Annotate requires/provides clauses too?
43
Versioning
44
Rewind: Binary compatibility"Here is a list of some important binary compatible changes
that the Java programming language supports:Reimplementing existing methods, constructors, and
initializers to improve performance.Adding new fields, methods, or constructors to an existing
class or interface.Deleting private fields, methods, or constructors of a class.Moving a method upward in the class hierarchy...."
- Java Language Specification, Ch. 13
45
Binary compatibility
Is a set of properties, not a set of featuresDescribes what can be done
"To preserve binary compatibility, a class or interface should treat its accessible members and constructors,their existence and behavior, as a contract with its users"
Does not help with what cannot be doneRemoving membersChanging signatures and thrown exceptions
46
More is needed
Sun is often asked to change or remove APIs
People who want this rarely consult with people who would be affected!
But sometimes, it is desirable to refactor or remove
Versioning lets the vector of a change be described
Magnitude: major or minor?
Direction: change of signature? or of behavior?
47
Modular code is versionedmodule org.planetjdk.aggregator @ 1.0 {
system jigsaw;requires module jdom @ 1.0;requires module tagsoup @ 1.2;requires module rome @ 1.0;requires module rome-fetcher @ 1.0;requires module joda-time @ 1.6;requires module java-xml @ 7;requires module java-base @ 7;class org.planetjdk.aggregator.Main;
}
48
Versioning in JSR 294
Language + VM know that modules are versionedVersion structure, order, and ranges are
implementation details of a module systemStructure 1.2.3.4.5
I,II,III,IV,V..IX,X,L,C,D,MR11V16.4M3.2T200906031105
Order 1.2.3.4 > 1.2.31.6:u13 < 1.7:b60 < 1.6:u14
Range [1.0, 2.0) 1.* 1.*\1.31.0+ >=1.0 1.0
49
Versioning in the Jigsaw module systemmodule org.planetjdk.aggregator @ 1.0 {
system jigsaw;requires module jdom @ 1.*;requires module tagsoup @ 1.2.*;requires module rome @ =1.0;requires module rome-fetcher @ =1.0;requires module joda-time @ [1.6,2.0);requires module java-xml @ 7.*;requires module java-base @ 7.*;class org.planetjdk.aggregator.Main;
}
50
Language+VM defer to a module systemSuppose a module says:
system jigsaw;requires module M @ 2.*;
javac asks Jigsaw for M @ 2.*Jigsaw will respond with its lowest 2.* version, e.g. 2.1
Hotspot asks Jigsaw for M @ 2.*Jigsaw will respond with its highest 2.* version, e.g. 2.9
M's runtime behavior is predictable up to Jigsaw's version policy
51
Accessibility
52
Module-private accessibility
To share types and their members across packages but within a module, make them module-privatepublic class Foo {
module String m() { ... }}
Any class in same module as Foo can access Foo.mModule membership inferred from directory layout
Module-private accessibility stored in the classfile and enforced by the VM
53
module is a 'restricted keyword'
Adding keywords that break code is frowned uponYou really can write:
package module;module class module {
module module module = new module();module module() {}
}
('can' and 'should' are two different things)
54
'package' modifierpackage foo;package class Bar {
package String name;package String getName() {..}
}
(Not completely compelling)
55
More information
Subscribe to the JSR 294 observer listCheck out OpenJDK's Project Jigsaw
http://openjdk.java.net/projects/jigsaw/http://cr.openjdk.java.net/~mr/jigsaw/api/
Attend our Modularity BOF7.45pm tonight, Gateway 102/103http://blogs.sun.com/abuckley/http://blogs.sun.com/mr/
Alex [email protected]
57
Short answer: Yes, with an if
Long answer: No, with a but
Q&A