SlideShare a Scribd company logo
1 of 39
Download to read offline
How and why I turned my old
Java projects into a first-class
serverless component
by Mario Fusco
Red Hat – Principal Software Engineer
@mariofusco
c
Agenda
➢
Declarative vs. Imperative programming
➢
What is a rule engine and how it works
➢
A simple example
➢
From drl to Java: the executable model
Agenda
➢
Declarative vs. Imperative programming
➢
What is a rule engine and how it works
➢
A simple example
➢
From drl to Java: the executable model
➢
What is GraalVM
➢
AoT compilation
➢
Limitations
➢
Refactoring Drools to (natively) compile on GraalVM
Agenda
c
➢
Declarative vs. Imperative programming
➢
What is a rule engine and how it works
➢
A simple example
➢
From drl to Java: the executable model
➢
What is GraalVM
➢
AoT compilation
➢
Limitations
➢
Refactoring Drools to (natively) compile on GraalVM
➢
What is Quarkus
➢
Quarkus features
➢
Integrating Drools with Quarkus
➢
Writing a Quarkus extension for Drools
What a rule-based program is
➢
A rule-based program is made up of discrete rules, each of which applies to a subset of the problem
➢
It is simpler, because you can concentrate on the rules for one situation at a time
➢
It can be more flexible in the face of fragmentary or poorly conditioned inputs
➢
Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in
short, all problems without clear algorithmic solutions
What a rule-based program is
➢
A rule-based program is made up of discrete rules, each of which applies to a subset of the problem
➢
It is simpler, because you can concentrate on the rules for one situation at a time
➢
It can be more flexible in the face of fragmentary or poorly conditioned inputs
➢
Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in
short, all problems without clear algorithmic solutions
Declarative
(What to do)
Imperative
(How to do it) Vs.
public void helloMark(Person person) {
if ( person.getName().equals( “Mark” ) {
System.out.println( “Hello Mark” );
}
}
rule “Hello Mark”
when
Person( name == “Mark” )
then
System.out.println( “Hello Mark” );
end
What a rule-based program is
➢
A rule-based program is made up of discrete rules, each of which applies to a subset of the problem
➢
It is simpler, because you can concentrate on the rules for one situation at a time
➢
It can be more flexible in the face of fragmentary or poorly conditioned inputs
➢
Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in
short, all problems without clear algorithmic solutions
Declarative
(What to do)
Imperative
(How to do it) Vs.
public void helloMark(Person person) {
if ( person.getName().equals( “Mark” ) {
System.out.println( “Hello Mark” );
}
}
rule “Hello Mark”
when
Person( name == “Mark” )
then
System.out.println( “Hello Mark” );
end
A method must
be called directly
Rules can never
be called directly
What a rule-based program is
➢
A rule-based program is made up of discrete rules, each of which applies to a subset of the problem
➢
It is simpler, because you can concentrate on the rules for one situation at a time
➢
It can be more flexible in the face of fragmentary or poorly conditioned inputs
➢
Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in
short, all problems without clear algorithmic solutions
Declarative
(What to do)
Imperative
(How to do it) Vs.
public void helloMark(Person person) {
if ( person.getName().equals( “Mark” ) {
System.out.println( “Hello Mark” );
}
}
rule “Hello Mark”
when
Person( name == “Mark” )
then
System.out.println( “Hello Mark” );
end
A method must
be called directly
Specific passing
of arguments
Rules can never
be called directly
Specific instances cannot
be passed but are
automatically selected
with pattern-matching
Introducing
➢
Easier to understand → Requirements can be more naturally translated into
rules. It is more likely for a technically skilled business analyst to verify, validate
or even change a rule than a piece of Java code
➢
Improved maintainability → We don't care about how to implement a solution
only what needs to be done to solve a problem
➢
Deals with evolving complexity → It's easier to modify a rule than a Java
program and to determine the impact of this change on the rest of the application
➢
Modularity → Each rule models an isolated and small portion of your business
logic and is not part of a monolithic program
➢
Clear separation of business logic from the rest of the system → Business
and infrastructural code have very different lifecycles
➢
Complex Event Processing → Facts can be handled like timestamped events
allowing temporal reasoning on them
RULES
How a rule-based system works
➢
The Rule Base contains a computation efficient
representation of the set of the defined rules
➢
The Working Memory contains the set of facts
inserted into sessions
➢
The engine matches the fact in the working
memory against the rules set
➢
When a match is found it creates an activation
and put it into the agenda
➢
An activation is the tuple of facts matching the
conditions of a rule plus the rule itself
➢
When all activations have been created the
agenda elects through a conflict resolution
strategy the one to be executed
➢
The elected activation is passed to the execution
engine and the fired
A simple rule set
rule RaiseAlarm when
exists Fire()
then
insert( new Alarm( "house1" ) );
System.out.println( "Raise the Alarm");
end
rule CancelAlarm when
not Fire()
a : Alarm()
then
delete( a );
System.out.println( "Cancel the Alarm");
end
rule TurnSprinklerOn when
s : Sprinkler( on == false )
f : Fire( room == s.room )
then
modify( s ) { setOn( true ) }
System.out.println( "Turn on the sprinkler for room " +
f.getRoom().getName() );
end
rule TurnSprinklerOff when
s : Sprinkler( on == true )
not Fire( room == s.room )
then
modify( s ) { setOn( false ) }
System.out.println( "Turn off the sprinkler for room " +
s.getRoom().getName() );
end
rule OK when
not Alarm()
not Sprinkler( on == true )
then
System.out.println( "Everything is ok" );
end
Pattern-matching
against objects in the
Working Memory
Code executed when
a match is found
What is
used by Quarkus
➢
A polyglot VM with cross-language JIT
supporting
●
Java Bytecode and JVM languages
●
Interop with different languages
●
Dynamic languages through Truffle API
➢
Cross-language interop out of the box
●
Simple AST-based interpreter
●
JIT across language boundaries
➢
Support for native binary compilation
(SubstrateVM)
●
faster boot-up
●
lower memory footprint
AoT compilation with GraalVM
➢
Static analysis
➢
Closed world assumption
➢
Dead code elimination:
     classes, fields, methods, branches
AoT compilation with GraalVM
➢
Static analysis
➢
Closed world assumption
➢
Dead code elimination:
     classes, fields, methods, branches
🚀 Fast process start
🔬 Less memory
💾 Small size on disk
GraalVM Limitations
Dynaminc Classloading
Deloying jars, wars, etc. at runtime impossible
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
return defineClass( name, bytecode, 0, bytecode.length );
}
}
GraalVM Limitations
Dynaminc Classloading
Deloying jars, wars, etc. at runtime impossible
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
return defineClass( name, bytecode, 0, bytecode.length );
}
}
GraalVM Limitations
Dynaminc Classloading
Deloying jars, wars, etc. at runtime impossible
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
return defineClass( name, bytecode, 0, bytecode.length );
}
}
JVMTI, JMX + other
native VM interfaces
No agents → No JRebel, Byteman, profilers, tracers
Miscellaneous
➢
Security Manager
➢ finalize() (depreceated anyway)
➢ InvokeDynamic and MethodHandle
GraalVM Limitations
Dynaminc Classloading
Deloying jars, wars, etc. at runtime impossible
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
return defineClass( name, bytecode, 0, bytecode.length );
}
}
JVMTI, JMX + other
native VM interfaces
No agents → No JRebel, Byteman, profilers, tracers
Miscellaneous
➢
Security Manager
➢ finalize() (depreceated anyway)
➢ InvokeDynamic and MethodHandle
GraalVM Limitations
Dynaminc Classloading
Deloying jars, wars, etc. at runtime impossible
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
return defineClass( name, bytecode, 0, bytecode.length );
}
}
JVMTI, JMX + other
native VM interfaces
No agents → No JRebel, Byteman, profilers, tracers
Miscellaneous
➢
Security Manager
➢ finalize() (depreceated anyway)
➢ InvokeDynamic and MethodHandle
Reflection
Requires registration (closed world assumption)
GraalVM Limitations
Dynaminc Classloading
Deloying jars, wars, etc. at runtime impossible
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
return defineClass( name, bytecode, 0, bytecode.length );
}
}
JVMTI, JMX + other
native VM interfaces
No agents → No JRebel, Byteman, profilers, tracers
Miscellaneous
➢
Security Manager
➢ finalize() (depreceated anyway)
➢ InvokeDynamic and MethodHandle
[
{
"name" : "org.domain.model.Person",
"allPublicConstructors" : true,
"allPublicMethods" : true
}
]
Reflection
Requires registration (closed world assumption)
-H:ReflectionConfigurationFiles=src/main/resources/reflection.json
Drools on GraalVM - Executable Model
rule "Older than Mark" when
$p1: Person( name == "Mark" )
$p2: Person( name != "Mark", age > $p1.age )
then
System.out.println( $p1.getName() +
" is older than " + $p2.getName() );
end
Variable<Person> markV = declarationOf( Person.class );
Variable<Person> olderV = declarationOf( Person.class );
Rule rule = rule( "Older than Mark" )
.build(
pattern(markV)
.expr("exprA", p -> p.getName().equals( "Mark" ),
alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ),
reactOn( "name", "age" )),
pattern(olderV)
.expr("exprB", p -> !p.getName().equals("Mark"),
alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ),
reactOn( "name" ))
.expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(),
betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ),
reactOn( "age" )),
on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() ))
)
Drools on GraalVM - Executable Model
rule "Older than Mark" when
$p1: Person( name == "Mark" )
$p2: Person( name != "Mark", age > $p1.age )
then
System.out.println( $p1.getName() +
" is older than " + $p2.getName() );
end
Variable<Person> markV = declarationOf( Person.class );
Variable<Person> olderV = declarationOf( Person.class );
Rule rule = rule( "Older than Mark" )
.build(
pattern(markV)
.expr("exprA", p -> p.getName().equals( "Mark" ),
alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ),
reactOn( "name", "age" )),
pattern(olderV)
.expr("exprB", p -> !p.getName().equals("Mark"),
alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ),
reactOn( "name" ))
.expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(),
betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ),
reactOn( "age" )),
on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() ))
)
Drools on GraalVM - Executable Model
rule "Older than Mark" when
$p1: Person( name == "Mark" )
$p2: Person( name != "Mark", age > $p1.age )
then
System.out.println( $p1.getName() +
" is older than " + $p2.getName() );
end
Variable<Person> markV = declarationOf( Person.class );
Variable<Person> olderV = declarationOf( Person.class );
Rule rule = rule( "Older than Mark" )
.build(
pattern(markV)
.expr("exprA", p -> p.getName().equals( "Mark" ),
alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ),
reactOn( "name", "age" )),
pattern(olderV)
.expr("exprB", p -> !p.getName().equals("Mark"),
alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ),
reactOn( "name" ))
.expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(),
betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ),
reactOn( "age" )),
on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() ))
)
Executable
model
Indexes and
reactivity
explicitly defined
Executable Model at a glance
➢
A pure Java DSL for Drools rules authoring
➢
A pure Java canonical representation of a rule base
➢
Automatically generated by Maven plugin or
Quarkus extension
●
Can be embedded in jar
●
Faster boot
➢
Improve Backward/Forward compatibility
➢
Allow for faster prototyping and experimentation of
new features
➢
Prerequisite to make Drools natively compilable on
GraalVM
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
throw new UnsupportedOperationException();
}
}
Drools on GraalVM – other refactors
Dynamic class definition
is no longer necessary
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
throw new UnsupportedOperationException();
}
}
Drools on GraalVM – other refactors
Dynamic class definition
is no longer necessary
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
<kbase name="simpleKB"
packages="org.drools.simple.project">
<ksession name="simpleKS" default="true"/>
</kbase>
</kmodule>
var m = KieServices.get().newKieModuleModel();
var kb = m.newKieBaseModel("simpleKB");
kb.setEventProcessingMode(CLOUD);
kb.addPackage("org.drools.simple.project");
var ks = kb.newKieSessionModel("simpleKS");
ks.setDefault(true);
ks.setType(STATEFUL);
ks.setClockType(ClockTypeOption.get("realtime"));
public class InternalClassLoader extends ClassLoader {
public Class<?> defineClass( String name, byte[] bytecode ) {
throw new UnsupportedOperationException();
}
}
Drools on GraalVM – other refactors
Dynamic class definition
is no longer necessary
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
<kbase name="simpleKB"
packages="org.drools.simple.project">
<ksession name="simpleKS" default="true"/>
</kbase>
</kmodule>
var m = KieServices.get().newKieModuleModel();
var kb = m.newKieBaseModel("simpleKB");
kb.setEventProcessingMode(CLOUD);
kb.addPackage("org.drools.simple.project");
var ks = kb.newKieSessionModel("simpleKS");
ks.setDefault(true);
ks.setType(STATEFUL);
ks.setClockType(ClockTypeOption.get("realtime"));
org.kie.api.io.KieResources =
org.drools.core.io.impl.ResourceFactoryServiceImpl
org.kie.api.marshalling.KieMarshallers =
org.drools.core.marshalling.MarshallerProviderImpl
org.kie.api.concurrent.KieExecutors =
org.drools.core.concurrent.ExecutorProviderImpl
Map<Class<?>, Object> serviceMap = new HashMap<>();
void wireServices() {
serviceMap.put( ServiceInterface.class,
Class.forName("org.drools.ServiceImpl")
.newInstance());
// … more services here
}
Demo 1
Drools on GraalVM
Introducing
➢
A Framework for writing (fast and
lightweight) Java applications
Introducing
➢
A Framework for writing (fast and
lightweight) Java applications
➢
(Optionally) allowing generation
of native executable via GraalVM
*.class
QUARKUS
optimized jar
native
executable
JVM
Maven/Gradle plugin
Introducing
➢
A Framework for writing (fast and
lightweight) Java applications
➢
(Optionally) allowing generation
of native executable via GraalVM
➢
Based on existing standard
●
Servlet
●
JAX-RS
●
JPA, JDBC
●
CDI
●
Bean Validation
●
Transactions
●
Logging
●
Microprofile
*.class
QUARKUS
optimized jar
native
executable
JVM
Maven/Gradle plugin
Introducing
➢
A Framework for writing (fast and
lightweight) Java applications
➢
(Optionally) allowing generation
of native executable via GraalVM
➢
Based on existing standard
●
Servlet
●
JAX-RS
●
JPA, JDBC
●
CDI
●
Bean Validation
●
Transactions
●
Logging
●
Microprofile
➢
Out-of-the-box integration with
libraries that you already know
*.class
QUARKUS
optimized jar
native
executable
JVM
Maven/Gradle plugin
Why Quarkus
Lower
memory
usage
Faster
startup
Optimized for
short-lived
processes
Kubernetes
Native
Live
reload
Microservices
Why Quarkus
Lower
memory
usage
Faster
startup
Optimized for
short-lived
processes
Kubernetes
Native
Live
reload
Microservices
Fast, lightweight Drools = Submarine
The question of whether a
computer can think is no
more interesting than the
question of whether a
submarine can swim
- Edsger W. Dijkstra
Integrating Quarkus and Drools
Writing a Quarkus extension
public class ExecutableModelGenerator {
private static final String PRODUCER_SOURCE = "package io.quarkus.drools.runtime;n" +
"import org.drools.modelcompiler.KieRuntimeBuilder;n" +
"n" +
"@javax.inject.Singletonn" +
"public class RuntimeProducer {n" +
" public static final KieRuntimeBuilder INSTANCE = new org.drools.project.model.ProjectRuntime();n" +
"n" +
" @javax.enterprise.inject.Producesn" +
" public KieRuntimeBuilder produce() { return INSTANCE; }n" +
"}";
@BuildStep(providesCapabilities = "io.quarkus.drools") @Record(STATIC_INIT)
public void generateModel( ArchiveRootBuildItem root,
BuildProducer<GeneratedBeanBuildItem> generatedBeans, BuildProducer<GeneratedClassBuildItem> generatedClasses) {
MemoryFileSystem srcMfs = new MemoryFileSystem();
String[] sources = generateSources(root, srcMfs);
srcMfs.write(toRuntimeSource(PRODUCER_CLASSNAME), PRODUCER_SOURCE.getBytes());
sources[sources.length - 1] = toRuntimeSource(PRODUCER_CLASSNAME);
registerGeneratedClasses(generatedBeans, generatedClasses, compileSources(srcMfs, sources));
}
private void registerGeneratedClasses( BuildProducer<GeneratedBeanBuildItem> generatedBeans,
BuildProducer<GeneratedClassBuildItem> generatedClasses, MemoryFileSystem trgMfs) {
for (String fileName : trgMfs.getFileNames()) {
String className = toClassName(fileName);
if (className.equals(PRODUCER_CLASSNAME)) {
generatedBeans.produce(new GeneratedBeanBuildItem(className, trgMfs.getBytes(fileName)));
} else {
generatedClasses.produce(new GeneratedClassBuildItem(true, className, trgMfs.getBytes(fileName)));
}
}
}
}
A simple Quarkus-based
REST endopint using Drools
@Path("/candrink/{name}/{age}")
public class CanDrinkResource {
@Inject
KieRuntimeBuilder runtimeBuilder;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String canDrink( @PathParam("name") String name, @PathParam("age") int age ) {
KieSession ksession = runtimeBuilder.newKieSession("canDrinkKS");
Result result = new Result();
ksession.insert(result);
ksession.insert(new Person( name, age ));
ksession.fireAllRules();
return result.toString();
}
}
Demo 2
Drools on Quarkus
Mario Fusco
Red Hat – Principal Software Engineer
mario.fusco@gmail.com
twitter: @mariofusco
Q A
Thanks ... Questions?

More Related Content

What's hot

Advanced Java Practical File
Advanced Java Practical FileAdvanced Java Practical File
Advanced Java Practical File
Soumya Behera
 
Software Transactioneel Geheugen
Software Transactioneel GeheugenSoftware Transactioneel Geheugen
Software Transactioneel Geheugen
Devnology
 
Concurrency Utilities in Java 8
Concurrency Utilities in Java 8Concurrency Utilities in Java 8
Concurrency Utilities in Java 8
Martin Toshev
 

What's hot (20)

The... Wonderful? World of Lambdas
The... Wonderful? World of LambdasThe... Wonderful? World of Lambdas
The... Wonderful? World of Lambdas
 
Advanced Java Practical File
Advanced Java Practical FileAdvanced Java Practical File
Advanced Java Practical File
 
Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)
 
CS2309 JAVA LAB MANUAL
CS2309 JAVA LAB MANUALCS2309 JAVA LAB MANUAL
CS2309 JAVA LAB MANUAL
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
Java Lab Manual
Java Lab ManualJava Lab Manual
Java Lab Manual
 
Software Transactioneel Geheugen
Software Transactioneel GeheugenSoftware Transactioneel Geheugen
Software Transactioneel Geheugen
 
Java Class Design
Java Class DesignJava Class Design
Java Class Design
 
Parallel streams in java 8
Parallel streams in java 8Parallel streams in java 8
Parallel streams in java 8
 
Java9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadJava9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidad
 
Parallel Programming With Dot Net
Parallel Programming With Dot NetParallel Programming With Dot Net
Parallel Programming With Dot Net
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
 
Creating Lazy stream in CSharp
Creating Lazy stream in CSharpCreating Lazy stream in CSharp
Creating Lazy stream in CSharp
 
Harnessing the Power of Java 8 Streams
Harnessing the Power of Java 8 Streams Harnessing the Power of Java 8 Streams
Harnessing the Power of Java 8 Streams
 
Concurrency Utilities in Java 8
Concurrency Utilities in Java 8Concurrency Utilities in Java 8
Concurrency Utilities in Java 8
 
Functional Programming Past Present Future
Functional Programming Past Present FutureFunctional Programming Past Present Future
Functional Programming Past Present Future
 
Java programming lab manual
Java programming lab manualJava programming lab manual
Java programming lab manual
 
Java Concurrency Idioms
Java Concurrency IdiomsJava Concurrency Idioms
Java Concurrency Idioms
 

Similar to How and why I turned my old Java projects into a first-class serverless component

Similar to How and why I turned my old Java projects into a first-class serverless component (20)

Kogito: cloud native business automation
Kogito: cloud native business automationKogito: cloud native business automation
Kogito: cloud native business automation
 
bluespec talk
bluespec talkbluespec talk
bluespec talk
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVM
 
Concurrency in Eclipse: Best Practices and Gotchas
Concurrency in Eclipse: Best Practices and GotchasConcurrency in Eclipse: Best Practices and Gotchas
Concurrency in Eclipse: Best Practices and Gotchas
 
Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)
 
Monitoring MySQL with DTrace/SystemTap
Monitoring MySQL with DTrace/SystemTapMonitoring MySQL with DTrace/SystemTap
Monitoring MySQL with DTrace/SystemTap
 
Knowledge of Javascript
Knowledge of JavascriptKnowledge of Javascript
Knowledge of Javascript
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
 
Ase02.ppt
Ase02.pptAse02.ppt
Ase02.ppt
 
Automated scaling of microservice stacks for JavaEE applications - JEEConf 2017
Automated scaling of microservice stacks for JavaEE applications - JEEConf 2017Automated scaling of microservice stacks for JavaEE applications - JEEConf 2017
Automated scaling of microservice stacks for JavaEE applications - JEEConf 2017
 
JEEconf 2017
JEEconf 2017JEEconf 2017
JEEconf 2017
 
Drools Introduction
Drools IntroductionDrools Introduction
Drools Introduction
 
Chaos is a ladder !
Chaos is a ladder !Chaos is a ladder !
Chaos is a ladder !
 
Android - Preventing common memory leaks
Android - Preventing common memory leaksAndroid - Preventing common memory leaks
Android - Preventing common memory leaks
 
Nelson: Rigorous Deployment for a Functional World
Nelson: Rigorous Deployment for a Functional WorldNelson: Rigorous Deployment for a Functional World
Nelson: Rigorous Deployment for a Functional World
 
Clean code & design patterns
Clean code & design patternsClean code & design patterns
Clean code & design patterns
 
Gradle For Beginners (Serbian Developer Conference 2013 english)
Gradle For Beginners (Serbian Developer Conference 2013 english)Gradle For Beginners (Serbian Developer Conference 2013 english)
Gradle For Beginners (Serbian Developer Conference 2013 english)
 
Ch 6 randomization
Ch 6 randomizationCh 6 randomization
Ch 6 randomization
 
Performance Test Driven Development with Oracle Coherence
Performance Test Driven Development with Oracle CoherencePerformance Test Driven Development with Oracle Coherence
Performance Test Driven Development with Oracle Coherence
 
Core Java Programming Language (JSE) : Chapter IV - Expressions and Flow Cont...
Core Java Programming Language (JSE) : Chapter IV - Expressions and Flow Cont...Core Java Programming Language (JSE) : Chapter IV - Expressions and Flow Cont...
Core Java Programming Language (JSE) : Chapter IV - Expressions and Flow Cont...
 

More from Mario Fusco

FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
Mario Fusco
 
Real world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageReal world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same language
Mario Fusco
 
Introducing Drools
Introducing DroolsIntroducing Drools
Introducing Drools
Mario Fusco
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
Mario Fusco
 
Swiss army knife Spring
Swiss army knife SpringSwiss army knife Spring
Swiss army knife Spring
Mario Fusco
 
No more loops with lambdaj
No more loops with lambdajNo more loops with lambdaj
No more loops with lambdaj
Mario Fusco
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Mario Fusco
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
Mario Fusco
 

More from Mario Fusco (16)

Let's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java APILet's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java API
 
OOP and FP
OOP and FPOOP and FP
OOP and FP
 
Lazy java
Lazy javaLazy java
Lazy java
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Drools 6 deep dive
Drools 6 deep diveDrools 6 deep dive
Drools 6 deep dive
 
OOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better Programmer
 
Monadic Java
Monadic JavaMonadic Java
Monadic Java
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
Real world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageReal world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same language
 
Introducing Drools
Introducing DroolsIntroducing Drools
Introducing Drools
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
 
Hammurabi
HammurabiHammurabi
Hammurabi
 
Swiss army knife Spring
Swiss army knife SpringSwiss army knife Spring
Swiss army knife Spring
 
No more loops with lambdaj
No more loops with lambdajNo more loops with lambdaj
No more loops with lambdaj
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 

Recently uploaded

AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 

Recently uploaded (20)

Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 

How and why I turned my old Java projects into a first-class serverless component

  • 1. How and why I turned my old Java projects into a first-class serverless component by Mario Fusco Red Hat – Principal Software Engineer @mariofusco c
  • 2. Agenda ➢ Declarative vs. Imperative programming ➢ What is a rule engine and how it works ➢ A simple example ➢ From drl to Java: the executable model
  • 3. Agenda ➢ Declarative vs. Imperative programming ➢ What is a rule engine and how it works ➢ A simple example ➢ From drl to Java: the executable model ➢ What is GraalVM ➢ AoT compilation ➢ Limitations ➢ Refactoring Drools to (natively) compile on GraalVM
  • 4. Agenda c ➢ Declarative vs. Imperative programming ➢ What is a rule engine and how it works ➢ A simple example ➢ From drl to Java: the executable model ➢ What is GraalVM ➢ AoT compilation ➢ Limitations ➢ Refactoring Drools to (natively) compile on GraalVM ➢ What is Quarkus ➢ Quarkus features ➢ Integrating Drools with Quarkus ➢ Writing a Quarkus extension for Drools
  • 5. What a rule-based program is ➢ A rule-based program is made up of discrete rules, each of which applies to a subset of the problem ➢ It is simpler, because you can concentrate on the rules for one situation at a time ➢ It can be more flexible in the face of fragmentary or poorly conditioned inputs ➢ Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in short, all problems without clear algorithmic solutions
  • 6. What a rule-based program is ➢ A rule-based program is made up of discrete rules, each of which applies to a subset of the problem ➢ It is simpler, because you can concentrate on the rules for one situation at a time ➢ It can be more flexible in the face of fragmentary or poorly conditioned inputs ➢ Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in short, all problems without clear algorithmic solutions Declarative (What to do) Imperative (How to do it) Vs. public void helloMark(Person person) { if ( person.getName().equals( “Mark” ) { System.out.println( “Hello Mark” ); } } rule “Hello Mark” when Person( name == “Mark” ) then System.out.println( “Hello Mark” ); end
  • 7. What a rule-based program is ➢ A rule-based program is made up of discrete rules, each of which applies to a subset of the problem ➢ It is simpler, because you can concentrate on the rules for one situation at a time ➢ It can be more flexible in the face of fragmentary or poorly conditioned inputs ➢ Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in short, all problems without clear algorithmic solutions Declarative (What to do) Imperative (How to do it) Vs. public void helloMark(Person person) { if ( person.getName().equals( “Mark” ) { System.out.println( “Hello Mark” ); } } rule “Hello Mark” when Person( name == “Mark” ) then System.out.println( “Hello Mark” ); end A method must be called directly Rules can never be called directly
  • 8. What a rule-based program is ➢ A rule-based program is made up of discrete rules, each of which applies to a subset of the problem ➢ It is simpler, because you can concentrate on the rules for one situation at a time ➢ It can be more flexible in the face of fragmentary or poorly conditioned inputs ➢ Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in short, all problems without clear algorithmic solutions Declarative (What to do) Imperative (How to do it) Vs. public void helloMark(Person person) { if ( person.getName().equals( “Mark” ) { System.out.println( “Hello Mark” ); } } rule “Hello Mark” when Person( name == “Mark” ) then System.out.println( “Hello Mark” ); end A method must be called directly Specific passing of arguments Rules can never be called directly Specific instances cannot be passed but are automatically selected with pattern-matching
  • 9. Introducing ➢ Easier to understand → Requirements can be more naturally translated into rules. It is more likely for a technically skilled business analyst to verify, validate or even change a rule than a piece of Java code ➢ Improved maintainability → We don't care about how to implement a solution only what needs to be done to solve a problem ➢ Deals with evolving complexity → It's easier to modify a rule than a Java program and to determine the impact of this change on the rest of the application ➢ Modularity → Each rule models an isolated and small portion of your business logic and is not part of a monolithic program ➢ Clear separation of business logic from the rest of the system → Business and infrastructural code have very different lifecycles ➢ Complex Event Processing → Facts can be handled like timestamped events allowing temporal reasoning on them RULES
  • 10. How a rule-based system works ➢ The Rule Base contains a computation efficient representation of the set of the defined rules ➢ The Working Memory contains the set of facts inserted into sessions ➢ The engine matches the fact in the working memory against the rules set ➢ When a match is found it creates an activation and put it into the agenda ➢ An activation is the tuple of facts matching the conditions of a rule plus the rule itself ➢ When all activations have been created the agenda elects through a conflict resolution strategy the one to be executed ➢ The elected activation is passed to the execution engine and the fired
  • 11. A simple rule set rule RaiseAlarm when exists Fire() then insert( new Alarm( "house1" ) ); System.out.println( "Raise the Alarm"); end rule CancelAlarm when not Fire() a : Alarm() then delete( a ); System.out.println( "Cancel the Alarm"); end rule TurnSprinklerOn when s : Sprinkler( on == false ) f : Fire( room == s.room ) then modify( s ) { setOn( true ) } System.out.println( "Turn on the sprinkler for room " + f.getRoom().getName() ); end rule TurnSprinklerOff when s : Sprinkler( on == true ) not Fire( room == s.room ) then modify( s ) { setOn( false ) } System.out.println( "Turn off the sprinkler for room " + s.getRoom().getName() ); end rule OK when not Alarm() not Sprinkler( on == true ) then System.out.println( "Everything is ok" ); end Pattern-matching against objects in the Working Memory Code executed when a match is found
  • 12. What is used by Quarkus ➢ A polyglot VM with cross-language JIT supporting ● Java Bytecode and JVM languages ● Interop with different languages ● Dynamic languages through Truffle API ➢ Cross-language interop out of the box ● Simple AST-based interpreter ● JIT across language boundaries ➢ Support for native binary compilation (SubstrateVM) ● faster boot-up ● lower memory footprint
  • 13. AoT compilation with GraalVM ➢ Static analysis ➢ Closed world assumption ➢ Dead code elimination:      classes, fields, methods, branches
  • 14. AoT compilation with GraalVM ➢ Static analysis ➢ Closed world assumption ➢ Dead code elimination:      classes, fields, methods, branches 🚀 Fast process start 🔬 Less memory 💾 Small size on disk
  • 15. GraalVM Limitations Dynaminc Classloading Deloying jars, wars, etc. at runtime impossible public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } }
  • 16. GraalVM Limitations Dynaminc Classloading Deloying jars, wars, etc. at runtime impossible public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } }
  • 17. GraalVM Limitations Dynaminc Classloading Deloying jars, wars, etc. at runtime impossible public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } } JVMTI, JMX + other native VM interfaces No agents → No JRebel, Byteman, profilers, tracers Miscellaneous ➢ Security Manager ➢ finalize() (depreceated anyway) ➢ InvokeDynamic and MethodHandle
  • 18. GraalVM Limitations Dynaminc Classloading Deloying jars, wars, etc. at runtime impossible public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } } JVMTI, JMX + other native VM interfaces No agents → No JRebel, Byteman, profilers, tracers Miscellaneous ➢ Security Manager ➢ finalize() (depreceated anyway) ➢ InvokeDynamic and MethodHandle
  • 19. GraalVM Limitations Dynaminc Classloading Deloying jars, wars, etc. at runtime impossible public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } } JVMTI, JMX + other native VM interfaces No agents → No JRebel, Byteman, profilers, tracers Miscellaneous ➢ Security Manager ➢ finalize() (depreceated anyway) ➢ InvokeDynamic and MethodHandle Reflection Requires registration (closed world assumption)
  • 20. GraalVM Limitations Dynaminc Classloading Deloying jars, wars, etc. at runtime impossible public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { return defineClass( name, bytecode, 0, bytecode.length ); } } JVMTI, JMX + other native VM interfaces No agents → No JRebel, Byteman, profilers, tracers Miscellaneous ➢ Security Manager ➢ finalize() (depreceated anyway) ➢ InvokeDynamic and MethodHandle [ { "name" : "org.domain.model.Person", "allPublicConstructors" : true, "allPublicMethods" : true } ] Reflection Requires registration (closed world assumption) -H:ReflectionConfigurationFiles=src/main/resources/reflection.json
  • 21. Drools on GraalVM - Executable Model rule "Older than Mark" when $p1: Person( name == "Mark" ) $p2: Person( name != "Mark", age > $p1.age ) then System.out.println( $p1.getName() + " is older than " + $p2.getName() ); end Variable<Person> markV = declarationOf( Person.class ); Variable<Person> olderV = declarationOf( Person.class ); Rule rule = rule( "Older than Mark" ) .build( pattern(markV) .expr("exprA", p -> p.getName().equals( "Mark" ), alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name", "age" )), pattern(olderV) .expr("exprB", p -> !p.getName().equals("Mark"), alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name" )) .expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(), betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ), reactOn( "age" )), on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() )) )
  • 22. Drools on GraalVM - Executable Model rule "Older than Mark" when $p1: Person( name == "Mark" ) $p2: Person( name != "Mark", age > $p1.age ) then System.out.println( $p1.getName() + " is older than " + $p2.getName() ); end Variable<Person> markV = declarationOf( Person.class ); Variable<Person> olderV = declarationOf( Person.class ); Rule rule = rule( "Older than Mark" ) .build( pattern(markV) .expr("exprA", p -> p.getName().equals( "Mark" ), alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name", "age" )), pattern(olderV) .expr("exprB", p -> !p.getName().equals("Mark"), alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name" )) .expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(), betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ), reactOn( "age" )), on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() )) )
  • 23. Drools on GraalVM - Executable Model rule "Older than Mark" when $p1: Person( name == "Mark" ) $p2: Person( name != "Mark", age > $p1.age ) then System.out.println( $p1.getName() + " is older than " + $p2.getName() ); end Variable<Person> markV = declarationOf( Person.class ); Variable<Person> olderV = declarationOf( Person.class ); Rule rule = rule( "Older than Mark" ) .build( pattern(markV) .expr("exprA", p -> p.getName().equals( "Mark" ), alphaIndexedBy( String.class, ConstraintType.EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name", "age" )), pattern(olderV) .expr("exprB", p -> !p.getName().equals("Mark"), alphaIndexedBy( String.class, ConstraintType.NOT_EQUAL, 1, p -> p.getName(), "Mark" ), reactOn( "name" )) .expr("exprC", markV, (p1, p2) -> p1.getAge() > p2.getAge(), betaIndexedBy( int.class, ConstraintType.GREATER_THAN, 0, p -> p.getAge(), p -> p.getAge() ), reactOn( "age" )), on(olderV, markV).execute((p1, p2) -> System.out.println( p1.getName() + " is older than " + p2.getName() )) ) Executable model Indexes and reactivity explicitly defined
  • 24. Executable Model at a glance ➢ A pure Java DSL for Drools rules authoring ➢ A pure Java canonical representation of a rule base ➢ Automatically generated by Maven plugin or Quarkus extension ● Can be embedded in jar ● Faster boot ➢ Improve Backward/Forward compatibility ➢ Allow for faster prototyping and experimentation of new features ➢ Prerequisite to make Drools natively compilable on GraalVM
  • 25. public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { throw new UnsupportedOperationException(); } } Drools on GraalVM – other refactors Dynamic class definition is no longer necessary
  • 26. public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { throw new UnsupportedOperationException(); } } Drools on GraalVM – other refactors Dynamic class definition is no longer necessary <?xml version="1.0" encoding="UTF-8"?> <kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> <kbase name="simpleKB" packages="org.drools.simple.project"> <ksession name="simpleKS" default="true"/> </kbase> </kmodule> var m = KieServices.get().newKieModuleModel(); var kb = m.newKieBaseModel("simpleKB"); kb.setEventProcessingMode(CLOUD); kb.addPackage("org.drools.simple.project"); var ks = kb.newKieSessionModel("simpleKS"); ks.setDefault(true); ks.setType(STATEFUL); ks.setClockType(ClockTypeOption.get("realtime"));
  • 27. public class InternalClassLoader extends ClassLoader { public Class<?> defineClass( String name, byte[] bytecode ) { throw new UnsupportedOperationException(); } } Drools on GraalVM – other refactors Dynamic class definition is no longer necessary <?xml version="1.0" encoding="UTF-8"?> <kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> <kbase name="simpleKB" packages="org.drools.simple.project"> <ksession name="simpleKS" default="true"/> </kbase> </kmodule> var m = KieServices.get().newKieModuleModel(); var kb = m.newKieBaseModel("simpleKB"); kb.setEventProcessingMode(CLOUD); kb.addPackage("org.drools.simple.project"); var ks = kb.newKieSessionModel("simpleKS"); ks.setDefault(true); ks.setType(STATEFUL); ks.setClockType(ClockTypeOption.get("realtime")); org.kie.api.io.KieResources = org.drools.core.io.impl.ResourceFactoryServiceImpl org.kie.api.marshalling.KieMarshallers = org.drools.core.marshalling.MarshallerProviderImpl org.kie.api.concurrent.KieExecutors = org.drools.core.concurrent.ExecutorProviderImpl Map<Class<?>, Object> serviceMap = new HashMap<>(); void wireServices() { serviceMap.put( ServiceInterface.class, Class.forName("org.drools.ServiceImpl") .newInstance()); // … more services here }
  • 28. Demo 1 Drools on GraalVM
  • 29. Introducing ➢ A Framework for writing (fast and lightweight) Java applications
  • 30. Introducing ➢ A Framework for writing (fast and lightweight) Java applications ➢ (Optionally) allowing generation of native executable via GraalVM *.class QUARKUS optimized jar native executable JVM Maven/Gradle plugin
  • 31. Introducing ➢ A Framework for writing (fast and lightweight) Java applications ➢ (Optionally) allowing generation of native executable via GraalVM ➢ Based on existing standard ● Servlet ● JAX-RS ● JPA, JDBC ● CDI ● Bean Validation ● Transactions ● Logging ● Microprofile *.class QUARKUS optimized jar native executable JVM Maven/Gradle plugin
  • 32. Introducing ➢ A Framework for writing (fast and lightweight) Java applications ➢ (Optionally) allowing generation of native executable via GraalVM ➢ Based on existing standard ● Servlet ● JAX-RS ● JPA, JDBC ● CDI ● Bean Validation ● Transactions ● Logging ● Microprofile ➢ Out-of-the-box integration with libraries that you already know *.class QUARKUS optimized jar native executable JVM Maven/Gradle plugin
  • 35. Fast, lightweight Drools = Submarine The question of whether a computer can think is no more interesting than the question of whether a submarine can swim - Edsger W. Dijkstra
  • 36. Integrating Quarkus and Drools Writing a Quarkus extension public class ExecutableModelGenerator { private static final String PRODUCER_SOURCE = "package io.quarkus.drools.runtime;n" + "import org.drools.modelcompiler.KieRuntimeBuilder;n" + "n" + "@javax.inject.Singletonn" + "public class RuntimeProducer {n" + " public static final KieRuntimeBuilder INSTANCE = new org.drools.project.model.ProjectRuntime();n" + "n" + " @javax.enterprise.inject.Producesn" + " public KieRuntimeBuilder produce() { return INSTANCE; }n" + "}"; @BuildStep(providesCapabilities = "io.quarkus.drools") @Record(STATIC_INIT) public void generateModel( ArchiveRootBuildItem root, BuildProducer<GeneratedBeanBuildItem> generatedBeans, BuildProducer<GeneratedClassBuildItem> generatedClasses) { MemoryFileSystem srcMfs = new MemoryFileSystem(); String[] sources = generateSources(root, srcMfs); srcMfs.write(toRuntimeSource(PRODUCER_CLASSNAME), PRODUCER_SOURCE.getBytes()); sources[sources.length - 1] = toRuntimeSource(PRODUCER_CLASSNAME); registerGeneratedClasses(generatedBeans, generatedClasses, compileSources(srcMfs, sources)); } private void registerGeneratedClasses( BuildProducer<GeneratedBeanBuildItem> generatedBeans, BuildProducer<GeneratedClassBuildItem> generatedClasses, MemoryFileSystem trgMfs) { for (String fileName : trgMfs.getFileNames()) { String className = toClassName(fileName); if (className.equals(PRODUCER_CLASSNAME)) { generatedBeans.produce(new GeneratedBeanBuildItem(className, trgMfs.getBytes(fileName))); } else { generatedClasses.produce(new GeneratedClassBuildItem(true, className, trgMfs.getBytes(fileName))); } } } }
  • 37. A simple Quarkus-based REST endopint using Drools @Path("/candrink/{name}/{age}") public class CanDrinkResource { @Inject KieRuntimeBuilder runtimeBuilder; @GET @Produces(MediaType.TEXT_PLAIN) public String canDrink( @PathParam("name") String name, @PathParam("age") int age ) { KieSession ksession = runtimeBuilder.newKieSession("canDrinkKS"); Result result = new Result(); ksession.insert(result); ksession.insert(new Person( name, age )); ksession.fireAllRules(); return result.toString(); } }
  • 38. Demo 2 Drools on Quarkus
  • 39. Mario Fusco Red Hat – Principal Software Engineer mario.fusco@gmail.com twitter: @mariofusco Q A Thanks ... Questions?