Slide 1

Slide 1 text

Holly Cummins @holly_cummins Georgios Andrianakis @geoand86 Red Hat Why you're missing out if you're not making Quarkus extensions

Slide 2

Slide 2 text

@holly_cummins @geoand86 #Quarkus #RedHat Hi Georgios!

Slide 3

Slide 3 text

@holly_cummins @geoand86 #Quarkus #RedHat extenwhats?

Slide 4

Slide 4 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core

Slide 5

Slide 5 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core JAX-RS

Slide 6

Slide 6 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS

Slide 7

Slide 7 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty

Slide 8

Slide 8 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT

Slide 9

Slide 9 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT Elasticsearch

Slide 10

Slide 10 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT Elasticsearch Apache Camel

Slide 11

Slide 11 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Apache Camel

Slide 12

Slide 12 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Apache Camel …

Slide 13

Slide 13 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Apache Camel …

Slide 14

Slide 14 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Netty extension Apache Camel …

Slide 15

Slide 15 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Netty extension Apache Camel …

Slide 16

Slide 16 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Netty extension JAX-RS extension Apache Camel …

Slide 17

Slide 17 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Netty extension JAX-RS extension Apache Camel …

Slide 18

Slide 18 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Netty extension JAX-RS extension Elasticsearch extension Apache Camel …

Slide 19

Slide 19 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Netty extension JAX-RS extension Elasticsearch extension Apache Camel …

Slide 20

Slide 20 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Netty extension JAX-RS extension Elasticsearch extension Hibernate extension Apache Camel …

Slide 21

Slide 21 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Netty extension JAX-RS extension Elasticsearch extension Hibernate extension Apache Camel …

Slide 22

Slide 22 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Netty extension JAX-RS extension Elasticsearch extension Hibernate extension Apache Camel Camel extension …

Slide 23

Slide 23 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch Netty extension JAX-RS extension Elasticsearch extension Hibernate extension Apache Camel Camel extension …

Slide 24

Slide 24 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch JWT extension Netty extension JAX-RS extension Elasticsearch extension Hibernate extension Apache Camel Camel extension …

Slide 25

Slide 25 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch JWT extension Netty extension JAX-RS extension Elasticsearch extension Hibernate extension Apache Camel Camel extension …

Slide 26

Slide 26 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch gRPC extension JWT extension Netty extension JAX-RS extension Elasticsearch extension Hibernate extension Apache Camel Camel extension …

Slide 27

Slide 27 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch gRPC extension JWT extension Netty extension JAX-RS extension Elasticsearch extension Hibernate extension Apache Camel Camel extension …

Slide 28

Slide 28 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch gRPC extension JWT extension Netty extension JAX-RS extension Elasticsearch extension Hibernate extension lots more extensions Apache Camel Camel extension …

Slide 29

Slide 29 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus core Hibernate JAX-RS Netty JWT gRPC Elasticsearch gRPC extension JWT extension Netty extension JAX-RS extension Elasticsearch extension Hibernate extension lots more extensions Apache Camel Camel extension … quarkiverse

Slide 30

Slide 30 text

@holly_cummins @geoand86 #Quarkus #RedHat why?

Slide 31

Slide 31 text

@holly_cummins @geoand86 #Quarkus #RedHat reminder: what makes quarkus special

Slide 32

Slide 32 text

traditional way vs quarkus way @ 
 @ > build time runtime

Slide 33

Slide 33 text

@ 
 @ > traditional way vs quarkus way @ 
 @ > build time runtime build time

Slide 34

Slide 34 text

@ 
 @ > traditional way vs quarkus way @ 
 @ > build time runtime runtime build time

Slide 35

Slide 35 text

the quarkus way enables native compilation native @ 
 @ > JVM build time

Slide 36

Slide 36 text

9 but … for a normal framework …

Slide 37

Slide 37 text

9 they load way too many classes but … for a normal framework …

Slide 38

Slide 38 text

9 they load way too many classes they are way too dynamic but … for a normal framework …

Slide 39

Slide 39 text

9 they load way too many classes they are way too dynamic (which means they use way too much reflection) but … for a normal framework …

Slide 40

Slide 40 text

9 they load way too many classes they are way too dynamic (which means they use way too much reflection) they perform a lot of initialization at runtime but … for a normal framework …

Slide 41

Slide 41 text

@ 
 @ > Packaging 
 (maven, gradle…) build time runtime how does a framework start?

Slide 42

Slide 42 text

@ 
 @ > Load and parse config files, properties, yaml, xml, etc. build time runtime how does a framework start?

Slide 43

Slide 43 text

@ 
 @ > Classpath scanning and annotation discovery Attempt to load class to enable/disable features build time runtime how does a framework start?

Slide 44

Slide 44 text

@ 
 @ > Build its metamodel of the world. build time runtime how does a framework start?

Slide 45

Slide 45 text

@ 
 @ > Start thread pools, IO, etc. build time runtime how does a framework start?

Slide 46

Slide 46 text

Do the work once, not at each start Get rid of all bootstrap classes Less time to start, less memory needed Less or no reflection nor dynamic proxies what if we initialize at build time?

Slide 47

Slide 47 text

@ 
 @ > build time Do the work once, not at each start Get rid of all bootstrap classes Less time to start, less memory needed Less or no reflection nor dynamic proxies what if we initialize at build time?

Slide 48

Slide 48 text

@ 
 @ > runtime build time Do the work once, not at each start Get rid of all bootstrap classes Less time to start, less memory needed Less or no reflection nor dynamic proxies what if we initialize at build time?

Slide 49

Slide 49 text

and another thing

Slide 50

Slide 50 text

and another thing

Slide 51

Slide 51 text

and another thing developer experience

Slide 52

Slide 52 text

and another thing developer experience developer joy

Slide 53

Slide 53 text

“while we’re manipulating the bytecode to support native, why don’t we make coding … easier?” [warning: may not actually be Quarkus origin story]

Slide 54

Slide 54 text

automagic dev instances (“dev services”) unified config opinionated shortcuts joy comes in several forms:

Slide 55

Slide 55 text

@holly_cummins @geoand86 #Quarkus #RedHat persistence.xml hibernate extension

Slide 56

Slide 56 text

@holly_cummins @geoand86 #Quarkus #RedHat persistence.xml hibernate extension the hibernate extension makes this go away

Slide 57

Slide 57 text

@holly_cummins @geoand86 #Quarkus #RedHat

Slide 58

Slide 58 text

@holly_cummins @geoand86 #Quarkus #RedHat dynamic-but-static

Slide 59

Slide 59 text

@holly_cummins @geoand86 #Quarkus #RedHat dynamic-but-static “wouldn’t it be nice if … 
 … but it’s too expensive to do it at runtime.”

Slide 60

Slide 60 text

@holly_cummins @geoand86 #Quarkus #RedHat public class CassandraConnector { private Cluster cluster; private Session session; public void connect(String node, Integer port) { Builder b = Cluster.builder().addContactPoint(node); if (port != null) { b.withPort(port); } cluster = b.build(); session = cluster.connect(); } public Session getSession() { return this.session; } public void close() { session.close(); cluster.close(); } }

Slide 61

Slide 61 text

@holly_cummins @geoand86 #Quarkus #RedHat public class CassandraConnector { private Cluster cluster; private Session session; public void connect(String node, Integer port) { Builder b = Cluster.builder().addContactPoint(node); if (port != null) { b.withPort(port); } cluster = b.build(); session = cluster.connect(); } public Session getSession() { return this.session; } public void close() { session.close(); cluster.close(); } } @Inject private QuarkusCqlSession session;

Slide 62

Slide 62 text

@holly_cummins @geoand86 #Quarkus #RedHat “opinionated choices and educated guesses.”

Slide 63

Slide 63 text

@holly_cummins @geoand86 #Quarkus #RedHat recap: why extensions? • good behaviour in native mode • fast behaviour in normal mode (pre-do all the things) • good dev experience

Slide 64

Slide 64 text

@geoand86 @holly_cummins #Quarkus #RedHat

Slide 65

Slide 65 text

@geoand86 @holly_cummins #Quarkus #RedHat

Slide 66

Slide 66 text

@geoand86 @holly_cummins #Quarkus #RedHat

Slide 67

Slide 67 text

@geoand86 @holly_cummins #Quarkus #RedHat

Slide 68

Slide 68 text

@holly_cummins @geoand86 #Quarkus #RedHat why write a new extension? • the community hasn’t written one yet • it’s your library • support a use case particular to your environment

Slide 69

Slide 69 text

@holly_cummins @geoand86 #Quarkus #RedHat “hook a build step?”

Slide 70

Slide 70 text

@holly_cummins @geoand86 #Quarkus #RedHat “hook a build step?”

Slide 71

Slide 71 text

@holly_cummins @geoand86 #Quarkus #RedHat “hook a build step?”

Slide 72

Slide 72 text

@holly_cummins @geoand86 #Quarkus #RedHat how?

Slide 73

Slide 73 text

@holly_cummins @geoand86 #Quarkus #RedHat extension concept deployment + runtime

Slide 74

Slide 74 text

@holly_cummins @geoand86 #Quarkus #RedHat extension concept build phase + startup phase

Slide 75

Slide 75 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus

Slide 76

Slide 76 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment

Slide 77

Slide 77 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime

Slide 78

Slide 78 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime

Slide 79

Slide 79 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime bytecode

Slide 80

Slide 80 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime bytecode extension

Slide 81

Slide 81 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime bytecode extension deployment

Slide 82

Slide 82 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime bytecode extension deployment runtime

Slide 83

Slide 83 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime bytecode extension deployment runtime

Slide 84

Slide 84 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime bytecode extension deployment runtime

Slide 85

Slide 85 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime bytecode extension deployment runtime bytecode

Slide 86

Slide 86 text

@holly_cummins @geoand86 #Quarkus #RedHat deployment

Slide 87

Slide 87 text

@holly_cummins @geoand86 #Quarkus #RedHat understand app deployment

Slide 88

Slide 88 text

@holly_cummins @geoand86 #Quarkus #RedHat understand app convert annotations to bytecode deployment

Slide 89

Slide 89 text

@holly_cummins @geoand86 #Quarkus #RedHat understand app convert annotations to bytecode optimize deployment

Slide 90

Slide 90 text

@holly_cummins @geoand86 #Quarkus #RedHat extension concept build steps + build items

Slide 91

Slide 91 text

@holly_cummins @geoand86 #Quarkus #RedHat

Slide 92

Slide 92 text

@holly_cummins @geoand86 #Quarkus #RedHat build steps

Slide 93

Slide 93 text

@holly_cummins @geoand86 #Quarkus #RedHat

Slide 94

Slide 94 text

@holly_cummins @geoand86 #Quarkus #RedHat build items

Slide 95

Slide 95 text

@holly_cummins @geoand86 #Quarkus #RedHat

Slide 96

Slide 96 text

@holly_cummins @geoand86 #Quarkus #RedHat framework automatically determines correct execution order and injects parameters

Slide 97

Slide 97 text

@holly_cummins @geoand86 #Quarkus #RedHat build items are communication mechanism between build steps framework automatically determines correct execution order and injects parameters

Slide 98

Slide 98 text

@holly_cummins @geoand86 #Quarkus #RedHat initial state build items intermediate state build items terminal state build items

Slide 99

Slide 99 text

@holly_cummins @geoand86 #Quarkus #RedHat initial state build items JarResultBuildStep intermediate state build items terminal state build items

Slide 100

Slide 100 text

@holly_cummins @geoand86 #Quarkus #RedHat initial state build items JarResultBuildStep GeneratedResourceBuildItem intermediate state build items terminal state build items

Slide 101

Slide 101 text

@holly_cummins @geoand86 #Quarkus #RedHat initial state build items JarResultBuildStep GeneratedResourceBuildItem ConfigClassBuildItem intermediate state build items terminal state build items

Slide 102

Slide 102 text

@holly_cummins @geoand86 #Quarkus #RedHat initial state build items JarResultBuildStep GeneratedResourceBuildItem ConfigClassBuildItem UnremovableBeanBuildItem intermediate state build items terminal state build items

Slide 103

Slide 103 text

@holly_cummins @geoand86 #Quarkus #RedHat initial state build items JarResultBuildStep GeneratedResourceBuildItem ConfigClassBuildItem UnremovableBeanBuildItem BuildSystemTargetBuildItem intermediate state build items terminal state build items

Slide 104

Slide 104 text

@holly_cummins @geoand86 #Quarkus #RedHat initial state build items JarResultBuildStep GeneratedResourceBuildItem ConfigClassBuildItem UnremovableBeanBuildItem BuildSystemTargetBuildItem LaunchModeBuildItem intermediate state build items terminal state build items

Slide 105

Slide 105 text

@holly_cummins @geoand86 #Quarkus #RedHat initial state build items JarResultBuildStep GeneratedResourceBuildItem ConfigClassBuildItem UnremovableBeanBuildItem BuildSystemTargetBuildItem LaunchModeBuildItem most extensions do stuff here intermediate state build items terminal state build items

Slide 106

Slide 106 text

@holly_cummins @geoand86 #Quarkus #RedHat what kind of things can build items do? Create a servlet Create a route Pull an external bean into the closed world Turn one annotation into another Add a log handler Read an extra application archive Flag a capability as present Interact with Kubernetes …

Slide 107

Slide 107 text

@holly_cummins @geoand86 #Quarkus #RedHat existing build items cover almost all needs like a library for extension writers

Slide 108

Slide 108 text

@holly_cummins @geoand86 #Quarkus #RedHat

Slide 109

Slide 109 text

@holly_cummins @geoand86 #Quarkus #RedHat extension concept index

Slide 110

Slide 110 text

@holly_cummins @geoand86 #Quarkus #RedHat extension concept index

Slide 111

Slide 111 text

@holly_cummins @geoand86 #Quarkus #RedHat extension concept index eliminates need for runtime classpath scanning

Slide 112

Slide 112 text

@holly_cummins @geoand86 #Quarkus #RedHat extension concept index “jandex” eliminates need for runtime classpath scanning

Slide 113

Slide 113 text

@holly_cummins @geoand86 #Quarkus #RedHat open world closed world

Slide 114

Slide 114 text

@holly_cummins @geoand86 #Quarkus #RedHat open world closed world hard to build-time optimise

Slide 115

Slide 115 text

@holly_cummins @geoand86 #Quarkus #RedHat open world closed world hard to build-time optimise easy to build-time optimise

Slide 116

Slide 116 text

@holly_cummins @geoand86 #Quarkus #RedHat open world closed world hard to build-time optimise easy to build-time optimise runtime class surprise!

Slide 117

Slide 117 text

@holly_cummins @geoand86 #Quarkus #RedHat open world closed world hard to build-time optimise easy to build-time optimise runtime class surprise!

Slide 118

Slide 118 text

@holly_cummins @geoand86 #Quarkus #RedHat open world closed world hard to build-time optimise easy to build-time optimise no worries runtime class surprise!

Slide 119

Slide 119 text

@holly_cummins @geoand86 #Quarkus #RedHat open world closed world hard to build-time optimise easy to build-time optimise no worries runtime class surprise!

Slide 120

Slide 120 text

@holly_cummins @geoand86 #Quarkus #RedHat open world closed world hard to build-time optimise easy to build-time optimise uh oh, this is outside our closed world no worries runtime class surprise!

Slide 121

Slide 121 text

@holly_cummins @geoand86 #Quarkus #RedHat AdditionalBeanBuildItem

Slide 122

Slide 122 text

@holly_cummins @geoand86 #Quarkus #RedHat AdditionalBeanBuildItem

Slide 123

Slide 123 text

@holly_cummins @geoand86 #Quarkus #RedHat extension concept bytecode recording easier than writing ASM (if recording isn’t optimised enough, use Gizmo to hand-craft bytecode)

Slide 124

Slide 124 text

Example @Recorder public class CaffeineCacheBuildRecorder { // a proxy of this is invoked at build time // the “real” invocation happens at runtime with the CaffeineCacheInfo obtained at build time public Supplier getCacheManagerSupplier(Set cacheInfos) { return new Supplier() { @Override public CacheManager get() { if (cacheInfos.isEmpty()) { return new CacheManagerImpl(Collections.emptyMap()); } else { Map caches = new HashMap<>(cacheInfos.size() + 1, 1.0F); for (CaffeineCacheInfo cacheInfo : cacheInfos) { CaffeineCache cache = new CaffeineCache(cacheInfo); caches.put(cacheInfo.name, cache); } return new CacheManagerImpl(caches); } } }; } }

Slide 125

Slide 125 text

@holly_cummins @geoand86 #Quarkus #RedHat extension concept configuration

Slide 126

Slide 126 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus

Slide 127

Slide 127 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment

Slide 128

Slide 128 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime

Slide 129

Slide 129 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime extension

Slide 130

Slide 130 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime extension deployment

Slide 131

Slide 131 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime extension deployment runtime

Slide 132

Slide 132 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime extension deployment runtime config config

Slide 133

Slide 133 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime extension deployment runtime config config config config

Slide 134

Slide 134 text

@holly_cummins @geoand86 #Quarkus #RedHat Quarkus deployment runtime extension deployment runtime config config config config

Slide 135

Slide 135 text

@holly_cummins @geoand86 #Quarkus #RedHat demo

Slide 136

Slide 136 text

@holly_cummins @geoand86 #Quarkus #RedHat demo: recap

Slide 137

Slide 137 text

@holly_cummins @geoand86 #Quarkus #RedHat https://github.com/holly-cummins/quarkus-minecraft-observability-extension

Slide 138

Slide 138 text

@holly_cummins @geoand86 #Quarkus #RedHat

Slide 139

Slide 139 text

@holly_cummins @geoand86 #Quarkus #RedHat

Slide 140

Slide 140 text

@holly_cummins @geoand86 #Quarkus #RedHat

Slide 141

Slide 141 text

@holly_cummins @geoand86 #Quarkus #RedHat https://github.com/holly-cummins/ quarkus-minecraft-observability-extension

Slide 142

Slide 142 text

@holly_cummins @geoand86 #Quarkus #RedHat extension concept GraalVM ● Contribute GraalVM configuration ○ Reflection registration ○ Dynamic proxy registration ○ Resource files ○ Message bundles ○ Etc. 
 ● Provide substitutions ○ Pieces of code that are used in place of regular library code when in native mode

Slide 143

Slide 143 text

Substitutions @TargetClass(org.infinispan.client.hotrod.impl.RemoteCacheImpl.class) public final class SubstituteRemoteCacheImpl { @Delete private ObjectName mbeanObjectName; @Substitute private void registerMBean(ObjectName jmxParent) { } @Substitute private void unregisterMBean() { } @Delete public void init(OperationsFactory operationsFactory, Configuration configuration, ObjectName jmxParent) { } }

Slide 144

Slide 144 text

Real world examples ● Jackson extension 
 ● Hibernate Validator extension 
 ● Spring DI extension 
 
 Resources ● http:/ /quarkus.io ● https:/ /quarkus.io/guides/all-builditems ● https:/ /quarkus.io/blog/quarkus-aws-cloudwatch_extension/ ● https:/ /quarkus.io/blog/solving-problems-with-custom-extensions/

Slide 145

Slide 145 text

® thank you @holly_cummins @geoand86 https://github.com/holly- cummins/quarkus-minecraft- observability-extension code