Migrating Speedment to Java 9 Dan Lawesson , @dan_lawesson CSO, - - PowerPoint PPT Presentation

migrating speedment to java 9
SMART_READER_LITE
LIVE PREVIEW

Migrating Speedment to Java 9 Dan Lawesson , @dan_lawesson CSO, - - PowerPoint PPT Presentation

Migrating Speedment to Java 9 Dan Lawesson , @dan_lawesson CSO, Speedment, Inc About Us About Us Dan Lawesson, PhD AI, model-based diagnosis CSO with S as in Science 20 years of Java experience Previous lives:


slide-1
SLIDE 1

Migrating Speedment to Java 9

Dan Lawesson , @dan_lawesson 
 CSO, Speedment, Inc

slide-2
SLIDE 2

About Us

slide-3
SLIDE 3

About Us

Dan Lawesson, PhD

  • AI, model-based diagnosis
  • CSO with S as in Science
  • 20 years of Java experience
  • Previous lives: telecom and

automotive IoT

slide-4
SLIDE 4

About Us

Dan Lawesson, PhD

  • AI, model-based diagnosis
  • CSO with S as in Science
  • 20 years of Java experience
  • Previous lives: telecom and

automotive IoT

Spire

  • Speedment Open Source mascot
  • Lives on GitHub
  • 2 years of mascot experience
slide-5
SLIDE 5

Outline

slide-6
SLIDE 6

Outline

  • Speedment

  • Jigsaw

  • Jigsawing Speedment

slide-7
SLIDE 7

Speedment

slide-8
SLIDE 8

Speedment

Speedment is

slide-9
SLIDE 9

Speedment

Speedment is

  • a Streams API ORM
slide-10
SLIDE 10

Speedment

Speedment is

  • a Streams API ORM
  • using in-JVM memory acceleration
slide-11
SLIDE 11

Speedment

Speedment is

  • a Streams API ORM
  • using in-JVM memory acceleration
  • and Code Generation,
slide-12
SLIDE 12

Speedment

Speedment is

  • a Streams API ORM
  • using in-JVM memory acceleration
  • and Code Generation,
  • with modular design
slide-13
SLIDE 13

Speedment

Speedment is

  • a Streams API ORM
  • using in-JVM memory acceleration
  • and Code Generation,
  • with modular design

Oracle Java Magazine May-June pages 34-40

slide-14
SLIDE 14

Speedment

Speedment is

  • a Streams API ORM
  • using in-JVM memory acceleration
  • and Code Generation,
  • with modular design

Oracle Java Magazine May-June pages 34-40

slide-15
SLIDE 15
slide-16
SLIDE 16

Compile-time Code Generation Tool

slide-17
SLIDE 17

Compile-time Code Generation Tool

slide-18
SLIDE 18
slide-19
SLIDE 19

Querying the Database using Streams

slide-20
SLIDE 20

Querying the Database using Streams

  • Queries are expressed using the

standard Java 8 Stream API

slide-21
SLIDE 21

Querying the Database using Streams

  • Queries are expressed using the

standard Java 8 Stream API

  • Streams are analyzed to produce

high-performance queries

slide-22
SLIDE 22

Expressing Queries as Streams

customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count();

slide-23
SLIDE 23

Expressing Queries as Streams

customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count(); Standard Stream API

slide-24
SLIDE 24

Expressing Queries as Streams

customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count(); Standard Stream API Full Type-Safety

slide-25
SLIDE 25

Expressing Queries as Streams

customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count(); Standard Stream API Generated Enum Constants Full Type-Safety

slide-26
SLIDE 26

Expressing Queries as Streams

customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count(); Standard Stream API Generated Enum Constants Only 1 value is loaded from DB Full Type-Safety

slide-27
SLIDE 27

Expressing Queries as Streams

customers.stream() .filter(Customer.REGION.equal(Region.NORTH_AMERICA)) .filter(Customer.REGISTERED.greaterOrEqual(startOfYear)) .count(); Standard Stream API Generated Enum Constants Only 1 value is loaded from DB Full Type-Safety

SELECT COUNT('id') FROM 'customer' WHERE 'customer'.'region' = ‘North America’ AND 'customer'.'registered' >= ‘2016-01-01’;

slide-28
SLIDE 28

Querying the Database using Streams

SELECT * FROM 'customer' REGION.equal(NORTH_AMERICA) REGISTERED.greaterOrEqual(2016-01-01) count() Source Filter Filter Term. Pipeline

slide-29
SLIDE 29

Querying the Database using Streams

SELECT * FROM 'customer' WHERE 'customer'.'region' = ‘North America’ REGION.equal(NORTH_AMERICA) REGISTERED.greaterOrEqual(2016-01-01) count() Source Filter Filter Term. Pipeline

slide-30
SLIDE 30

Querying the Database using Streams

SELECT * FROM 'customer' WHERE 'customer'.'region' = ‘North America’ AND 'customer'.'registered' >= ‘2016-01-01’; REGISTERED.greaterOrEqual(2016-01-01) count() Source Filter Term. Pipeline

slide-31
SLIDE 31

Querying the Database using Streams

SELECT COUNT('id') FROM 'customer' WHERE 'customer'.'region' = ‘North America’ AND 'customer'.'registered' >= ‘2016-01-01’; count() Source Term. Pipeline

slide-32
SLIDE 32

Querying the Database using Streams

SELECT COUNT('id') FROM 'customer' WHERE 'customer'.'region' = ‘North America’ AND 'customer'.'registered' >= ‘2016-01-01’; Source Pipeline

slide-33
SLIDE 33

Expressing Queries as Streams

// Gets the second page of customers in North America // sorted by name in the form of a JSON array

slide-34
SLIDE 34

Expressing Queries as Streams

// Gets the second page of customers in North America // sorted by name in the form of a JSON array customers.stream() .filter(REGION.equal(Region.NORTH_AMERICA)) .sorted(NAME.comparator()) .skip(10) .limit(10) // JVM from here… .collect(toJson(encode.allOf(customers))) [ {”id”:11, ”name”: …}, {…}, … ]

slide-35
SLIDE 35

Parallelism as Expected for a Stream

// Supports parallelism on custom executors // with full control of thread work item layout

slide-36
SLIDE 36

Parallelism as Expected for a Stream

// Supports parallelism on custom executors // with full control of thread work item layout customers.stream() .parallel() .filter(REGION.equal(Region.NORTH_AMERICA)) .forEach(expensiveOperatation());

slide-37
SLIDE 37

Querying

Optional<Hare> oldHare = hares.stream() .filter(Hare.AGE.greaterThan(5)) .findAny();

slide-38
SLIDE 38

Querying

Optional<Hare> oldHare = hares.stream() .filter(Hare.AGE.greaterThan(5)) .findAny();

Predicate Builder

slide-39
SLIDE 39

Querying

Optional<Hare> oldHare = hares.stream() .filter(Hare.AGE.greaterThan(5)) .findAny();

Predicate Builder

SELECT id, name, color, age FROM hare WHERE (age > 5) LIMIT 1;

slide-40
SLIDE 40

Entities are Linked

// Find the owner of the orange carrot Optional<Hare> hare = carrots.stream() .filter(Carrot.NAME.equal("Orange")) .map(hares.finderBy(Carrot.OWNER)) .findAny(); // Find one carrot owned by Harry // Carrot is a foreign key table Optional<Carrot> carrot = hares.stream() .filter(Hare.NAME.equal("Harry")) .flatMap(carrots.finderBackwardsBy(Carrot.OWNER)) .findAny();

slide-41
SLIDE 41

Joins

Map<Hare, List<Carrot>> join = carrots.stream() .collect( groupingBy(hares.finderBy(Carrot.OWNER)) );

slide-42
SLIDE 42

Joins

Map<Hare, List<Carrot>> join = carrots.stream() .collect( groupingBy(hares.finderBy(Carrot.OWNER)) );

Standard Java 8

slide-43
SLIDE 43

Joins

Map<Hare, List<Carrot>> join = carrots.stream() .collect( groupingBy(hares.finderBy(Carrot.OWNER)) );

Standard Java 8

slide-44
SLIDE 44

Imperative vs Declarative

slide-45
SLIDE 45

Imperative vs Declarative

SQL describes what rather than how

slide-46
SLIDE 46

Imperative vs Declarative

SQL describes what rather than how database engine figures out the how

slide-47
SLIDE 47

Imperative vs Declarative

SQL describes what rather than how database engine figures out the how Streams are also declarative - a result is described

slide-48
SLIDE 48

Imperative vs Declarative

SQL describes what rather than how database engine figures out the how Streams are also declarative - a result is described framework takes pipeline as input and determines the how

slide-49
SLIDE 49

Typical ORM + Java Streams Application

slide-50
SLIDE 50

Typical ORM + Java Streams Application

Explicit SQL + Java Stream is an imperative two step program:

slide-51
SLIDE 51

Typical ORM + Java Streams Application

Explicit SQL + Java Stream is an imperative two step program:

  • 1. Compute Result Set SELECT x FROM y WHERE z

slide-52
SLIDE 52

Typical ORM + Java Streams Application

Explicit SQL + Java Stream is an imperative two step program:

  • 1. Compute Result Set SELECT x FROM y WHERE z

  • 2. Stream over Result Set rs.stream().filter…
slide-53
SLIDE 53

Speedment - Breaking the Language Barrier

slide-54
SLIDE 54

Speedment - Breaking the Language Barrier

Java Stream expressing both database and JVM operations ->

slide-55
SLIDE 55

Speedment - Breaking the Language Barrier

Java Stream expressing both database and JVM operations -> the program is declarative,

slide-56
SLIDE 56

Speedment - Breaking the Language Barrier

Java Stream expressing both database and JVM operations -> the program is declarative, the runtime determines the DB-JVM work split.

slide-57
SLIDE 57

Speedment - Fully Declarative DB Applications

slide-58
SLIDE 58

Speedment - Fully Declarative DB Applications

Fully declarative ->

slide-59
SLIDE 59

Speedment - Fully Declarative DB Applications

Fully declarative -> Speedment Enterprise: add in-memory-acceleration

slide-60
SLIDE 60

Speedment - Fully Declarative DB Applications

Fully declarative -> Speedment Enterprise: add in-memory-acceleration without changing anything in the stream application.

slide-61
SLIDE 61

Jigsaw

slide-62
SLIDE 62

Jigsaw

slide-63
SLIDE 63

Jigsaw

  • Modules - an abstraction on top of packages
  • Strong Encapsulation
  • Reliable Configuration
slide-64
SLIDE 64

Jigsaw

  • Modules - an abstraction on top of packages
  • Strong Encapsulation
  • Reliable Configuration
slide-65
SLIDE 65
slide-66
SLIDE 66

Split Packages

Reliable configuration - a package may only belong to one module

slide-67
SLIDE 67

Split Packages

Reliable configuration - a package may only belong to one module

slide-68
SLIDE 68

Split Packages

Reliable configuration - a package may only belong to one module

slide-69
SLIDE 69

Split Packages

Reliable configuration - a package may only belong to one module

X

slide-70
SLIDE 70
slide-71
SLIDE 71

Automatic Modules

slide-72
SLIDE 72

Automatic Modules

  • Smooth transition to Java 9
slide-73
SLIDE 73

Automatic Modules

  • Smooth transition to Java 9
  • Move the Java 8 JAR from class path to module path
slide-74
SLIDE 74

Automatic Modules

  • Smooth transition to Java 9
  • Move the Java 8 JAR from class path to module path
  • The JAR automatically becomes a module
slide-75
SLIDE 75
slide-76
SLIDE 76

Automatic modules vs split packages

  • Maven puts dependencies on the module path
slide-77
SLIDE 77

Automatic modules vs split packages

  • Maven puts dependencies on the module path
  • Java 8 to 9 portability -> automatic modules
slide-78
SLIDE 78

Automatic modules vs split packages

  • Maven puts dependencies on the module path
  • Java 8 to 9 portability -> automatic modules
  • Automatic modules give split packages
slide-79
SLIDE 79

Automatic modules vs split packages

  • Maven puts dependencies on the module path
  • Java 8 to 9 portability -> automatic modules
  • Automatic modules give split packages
  • But reliable configuration means no split packages
slide-80
SLIDE 80

Automatic modules vs split packages

  • Maven puts dependencies on the module path
  • Java 8 to 9 portability -> automatic modules
  • Automatic modules give split packages
  • But reliable configuration means no split packages

slide-81
SLIDE 81

Some Other Jigsaw Controversies

slide-82
SLIDE 82

Some Other Jigsaw Controversies

  • Works for JDK != works for applications
  • Restricts current application domain use cases

slide-83
SLIDE 83

Some Other Jigsaw Controversies

  • Works for JDK != works for applications
  • Restricts current application domain use cases

  • sun.misc.Unsafe
  • ”Should not be used” vs ”A key for Java real-world success”

slide-84
SLIDE 84

Some Other Jigsaw Controversies

  • Works for JDK != works for applications
  • Restricts current application domain use cases

  • sun.misc.Unsafe
  • ”Should not be used” vs ”A key for Java real-world success”

  • Fundamentally different compared to e.g. OSGi
  • lazy loading, dynamic package adding, split packages
slide-85
SLIDE 85

Jigsawing the Java 8 Application

slide-86
SLIDE 86

Jigsawing the Java 8 Application

  • Run Java 8 under Java 9 is super easy
slide-87
SLIDE 87

Jigsawing the Java 8 Application

  • Run Java 8 under Java 9 is super easy

java –cp <…> –jar app.jar

slide-88
SLIDE 88

Jigsawing the Java 8 Application

  • Run Java 8 under Java 9 is super easy

java –cp <…> –jar app.jar

  • The challenge is to move from cp to mp
slide-89
SLIDE 89

Inter module dependencies

slide-90
SLIDE 90

Inter module dependencies

Dependencies explicitly given in module-info.java

slide-91
SLIDE 91

Inter module dependencies

Dependencies explicitly given in module-info.java

module com.speedment.common {
 requires com.foo.bar; // a module we depend on exports com.speedment.common.invariant; // a package we expose to the user }

slide-92
SLIDE 92

A Straight-Forward Modularization Approach

class path module path

slide-93
SLIDE 93

A Straight-Forward Modularization Approach

  • 1. All JARs on class path <all jars>

class path module path

slide-94
SLIDE 94

A Straight-Forward Modularization Approach

  • 1. All JARs on class path <all jars>
  • 2. App as a monolithic module <all deps> myapp.jar

class path module path

slide-95
SLIDE 95

A Straight-Forward Modularization Approach

  • 1. All JARs on class path <all jars>
  • 2. App as a monolithic module <all deps> myapp.jar
  • 3. Declare dependencies

class path module path

slide-96
SLIDE 96

A Straight-Forward Modularization Approach

  • 1. All JARs on class path <all jars>
  • 2. App as a monolithic module <all deps> myapp.jar
  • 3. Declare dependencies
  • 4. Move some JARs from cp to mp <deps> ->

class path module path

slide-97
SLIDE 97

A Straight-Forward Modularization Approach

  • 1. All JARs on class path <all jars>
  • 2. App as a monolithic module <all deps> myapp.jar
  • 3. Declare dependencies
  • 4. Move some JARs from cp to mp <deps> ->
  • 5. Modularize app

class path module path

slide-98
SLIDE 98

The Speedment Java 8 Modules

slide-99
SLIDE 99

The Speedment Java 8 Modules

Speedment pom.xml

slide-100
SLIDE 100

The Speedment Java 8 Modules

Speedment pom.xml

<modules> <module>common-parent</module> <module>runtime-parent</module> <module>generator-parent</module> <module>tool-parent</module> <module>build-parent</module> <module>plugin-parent</module> <module>connector-parent</module> <module>archetype-parent</module> <module>example-parent</module> </modules>

slide-101
SLIDE 101

The Modules of the Speedment common Module

slide-102
SLIDE 102

The Modules of the Speedment common Module

Speedment common/pom.xml

slide-103
SLIDE 103

The Modules of the Speedment common Module

Speedment common/pom.xml

<modules> <module>invariant</module> <module>function</module> <module>json</module> <module>tuple</module> <module>logger</module> <module>codegen</module> <module>codegenxml</module> <module>injector</module> <module>rest</module> <module>lazy</module> <module>mapstream</module> <module>mutablestream</module> <module>singletonstream</module> <module>common-all</module> <module>annotation</module> <module>benchmark</module> <module>combinatorics</module> <module>collection</module> </modules>

slide-104
SLIDE 104

Automatic Jigsawing Script Outline

slide-105
SLIDE 105

Automatic Jigsawing Script Outline

  • Create separate directories for the modules
slide-106
SLIDE 106

Automatic Jigsawing Script Outline

  • Create separate directories for the modules
  • Move source code packages to respective modules
slide-107
SLIDE 107

Automatic Jigsawing Script Outline

  • Create separate directories for the modules
  • Move source code packages to respective modules
  • Add empty module-info.java
slide-108
SLIDE 108

Automatic Jigsawing Script Outline

  • Create separate directories for the modules
  • Move source code packages to respective modules
  • Add empty module-info.java
  • Loop:
  • 1. Compile
slide-109
SLIDE 109

Automatic Jigsawing Script Outline

  • Create separate directories for the modules
  • Move source code packages to respective modules
  • Add empty module-info.java
  • Loop:
  • 1. Compile
  • 2. Parse and fix errors
slide-110
SLIDE 110

Automatic Jigsawing Script Outline

  • Create separate directories for the modules
  • Move source code packages to respective modules
  • Add empty module-info.java
  • Loop:
  • 1. Compile
  • 2. Parse and fix errors
  • 3. git add
  • 4. git commit
slide-111
SLIDE 111

Automatic Jigsawing - add requires

slide-112
SLIDE 112

Automatic Jigsawing - add requires

Missing Speedment internal dependency
 \[ERROR\].*\(package (.*) is declared in module (.*), but module com.speedment.(.*)\.(.*) does not read it\) Fix: module com.speedment.X { + requires com.speedment.Y; }

slide-113
SLIDE 113

Automatic Jigsawing - add exports

slide-114
SLIDE 114

Automatic Jigsawing - add exports

Missing Speedment internal visibility
 \[ERROR\].*\(package com.speedment.(.*)\.(.*) is declared in module com.speedment.(.*)\.(.*), which does not export it\) Fix: module com.speedment.Y { + exports com.speedment.X; }

slide-115
SLIDE 115

Automatic Jigsawing - patch (ab)use of JDK API

slide-116
SLIDE 116

Automatic Jigsawing - patch (ab)use of JDK API

Speedment usage of non-public JDK API
 \[ERROR\].*\(package (.*) is declared in module (.*), which does not export it to module com.speedment.(.*)\.(.*)\) Temporary workaround: add exports in the pom file

<artifactId>maven-compiler-plugin</artifactId> + <configuration> + <compilerArgs> + <arg>—add-exports</arg><arg>java.base/sun.nio.ch=com.speedment.… + </compilerArgs> + </configuration>

slide-117
SLIDE 117

Automatic Jigsawing - remove OSGi bundling

slide-118
SLIDE 118

Automatic Jigsawing - remove OSGi bundling

Maven does not currently coexist well with OSGi bundling and Jigsaw


\[ERROR\].*Manifest com\.speedment\.([^:]*)\:([^:]*)\:[^:]*\:.* \: Invalid class file module-info\.class \ (java\.lang\.ArrayIndexOutOfBoundsException\: 19\)

Temporary workaround: comment out the bundling

  • <packaging>bundle</packaging>

+ <packaging>jar</packaging> … <plugins> + <!-- <plugin> <groupId>org.apache.felix</groupId> …

slide-119
SLIDE 119

Speedment Open Source - the Easy Case

slide-120
SLIDE 120

Speedment Open Source - the Easy Case

  • No usage of sun.misc.Unsafe
slide-121
SLIDE 121

Speedment Open Source - the Easy Case

  • No usage of sun.misc.Unsafe
  • No third party dependencies
slide-122
SLIDE 122

Speedment Open Source - the Easy Case

  • No usage of sun.misc.Unsafe
  • No third party dependencies
  • JDK dependencies on module path - no automatic modules
slide-123
SLIDE 123

Speedment Open Source - the Easy Case

  • No usage of sun.misc.Unsafe
  • No third party dependencies
  • JDK dependencies on module path - no automatic modules
  • Automatic script creates workarounds that will need revisiting
slide-124
SLIDE 124

Speedment Open Source - the Easy Case

  • No usage of sun.misc.Unsafe
  • No third party dependencies
  • JDK dependencies on module path - no automatic modules
  • Automatic script creates workarounds that will need revisiting
  • No reflection
slide-125
SLIDE 125

No Reflection in Speedment

slide-126
SLIDE 126

No Reflection in Speedment

  • O/R mapping -> reflection
slide-127
SLIDE 127

No Reflection in Speedment

  • O/R mapping -> reflection
  • instantiate user code

slide-128
SLIDE 128

No Reflection in Speedment

  • O/R mapping -> reflection
  • instantiate user code

  • Code Generation to the Rescue!
slide-129
SLIDE 129

Speedment Enterprise - a Jigsaw Puzzle

slide-130
SLIDE 130

Speedment Enterprise - a Jigsaw Puzzle

Uses sun.misc.Unsafe

slide-131
SLIDE 131

Speedment Enterprise - a Jigsaw Puzzle

Uses sun.misc.Unsafe

  • DirectBuffer.cleaner() - for predictable cleanup
slide-132
SLIDE 132

Speedment Enterprise - a Jigsaw Puzzle

Uses sun.misc.Unsafe

  • DirectBuffer.cleaner() - for predictable cleanup
  • DirectBuffer.address() - for efficient off-heap byte arrays
slide-133
SLIDE 133

Speedment Enterprise - a Jigsaw Puzzle

Uses sun.misc.Unsafe

  • DirectBuffer.cleaner() - for predictable cleanup
  • DirectBuffer.address() - for efficient off-heap byte arrays

Third party dependencies

slide-134
SLIDE 134

Speedment Enterprise - a Jigsaw Puzzle

Uses sun.misc.Unsafe

  • DirectBuffer.cleaner() - for predictable cleanup
  • DirectBuffer.address() - for efficient off-heap byte arrays

Third party dependencies

  • Depends on Third Party JARs
slide-135
SLIDE 135

Speedment Enterprise - a Jigsaw Puzzle

Uses sun.misc.Unsafe

  • DirectBuffer.cleaner() - for predictable cleanup
  • DirectBuffer.address() - for efficient off-heap byte arrays

Third party dependencies

  • Depends on Third Party JARs
  • Automatic modules with split packages
slide-136
SLIDE 136

Awaiting Community Progress

slide-137
SLIDE 137

Awaiting Community Progress

  • OSGi bundles

slide-138
SLIDE 138

Awaiting Community Progress

  • OSGi bundles

  • Third Party Dependencies
slide-139
SLIDE 139

Awaiting Community Progress

  • OSGi bundles

  • Third Party Dependencies
  • Split packages
slide-140
SLIDE 140

Awaiting Community Progress

  • OSGi bundles

  • Third Party Dependencies
  • Split packages
  • Concealed package conflicts
slide-141
SLIDE 141

Awaiting Community Progress

  • OSGi bundles

  • Third Party Dependencies
  • Split packages
  • Concealed package conflicts
  • Duplicate package names

slide-142
SLIDE 142

Awaiting Community Progress

  • OSGi bundles

  • Third Party Dependencies
  • Split packages
  • Concealed package conflicts
  • Duplicate package names

  • Spring Integration

slide-143
SLIDE 143

Awaiting Community Progress

  • OSGi bundles

  • Third Party Dependencies
  • Split packages
  • Concealed package conflicts
  • Duplicate package names

  • Spring Integration

  • Unit test frameworks
slide-144
SLIDE 144

Conclusions

slide-145
SLIDE 145

Conclusions

Lean Principle – "Defer Commitment" or "Decide as late as possible”

slide-146
SLIDE 146

Conclusions

Lean Principle – "Defer Commitment" or "Decide as late as possible” Time well spent:

  • refine application modularity,
slide-147
SLIDE 147

Conclusions

Lean Principle – "Defer Commitment" or "Decide as late as possible” Time well spent:

  • refine application modularity,
  • rework references to non-open parts of the JDK and
slide-148
SLIDE 148

Conclusions

Lean Principle – "Defer Commitment" or "Decide as late as possible” Time well spent:

  • refine application modularity,
  • rework references to non-open parts of the JDK and
  • revisit design decisions regarding Unsafe. 

slide-149
SLIDE 149

Conclusions

Lean Principle – "Defer Commitment" or "Decide as late as possible” Time well spent:

  • refine application modularity,
  • rework references to non-open parts of the JDK and
  • revisit design decisions regarding Unsafe. 


Postpone Decisions (S.E.P.):

  • Working around third party dependencies
slide-150
SLIDE 150

Conclusions

Lean Principle – "Defer Commitment" or "Decide as late as possible” Time well spent:

  • refine application modularity,
  • rework references to non-open parts of the JDK and
  • revisit design decisions regarding Unsafe. 


Postpone Decisions (S.E.P.):

  • Working around third party dependencies
  • Spring Integration
slide-151
SLIDE 151

Conclusions

Lean Principle – "Defer Commitment" or "Decide as late as possible” Time well spent:

  • refine application modularity,
  • rework references to non-open parts of the JDK and
  • revisit design decisions regarding Unsafe. 


Postpone Decisions (S.E.P.):

  • Working around third party dependencies
  • Spring Integration
  • OSGi bundling
slide-152
SLIDE 152

Try Speedment

github.com/speedment/speedment www.speedment.com/initializer/

slide-153
SLIDE 153

Q&A

@speedment @dan_lawesson

slide-154
SLIDE 154

Extra Slides for Q&A

slide-155
SLIDE 155

Many-to-Many

Map<Human, List<Hare>> humanFriends = friends.stream() .collect( groupingBy(humans.finderBy(Friend.HUMAN), // Classifier mapping( hares.finderBy(Friend.HARE), //Friend to Hare finder toList() // Downstream aggregation w. List collector ) ) );

slide-156
SLIDE 156

Many-to-Many

Map<Human, List<Hare>> humanFriends = friends.stream() .collect( groupingBy(humans.finderBy(Friend.HUMAN), // Classifier mapping( hares.finderBy(Friend.HARE), //Friend to Hare finder toList() // Downstream aggregation w. List collector ) ) );

Standard Java 8

slide-157
SLIDE 157

Update

hares.stream() .filter(Hare.ID.equal(42)) // All Hares with ID = 42 (just one) .map(Hare.AGE.setTo(10)) // Applies a setter .forEach(hares.updater()); // Applies the updater function

slide-158
SLIDE 158

Update

hares.stream() .filter(Hare.ID.equal(42)) // All Hares with ID = 42 (just one) .map(Hare.AGE.setTo(10)) // Applies a setter .forEach(hares.updater()); // Applies the updater function

Standard Java 8

slide-159
SLIDE 159

Database Connectors

slide-160
SLIDE 160

Beyond Open-Source

  • Speedment Enterprise
  • Run your database queries orders of magnitude faster!
  • 10x, 100x, 1 000x, 10 000x, …
  • Use the same Stream API
slide-161
SLIDE 161

How is This Possible?

  • No changes to user-written code
  • Alternative stream source
  • Data is stored in-memory
  • Generates optimized serializers 


for off-heap storage

slide-162
SLIDE 162

In-JVM-Memory, JMH Benchmarks(*)

Benchmark Mode Cnt Score Error Units SpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/op SpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/op SpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/op SpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op (*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns.

slide-163
SLIDE 163

In-JVM-Memory, JMH Benchmarks(*)

Benchmark Mode Cnt Score Error Units SpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/op SpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/op SpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/op SpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op (*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns. 10x

slide-164
SLIDE 164

In-JVM-Memory, JMH Benchmarks(*)

Benchmark Mode Cnt Score Error Units SpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/op SpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/op SpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/op SpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op (*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns. 10x >10x

slide-165
SLIDE 165

In-JVM-Memory, JMH Benchmarks(*)

Benchmark Mode Cnt Score Error Units SpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/op SpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/op SpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/op SpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op (*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns. 10x >10x 100x

slide-166
SLIDE 166

In-JVM-Memory, JMH Benchmarks(*)

Benchmark Mode Cnt Score Error Units SpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/op SpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/op SpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/op SpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op (*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns. 10x >10x 100x 2,000,000x

slide-167
SLIDE 167

In-JVM-Memory, JMH Benchmarks(*)

Benchmark Mode Cnt Score Error Units SpeedmentBenchmark.findStartsWith avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.findStartsWithSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.join avgt 200 0.476 ± 0.005 s/op SpeedmentBenchmark.joinSql avgt 200 5.174 ± 0.010 s/op SpeedmentBenchmark.sort avgt 200 ≈ 10⁻⁶ s/op SpeedmentBenchmark.sortSql avgt 200 ≈ 10⁻⁴ s/op SpeedmentBenchmark.scrollSorted avgt 200 ≈ 10⁻⁵ s/op SpeedmentBenchmark.scrollSortedSql avgt 200 24.661 ± 0.670 s/op SpeedmentBenchmark.count avgt 180 ≈ 10⁻⁸ s/op SpeedmentBenchmark.countSql avgt 200 5.143 ± 0.012 s/op (*) Preliminary results, Mac Book Pro, 2.2 GHz i7, 16GB, MySQL 5.7.16 standard with indexes on all relevant columns. 10x >10x 100x 2,000,000x 500,000,000x

slide-168
SLIDE 168

Gitkraken view of Jigsawing Script Commits

slide-169
SLIDE 169

Gitkraken view of Jigsawing Script Commits