java 9 modules: the duke yet lives that osgi shall depose

Post on 21-Jan-2018

487 Views

Category:

Software

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Java 9 Modules. The Duke Yet Lives That OSGi Shall Depose

Nikita Lipsky

Excelsior LLC

1

2

Modules in IDE

3

Modules in Mavencom.foo

app1.0

com.fooparse-api

2.0

com.foopersist-api

3.0

org.apachecommons

2.1

org.apachecommons-io

3.14

Modules in Mavencom.foo

app1.0

com.fooparse-api

2.0

com.foopersist-api

3.0

org.apachecommons

2.1

org.apachecommons

3.15

OSGi

6

Why Jigsaw is not OSGi?

Mark Reinhold (the Chief Architect of the Java Platform Group):

“…As it (OSGi) stands, moreover, it’s useful for library and application modules but, since it’s built strictly on top of the Java SE Platform, it can’t be used to modularize the Platform itself”

7

Why Jigsaw is not OSGi?

Question: why the presence of j.l.Object in Java Language Specification, implemented in Java in turn, does not lead to a bootstrap problem?

Факт: Существует реализация Java SE, где OSGi поддерживается на уровне JVM (на уровне платформы).

8

Why Jigsaw is not OSGi?

Question: why the presence of j.l.Object in Java Language Specification, implemented in Java in turn, does not lead to a bootstrap problem?

Fact: There is a Java SE implementation that supports OSGi at the JVM level (at the platform level).

9

Nikita Lipsky• 20+ years in software development

• Excelsior JET project initiator– 16+ years of contributions– compiler engineer – team lead– product lead– etc.

• Twitter: @pjBooms

10

Excelsior JET?• AOT-centric Java SE implementation

– certified as Java Compatible since 2005

• AOT compiler + Java Runtime– mixed compilation: AOT + JIT– AOT support for custom classloaders (Eclipse RCP, Tomcat)

• Toolkit– Startup Optimizer– Deployment

11

Agenda

• Why OSGi

• How OSGi does it

• Why NOT OSGi

• Why Jigsaw is not OSGi

• Jigsaw mantra

• Jigsaw problems

12

Where OSGi?

Standardized by OSGi Alliance (IBM, Adobe, Bosch, Huawei, NTT, Oraсle)

Implementations:

• Equinox – Eclipse IDE, Eclipse RCP, IBM Websphere

• Apache Felix– Oracle WebLogic, Glassfish, Netbeans

13

Why OSGi?

14

Why OSGi?• Modularity

– Reduced complexity– Hide internals (encapsulation)– Dependency management and easy deployment

• Dynamic updates• Versioning• Lazy• Simple, fast, small, secure, etc.https://www.osgi.org/developer/benefits-of-using-osgi/

15

Модульная система OSGi

16

OSGi Module SystemOSGi module – Bundle:• Jar or directory• Import/export is defined in META-INF/MANIFEST.MF:

Manifest-Version: 1.0 Bundle-ManifestVersion: 2

Bundle-SymbolicName: B

Bundle-Version: 1

Bundle-Name: B Bundle

Export-Package: org.bar

Import-Package: org.foo;version=“[1,2)”

17

OSGi Module System

• OSGi bundle imports/exports

– packages (Import-Package/Export-Package)

– services (Import-Service/Export-Service).

• May import other bundles directly

– Require-Bundle directive

– However it is not the best practice (less flexible)

18

OSGi Module System

19

Bundle A

Class ABundle B

Class B

Bundle C

Class CExport-Package: packageCImport-Package: packageA

Export-Package: packageAI

Import-Package: packageA,packageC

OSGi Runtime

• Resolves Import/Export of OSGi bundles(wiring)

• Defines bundle life cycle

– May start (activate) bundles lazily

– Enables on-the-fly bundle updates without system restart (aka hot redeploy).

20

Jar/Classpath HellApp1.0

LibraryFoo2.0

LibraryBar3.0

LibraryBaz2.1

LibraryBaz3.1

21

Versioning in OSGi

• OSGI resolves JAR hell:

– import/export is qualified by version

– If two bundles require a library bundle of two different versions, both versions will be loaded

22

Why OSGi?So, OSGi promises:• Modularity

– explicit dependencies– encapsulation

• JAR Hell problem resolution– via versioning

• Hot ReDeploy– via ability to update a separate bundle dynamically

23

Why OSGi?So, OSGi promises:• Modularity

– explicit dependencies– encapsulation

• JAR Hell problem resolution– via versioning

• Hot ReDeploy– via ability to update a separate bundle dynamically

24

Why OSGi?So, OSGi promises:• Modularity

– explicit dependencies– encapsulation

• JAR Hell problem resolution– via versioning

• Hot ReDeploy– via ability to update a separate bundle dynamically

25

Why OSGi?So, OSGi promises:• Modularity

– explicit dependencies– encapsulation

• JAR Hell problem resolution– via versioning

• Hot ReDeploy– via ability to update a separate bundle dynamically

26

27

How OSGi?

28

Versioning in OSGi

Question: How to implement versioning?

Task: For given A module importing Lib (v1) library, and B module importing Lib (v2), it is required that both versions of Lib working without conflicts.

Solution: load the versions of the library by different classloaders.

29

Versioning in OSGi

Question: How to implement versioning?

Task: For a given module A importing library Lib (v1), and module B importing Lib (v2), it is required that both versions of Lib work without conflicts.

Solution: load the versions of the library by different classloaders.

30

Versioning in OSGi

Question: How to implement versioning?

Task: For a given module A importing library Lib (v1), and module B importing Lib (v2), it is required that both versions of Lib work without conflicts.

Solution: load versions of the library by different classloaders.

31

Versioning in OSGi

Thus each OSGi bundle is loaded by its own classloader:

• Subtype of java.lang.ClassLoader

• Unique class namespace

• No conflicts with classes of other bundles

32

Versioning in OSGi

33

com.fooApp1.0

com.fooparse-api

2.0

com.foopersist-api

3.0

org.apachecommons

2.1

org.apachecommons

3.1

CL

CL

CL

CL

CL

Different versions of apache commons may simultaneously present in the JVM

Each bundle hasits own classloader

Encapsulation in OSGi

34

Encapsulation in OSGisrc/com/foo/exported/A.java:

package com.foo.exported;

import com.foo.internal.B;

public class A {B useB;

}

src/com/foo/internal/B.java:

package com.foo.internal;

public class B {

}

How to make the class B inaccessible from outside?

35

Encapsulation in OSGi

Question: how to make an internal class of a module declared public inaccessible outside?

36

Encapsulation in OSGi

Question: how to make an internal class of a module declared public inaccessible outside?

Answer: classloaders (!) may hide internal classes.

37

Dynamic Updates

Task: update one (!) changed bundle in a running program without stopping it

38

Dynamic Updates

Task: update one (!) changed bundle in a running program without stopping it

Solution: CLASSLOADERS!

(unload old bundle, load new bundle by a new classloader)

39

Bundle life cycle

40

Lazy start

Start of bundles in OSGi is implemented via the bundle activators feature:• Each bundle may have an activator

– Bundle-Activator manifest directive– Implementation of an interface with methods start(), stop()

– Static class initializer analogue for bundles

41

Lazy start

Start of bundles in OSGi is implemented via the bundle activators feature:

public interface BundleActivator {void start(BundleContext context) throws Exception;void stop(BundleContext context) throws Exception;

}

42

Lazy start

• Bundle start can be defined by OSGi configuration

• Otherwise the bundle starts when it is required by other started bundles

43

Lazy start

Task: start (load) bundles only when they become needed for program execution

44

Lazy start

Solution: CLASSLOADERS (again!) in OSGi invoke the start()method of the bundle activator right before loading of the first class of a bundle

Since classloading in the JVM is lazy, bundle activation becomes lazy AUTOMATICALLY

45

Lazy start

Solution: CLASSLOADERS (again!) in OSGi invoke the start()method of the bundle activator right before loading of the first class of a bundle

Since classloading in the JVM is lazy, bundle activation becomes lazy AUTOMATICALLY

46

Lazy start

Solution: CLASSLOADERS (again!) in OSGi invoke the start()method of the bundle activator right before loading of the first class of a bundle

Since classloading in the JVM is lazy, bundle activation becomes lazy AUTOMATICALLY

47

How OSGi?

All solved in one fell swoop!48

49

Why Not OSGi?

50

Modularity?Bundle A

Bundle B

51

Modularity?Bundle A

Bundle B Bundle C

52

Modularity?Bundle A

Bundle B Bundle C

Bundle D

53

Modularity?Bundle A

Bundle B Bundle C

Bundle D

54

Modularity?Bundle A

Bundle B Bundle C

Bundle D

55

Modularity?Bundle A

Bundle B Bundle C

Bundle D

56

Modularity?

OSGI allows cycles in

the dependency graph

Exercise: understand, why

that is bad

A

B C

D

57

On the fly updates?

58

On the fly updates?

Bundle ABundle B

59

On the fly updates?

Bundle ABundle B

Let’s update bundle B

60

On the fly updates?

Bundle ABundle B

61

On the fly updates?

Bundle A

Bundle B

62

On the fly updates?

Bundle A

NEWBundle B

63

On the fly updates?

Bundle ANEWBundle B

64

On the fly updates?

Bundle ABundle B

Does it work for bundle A?

65

On the fly updates?

Bundle B

Class B

Bundle A

Class А

66

On the fly updates?

Bundle B

Class B

Bundle A

Class А

If bundle B imports bundle А then there is a class from B that references a class from A

67

Symbolic references resolution

B.java:class B {

A useA;int f1 = A.f;int f2 = A.foo();

}

A.java:class A {

static int f;static int foo(){};

}68

Symbolic references resolution

69

B.class…

CONSTANT_Class: A

CONSTANT_FieldRef: A.f@int

CONSTANT_MethodRef: A.foo()I

A.class…

Field: f@int

Method: foo()I

Symbolic references resolution

• A class references other classes and their fields/methods symbolically

70

Symbolic references resolution

• A class references other classes and their fields/methods symbolically

• JVM resolves those symbolic references with real values at runtime

71

Symbolic references resolution

• A class references other classes and their fields/methods symbolically

• JVM resolves those symbolic references with real values at runtime

• Once a reference is resolved, the value of the reference is never changed!

72

On the fly updates?

• If a reference from a class B to a class A is resolved then the class А cannot be unloadedfrom the JVM without unloading the class B

73

On the fly updates?

• If a reference from a class B to a class A is resolved then the class А cannot be unloadedfrom the JVM without unloading the class B

• Hence if a bundle В imports a bundle А then the bundle А cannot be unloaded without also unloading the bundle B

74

On the fly updates?

Bundle ABundle B

Let’s update bundle A

75

On the fly updates?

Bundle ABundle B

76

On the fly updates?

Bundle A

Bundle B

77

On the fly updates?

Бандл ABundle B

78

On the fly updates?

Now let’s remember

cyclic dependencies

Exercise: try to update

SWT bundle in running Eclipse

A

B C

D

79

80

On the fly updates?

• On the fly updates in OSGi work, more or less, only for leaf bundles that are not imported by other bundles – plugins

81

On the fly updates?

• On the fly updates in OSGi work, more or less, only for leaf bundles that are not imported by other bundles – plugins

• There are much simpler ways than OSGi to implement plugins

82

On the fly updates?

Even leaf bundles are not so easy to unload from the JVM:

• The classes from leaf bundles can live in the JVM after their unloading

– Known problem: Classloaders Memory Leak

83

One does not simply

unload a class from the JVM84

Versioning?

85

Versioning?App1.0

Foo2.0

Bar3.0

Baz2.1

Baz3.1

86

Versioning?App1.0

Foo2.0

Bar3.0

Baz2.1

Baz3.1

87

Versioning?App1.0

Foo2.0

Bar3.0

Baz2.1

Baz3.1

A

88

Versioning?App1.0

Foo2.0

Bar3.0

Baz2.1

Baz3.1

A A

89

Versioning?App1.0

Foo2.0

Bar3.0

Baz2.1

Baz3.1

A

A

90

Versioning?App1.0

Foo2.0

Bar3.0

Baz2.1

Baz3.1

A A

91

Versioning?App1.0

Foo2.0

Bar3.0

Baz2.1

Baz3.1

A A

92

Versioning?App1.0

Foo2.0

Bar3.0

Baz2.1

Baz3.1

A A

I’m “A”!

93

Versioning?App1.0

Foo2.0

Bar3.0

Baz2.1

Baz3.1

A A

I’m “A”!No, I’m

“A”!

94

Versioning?App1.0

Foo2.0

Bar3.0

Baz2.1

Baz3.1

AAAAA!AAAAA!

AA

95

96

Loading constraints

• Loading constraints prohibit two classes with the same fully qualified name to appear in the namespace of another class

97

Loading constraints

B.java:class B {

T1 f1 = A.f;int f2 = A.m(t2);

}

A.java:class A {

static T1 f;static int m(T2 t)

If B is loaded by L1 classloader and A is loaded by L2 then the JVM will check that (T1, L1) = (T1, L2) and (T2, L1) = (T2, L2)

==

98

Versioning?

• JVM throws java.lang.LinkageError on loading constraints violation

99

Versioning?

• JVM throws java.lang.LinkageError on loading constraints violation

• OSGi DOES NOT help developers to avoid loading constraints violation

– Just google for “OSGI” and “LinkageError” to estimate the scale of the problem

100

Versioning?

There are bundles in the latest Eclipse versions with potential loading constraints violations and nobody cares!

101

Versioning?

Conclusion: OSGi does not solve JAR Hell but raises it to a new, more sophisticated level.

102

Versioning?

Conclusion: Do not use two different versions of the same library in one application!

103

Encapsulation?

Question: well, at least the encapsulation problem is solved by OSGi, right?

104

Reflection – universal countermeasure

against encapsulation in Java

Encapsulation?

setAccessible(true)

105

Encapsulation?

Question: well, at least the encapsulation problem is solved by OSGi, right?

Answer: OSGi does not protect from unauthorized access via Reflection

106

Lazy start?

107

Lazy start?

108

Lazy start?Bundle A

Bundle B Bundle C

Question: in what order the bundles will be activated?

109

Lazy start?

Bundle activation order in OSGi depends on classloading order directly

– A bundle is started from loadClass() of the bundle classloader

110

Lazy start?

Bundle activation order in OSGi depends on classloading order directly

– A bundle is started from loadClass() of the bundle classloader

However, class loading order is not defined by the JVM specification!

111

Symbolic references resolutionA class may reference other classes and their fields/methods symbolically. A JVM may resolve references:

• Lazily– Each reference is resolved on first access

• Eagerly– All references are resolved at the time of class loading

112

Lazy start?

The classloading order depends on the class reference resolution scheme in the given JVM implementation: lazy, less lazy, eager.

113

Lazy start?

Bundle B activator:class B implements BundleActivator {

public void start() {assert A.f!= null;

}

Bundle A activator:class A implements BundleActivator {

static T f;public void start() {

f = new T();}

Typical case: В thinks that А is already activated, but in fact А can be activated after B, so assertion fails

114

Lazy start?

• Bundle activation scheme in OSGi is a time bomb:

– If the JVM starts to resolve class references less lazily, practically all OSGi applications will stop working

115

Why NOT OSGi?

• Modularity with cycles

• Hot Redeploy works for leaf bundles only

• No protection from loading constraints violation

• No protection of implementation details from reflective access

• Bundle activation order depends substantially on class reference resolution scheme

116

Jigsaw

117

Jigsaw

118

Jigsaw vs. OSGi

OSGi is dynamic essentially

– modules appear at run time only

119

Jigsaw vs. OSGi

Jigsaw was thought up as static from the beginning.

Practically all JDK tools know about modules:– javac: respects modules visibility rules

– jdeps: analyses dependencies

– jar, jmod: pack modules

– jlink: prepares final image for deployment

– java: there are modules in runtime as well

120

Module example// src/java.sql/module-info.javamodule java.sql {

requires transitive java.logging;requires transitive java.xml;

exports java.sql;exports javax.sql;exports javax.transaction.xa;uses java.sql.Driver;

}

121

Jigsaw vs. OSGi

Jigsaw prohibits (explicit) cycles

in the dependency graph

Modules import modules

and not packages.

122

Versioning

There was versioning in the first drafts of Jigsaw (similar to OSGi).

123

Versioning

There was versioning in the first drafts of Jigsaw (similar to OSGi).

However versioning was removed later …

124

Versioning

There was versioning in the first drafts of Jigsaw (similar to OSGi).

However versioning was removed later …

Why?

125

Versioning

Versioning immediately means:

1 module 1 classloader

126

Versioning

Versioning immediately means:

1 module 1 classloader

It was exactly so in the first Jigsaw drafts!

127

Jigsaw and classloaders

Jigsaw is not just modules, but also the Java SE platform split into modules.

128

Jigsaw and classloaders

Backward compatibility problem:

According to the specification

getClassloader() == nullfor core platform classes.то противоречит

That precludes splitting of the platform into modules, with each module loaded by its loader

129

Jigsaw and classloaders

Backward compatibility problem:

According to the specification

getClassloader() == nullfor core platform classes.то противоречит

That precludes splitting of the platform into modules, with each module loaded by its loader

130

Jigsaw and classloaders

Problem 2: How to protect developers from loading constraints violation?

131

Versioning

Another detail: import in early Jigsaw versions (as in OSGi) was qualified by not a single version but by а version range:

– A module may declare that it can work with a dependency of “from” version to “to” version

132

Versioning

Problem 3: Resolving dependencies (wiring modules) from version ranges is an NP-complete problem!

– Reduced to 3-SAT

133

Versioning

… after that versioning in JPMS breathed its last.

134

Versioning

… after that versioning in JPMS breathed its last.

No versioning – no classloaders for modules.

135

Jigsaw

• No dynamic updates

• No versioning

136

Jigsaw

• No dynamic updates

• No versioning

So what does it have?

137

Jigsaw Mantra

Reliable Configuration

Strong Encapsulation

138

Reliable Configuration

Такая ситуация в Jigsaw просто запрещена!

App1.0

Foo2.0

Bar3.0

Baz2.1

Baz3.1

139

Reliable Configuration

Jigsaw simply prohibits this situation!

App1.0

Foo2.0

Bar3.0

Baz2.1

Baz3.1

140

Reliable Configuration

Right (reliable) configuration:

App1.0

Foo2.5

Bar3.0

Baz3.1

141

Reliable Configuration

Reliable configuration:

• All module dependencies are resolved

• No cyclic dependencies

• No modules containing the same packages (split packages)

These properties are checked at startup (wiring)

142

Strong Encapsulation

setAccessible(true)

143

Strong Encapsulation

Java 9 modules are first class citizens

• Define visibility access rules

– via declared export

• There is no access to non-exported functionality outside of the module even via reflection

– Even setAccessible(true) does not work

144

Strong Encapsulation

Java 9 modules are first class citizens

• Define visibility access rules

– via declared export

• There is no access to non-exported functionality outside of the module even via reflection

– Even setAccessible(true) does not work

145

Strong Encapsulation

Java 9 modules are first class citizens

• Define visibility access rules

– via declared export

• There is no access to non-exported functionality outside of the module even via reflection

– Even setAccessible(true) does not work

146

So Jigsaw does not have problems?

147

148

Reliable Configuration?

• Reflective access was prohibited between modules without explicit dependencies in early Jigsaw drafts

• However it had to be relaxed when classloaders had gone from JPMS– because Class.forName() has to work

backward compatible

149

Reliable Configuration?

• Reflective access was prohibited between modules without explicit dependencies in early Jigsaw drafts

• Had to be relaxed when classloaders had gone from JPMS– because Class.forName() had to remain

backward compatible

150

Reliable Configuration?

However if you may have reflective dependencies that are not explicitly declared, where is the guarantee that the resulting configuration is reliable?

151

Reliable Configuration?

Split packages are prohibited, but what about application containers (Tomcat, Java EE)?

152

Jigsaw Layers *

To solve the application containers problem

Layers feature was introduced in JPMS:

• Local module system for each application in a container

• Two modules containing the same package have to belong to different layers

153

Jigsaw Layers *

* The picture is from Alex Buckley’s presentation: Project Jigsaw Under the hood154

Strong Encapsulation?

155

Strong Encapsulation?

The platform is split into modules:

• Which means that private APIs become really private

156

Strong Encapsulation?

The platform is split into modules:

• Which means that private APIs become really private

• But what about

sun.misc.Unsafe ?

157

Strong Encapsulation?

Ok, Java community (temporarily)

defended sun.misc.Unsafe (in an unequal fight)!

158

Strong Encapsulation?

But what about Dependency Injection?

159

Strong Encapsulation?

DI frameworks essentially depend on:

• reflective access to the code in which they inject dependencies

• including non-exported code

160

Strong Encapsulation?

module my.module {exports my.module.pack;

}

161

Strong Encapsulation?

module my.module {exports my.module.pack;exports my.module.internal.object.orgy;

}

162

Strong Encapsulation?

module my.moduleO{

exports my.module.pack;}

163

Strong Encapsulation?

open module my.module {

exports my.module.pack;}

164

Strong Encapsulation?

Open modules were introduced to solve the DI frameworks problem:

• An open module allows reflective access to its non-exported functionality

165

Strong Encapsulation?

Open modules provide not-so-strong encapsulation, but it is better than nothing.

166

Jigsaw

Well, but what benefits me in Jigsaw at last?

167

Jigsaw benefitsIf all your dependencies are on the classpath now, migrating to the modulepath would improve the architecture of your application by eliminating:• cycles in the dependencies• split packages (jar hell)• unsound access into implementation details of

other modules• dependencies to JDK private API

168

Jigsaw benefitsIf all your dependencies are on the classpath now, migrating to the modulepath would improve the architecture of your application by eliminating:• cycles in the dependency graph• split packages (jar hell)• unsound access into implementation details of

other modules• dependencies to JDK private API

169

Jigsaw benefitsIf all your dependencies are on the classpath now, migrating to the modulepath would improve the architecture of your application by eliminating:• cycles in the dependency graph• split packages (jar hell)• unsound access into implementation details of

other modules• dependencies to JDK private API

170

Jigsaw benefitsIf all your dependencies are on the classpath now, migrating to the modulepath would improve the architecture of your application by eliminating:• cycles in the dependency graph• split packages (jar hell)• unsound reliance upon implementation details of

other modules• dependencies to JDK private API

171

Jigsaw benefitsIf all your dependencies are on the classpath now, migrating to the modulepath would improve the architecture of your application by eliminating:• cycles in the dependency graph• split packages (jar hell)• unsound reliance upon implementation details of

other modules• dependencies on JDK private APIs

172

Jigsaw benefits

Jigsaw introduces a migration path to the modulepath:

• Old classpath forms Unnamed Modulе

• Jars from classpath may be temporally moved as is to modulepath as Auto Modules

• Module declaration can be added to auto modules later

173

Jigsaw benefits

Jigsaw introduces a migration path to the modulepath:

• Old classpath forms Unnamed Module

• Jars from classpath may be temporally moved as is to modulepath as Auto Modules

• Module declaration can be added to auto modules later

174

Jigsaw benefits

Jigsaw introduces a migration path to the modulepath:

• Old classpath forms Unnamed Modulе

• Jars from classpath may be temporarily moved “as-is” to modulepath as Auto Modules

• Module declaration can be added to auto modules later

175

Jigsaw benefits

Jigsaw introduces a migration path to the modulepath:

• Old classpath forms Unnamed Modulе

• Jars from classpath may be temporarily moved “as-is” to modulepath as Auto Modules

• Module declaration can be added to auto modules later

176

Jigsaw benefitsUnfortunately, most Java developers won’t benefit from JPMS immediately:• Java EE standards do not define how they will

interoperate with JPMS yet• Even servlet containers standard knows nothing

about modules so far– Dependencies in war файлах are essentially old plain

classpath!

177

Jigsaw benefitsUnfortunately, most Java developers won’t benefit from JPMS immediately:• Java EE standards do not define how they will

interoperate with JPMS yet• Even the servlet container standard knows

nothing about modules so far– Dependencies in war files are old plain classpath in

fact!

178

The birth is inevitable!

179

Conclusion• OSGi is a nice attempt to give modules to Java

developers– but OSGi has many problems unfortunately– including fundamental

• Jigsaw is a carefully designed system without visible fundamental problems– but with a system of checks and balances– there are community acceptance problems

180

Q & A

Nikita Lipsky,Excelsior

nlipsky@excelsior-usa.comtwitter: @pjBooms

181

top related