SlideShare a Scribd company logo
How and why I turned my old
Java projects into a first-class
serverless component
by Mario Fusco
Red Hat – Principal Software Engineer
@mariofusco
● A cloud-native development, deployment and execution platform for
business automation:
○ Rules and Decisions (Drools)
○ Processes and Cases (jBPM)
● ... under the covers
○ the backbone is code generation based on business assets
○ executable model for the process/rule/decision definitions
○ type safe data model that encapsulates variables
○ REST api for each public business process/decision/rule
Introducing
Demo
Kogito + Quarkus
Cool, but ... how did we get there?
A minimal agenda
⼚GraalVM features and limitations
⼚How (and why) we made Drools
natively compilable on GraalVM
⼚How we integrated Kogito with
Quarkus: creating a Quarkus extension
⼚Enabling hot reload of rules, decision
tables and processes
⼚One last demo
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
}
JVM vs.
Native
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
Compile generate
Java sources in
memory
Integrating Quarkus and Kogito
Writing a Quarkus extension
public class KogitoAssetProcessor {
@BuildStep(providesCapabilities = "io.quarkus.kogito")
public void generateModel( ArchiveRootBuildItem root,
BuildProducer<GeneratedBeanBuildItem> generatedBeans,
LaunchModeBuildItem launchMode) throws IOException {
LaunchMode launchMode = launchModeItem.getLaunchMode();
if (hotReload(launchMode)) {
return;
}
ApplicationGenerator appGen = createApplicationGenerator(root, launchMode);
Collection<GeneratedFile> generatedFiles = appGen.generate();
if (!generatedFiles.isEmpty()) {
MemoryFileSystem trgMfs = new MemoryFileSystem();
CompilationResult result = compile( root, trgMfs, generatedFiles,
generatedBeans, launchMode );
register( trgMfs, generatedBeans, launchMode, result );
}
}
}
Avoid recompiling
everything during
an hot reload
Generate
executable model
source files
Register generated
classes into
Quarkus runtime
Kogito hot reload
public class KogitoCompilationProvider extends JavaCompilationProvider {
@Override
public final void compile(Set<File> filesToCompile, Context context) {
File outputDirectory = context.getOutputDirectory();
try {
ApplicationGenerator appGen = new ApplicationGenerator( appPackageName,
outputDirectory );
Generator generator = addGenerator(appGen, filesToCompile, context);
Collection<GeneratedFile> generatedFiles = generator.generate();
HashSet<File> generatedSourceFiles = new HashSet<>();
for (GeneratedFile file : generatedFiles) {
Path path = pathOf(outputDirectory.getPath(), file.relativePath());
Files.write(path, file.contents());
generatedSourceFiles.add(path.toFile());
}
super.compile(generatedSourceFiles, context);
} catch (IOException e) {
throw new KogitoCompilerException(e);
}
}
}
Write regenerated
source in the file
system
Extends Java hot
reload mechanism
provided by Quarkus
Regenerate executable
model only for changed
sources
Pass the list of
generated sources to
super in order to
recompile them
A simple Quarkus-based
REST endpoint using Kogito
@Path("/candrink/{name}/{age}")
public class CanDrinkResource {
@Inject @Named("canDrinkKS")
RuleUnit<SessionMemory> ruleUnit;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String canDrink( @PathParam("name") String name, @PathParam("age") int age ) {
SessionMemory memory = new SessionMemory();
Result result = new Result();
memory.add(result);
memory.add(new Person( name, age ));
ruleUnit.evaluate(memory);
return result.toString();
}
}
What’s next?
Don’t miss Maciej Swiderski’s DevNationLive talk on the 5th
of September:
Event-driven business automation powered by cloud native Java
➱
Rule bases modularization via
Rule Units
➱
Rule Units orchestration through
jBPM workflows
➱
Seamless integration with Camel
routes, Kafka streams, ...
➱
Automatic REST endpoint
generation returning result of DRL
queries
Mario Fusco
Red Hat – Principal Software Engineer
mario.fusco@gmail.com
twitter: @mariofusco
Q A
Thanks ... Questions?

More Related Content

PDF
Kogito: cloud native business automation
PDF
"Managing the Complete Machine Learning Lifecycle with MLflow"
PPTX
Google cloud Dataflow & Apache Flink
PDF
MLOps Using MLflow
PDF
Introduction to Cassandra
PDF
When NOT to use Apache Kafka?
PPTX
Cassandra vs. ScyllaDB: Evolutionary Differences
PDF
MLflow Model Serving
Kogito: cloud native business automation
"Managing the Complete Machine Learning Lifecycle with MLflow"
Google cloud Dataflow & Apache Flink
MLOps Using MLflow
Introduction to Cassandra
When NOT to use Apache Kafka?
Cassandra vs. ScyllaDB: Evolutionary Differences
MLflow Model Serving

What's hot (20)

PDF
Spark at Zillow
PDF
A Deep Dive into Query Execution Engine of Spark SQL
PDF
Machine learning at scale with Google Cloud Platform
PDF
Data Source API in Spark
PDF
What is MLOps
PPTX
NOVA SQL User Group - Azure Synapse Analytics Overview - May 2020
PPTX
Policy as Code: IT Governance With HashiCorp Sentinel
PDF
Migrating Airflow-based Apache Spark Jobs to Kubernetes – the Native Way
PPTX
Introduction to Apache Kafka
PPTX
Programming in Spark using PySpark
PDF
Spark (Structured) Streaming vs. Kafka Streams
PDF
Forest Cover type prediction
PPTX
Cassandra Data Modeling - Practical Considerations @ Netflix
PDF
New Directions for Apache Arrow
PDF
Introducing DataFrames in Spark for Large Scale Data Science
PPTX
Differentiate Big Data vs Data Warehouse use cases for a cloud solution
PDF
Scaling Machine Learning with Apache Spark
PDF
Introduction to Spark with Python
PDF
Data Pipline Observability meetup
PDF
What is Apache Spark | Apache Spark Tutorial For Beginners | Apache Spark Tra...
Spark at Zillow
A Deep Dive into Query Execution Engine of Spark SQL
Machine learning at scale with Google Cloud Platform
Data Source API in Spark
What is MLOps
NOVA SQL User Group - Azure Synapse Analytics Overview - May 2020
Policy as Code: IT Governance With HashiCorp Sentinel
Migrating Airflow-based Apache Spark Jobs to Kubernetes – the Native Way
Introduction to Apache Kafka
Programming in Spark using PySpark
Spark (Structured) Streaming vs. Kafka Streams
Forest Cover type prediction
Cassandra Data Modeling - Practical Considerations @ Netflix
New Directions for Apache Arrow
Introducing DataFrames in Spark for Large Scale Data Science
Differentiate Big Data vs Data Warehouse use cases for a cloud solution
Scaling Machine Learning with Apache Spark
Introduction to Spark with Python
Data Pipline Observability meetup
What is Apache Spark | Apache Spark Tutorial For Beginners | Apache Spark Tra...
Ad

Similar to Introducing Kogito (20)

PDF
Scala in Places API
PDF
Introduction to Scalding and Monoids
PDF
Clojure for Java developers - Stockholm
PDF
JavaScript and the AST
ZIP
Lisp Macros in 20 Minutes (Featuring Clojure)
PDF
Unit testing JavaScript using Mocha and Node
PDF
Go 1.10 Release Party - PDX Go
PPTX
Clojure And Swing
PDF
Scala @ TechMeetup Edinburgh
PDF
DataMapper
PDF
Node.js vs Play Framework (with Japanese subtitles)
PDF
Polyglot Programming @ Jax.de 2010
PPT
Groovy Introduction - JAX Germany - 2008
PPTX
JavaScript Basics - GameCraft Training
PDF
Node.js - async for the rest of us.
PPT
2007 09 10 Fzi Training Groovy Grails V Ws
PDF
TDC2018SP | Trilha Go - Processando analise genetica em background com Go
PPTX
Groovy
PDF
Griffon @ Svwjug
PDF
Riak at The NYC Cloud Computing Meetup Group
Scala in Places API
Introduction to Scalding and Monoids
Clojure for Java developers - Stockholm
JavaScript and the AST
Lisp Macros in 20 Minutes (Featuring Clojure)
Unit testing JavaScript using Mocha and Node
Go 1.10 Release Party - PDX Go
Clojure And Swing
Scala @ TechMeetup Edinburgh
DataMapper
Node.js vs Play Framework (with Japanese subtitles)
Polyglot Programming @ Jax.de 2010
Groovy Introduction - JAX Germany - 2008
JavaScript Basics - GameCraft Training
Node.js - async for the rest of us.
2007 09 10 Fzi Training Groovy Grails V Ws
TDC2018SP | Trilha Go - Processando analise genetica em background com Go
Groovy
Griffon @ Svwjug
Riak at The NYC Cloud Computing Meetup Group
Ad

More from Red Hat Developers (20)

PDF
DevNation Tech Talk: Getting GitOps
PDF
Exploring the power of OpenTelemetry on Kubernetes
PDF
GitHub Makeover | DevNation Tech Talk
PDF
Quinoa: A modern Quarkus UI with no hassles | DevNation tech Talk
PDF
Extra micrometer practices with Quarkus | DevNation Tech Talk
PDF
Event-driven autoscaling through KEDA and Knative Integration | DevNation Tec...
PDF
Integrating Loom in Quarkus | DevNation Tech Talk
PDF
Quarkus Renarde đŸŠŠâ™„: an old-school Web framework with today's touch | DevNatio...
PDF
Containers without docker | DevNation Tech Talk
PDF
Distributed deployment of microservices across multiple OpenShift clusters | ...
PDF
DevNation Workshop: Object detection with Red Hat OpenShift Data Science [Mar...
PDF
Dear security, compliance, and auditing: We’re sorry. Love, DevOps | DevNatio...
PDF
11 CLI tools every developer should know | DevNation Tech Talk
PDF
A Microservices approach with Cassandra and Quarkus | DevNation Tech Talk
PDF
GitHub Actions and OpenShift: ​​Supercharging your software development loops...
PDF
To the moon and beyond with Java 17 APIs! | DevNation Tech Talk
PDF
Profile your Java apps in production on Red Hat OpenShift with Cryostat | Dev...
PDF
Kafka at the Edge: an IoT scenario with OpenShift Streams for Apache Kafka | ...
PDF
Kubernetes configuration and security policies with KubeLinter | DevNation Te...
PDF
Level-up your gaming telemetry using Kafka Streams | DevNation Tech Talk
DevNation Tech Talk: Getting GitOps
Exploring the power of OpenTelemetry on Kubernetes
GitHub Makeover | DevNation Tech Talk
Quinoa: A modern Quarkus UI with no hassles | DevNation tech Talk
Extra micrometer practices with Quarkus | DevNation Tech Talk
Event-driven autoscaling through KEDA and Knative Integration | DevNation Tec...
Integrating Loom in Quarkus | DevNation Tech Talk
Quarkus Renarde đŸŠŠâ™„: an old-school Web framework with today's touch | DevNatio...
Containers without docker | DevNation Tech Talk
Distributed deployment of microservices across multiple OpenShift clusters | ...
DevNation Workshop: Object detection with Red Hat OpenShift Data Science [Mar...
Dear security, compliance, and auditing: We’re sorry. Love, DevOps | DevNatio...
11 CLI tools every developer should know | DevNation Tech Talk
A Microservices approach with Cassandra and Quarkus | DevNation Tech Talk
GitHub Actions and OpenShift: ​​Supercharging your software development loops...
To the moon and beyond with Java 17 APIs! | DevNation Tech Talk
Profile your Java apps in production on Red Hat OpenShift with Cryostat | Dev...
Kafka at the Edge: an IoT scenario with OpenShift Streams for Apache Kafka | ...
Kubernetes configuration and security policies with KubeLinter | DevNation Te...
Level-up your gaming telemetry using Kafka Streams | DevNation Tech Talk

Recently uploaded (20)

PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Introduction to Artificial Intelligence
PDF
System and Network Administration Chapter 2
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
medical staffing services at VALiNTRY
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PPTX
Transform Your Business with a Software ERP System
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
ai tools demonstartion for schools and inter college
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
PTS Company Brochure 2025 (1).pdf.......
Odoo Companies in India – Driving Business Transformation.pdf
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
How to Choose the Right IT Partner for Your Business in Malaysia
Introduction to Artificial Intelligence
System and Network Administration Chapter 2
wealthsignaloriginal-com-DS-text-... (1).pdf
medical staffing services at VALiNTRY
Navsoft: AI-Powered Business Solutions & Custom Software Development
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
Transform Your Business with a Software ERP System
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Wondershare Filmora 15 Crack With Activation Key [2025
ai tools demonstartion for schools and inter college
Upgrade and Innovation Strategies for SAP ERP Customers
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PTS Company Brochure 2025 (1).pdf.......

Introducing Kogito

  • 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
  • 2. ● A cloud-native development, deployment and execution platform for business automation: ○ Rules and Decisions (Drools) ○ Processes and Cases (jBPM) ● ... under the covers ○ the backbone is code generation based on business assets ○ executable model for the process/rule/decision definitions ○ type safe data model that encapsulates variables ○ REST api for each public business process/decision/rule Introducing
  • 4. Cool, but ... how did we get there? A minimal agenda ⼚GraalVM features and limitations ⼚How (and why) we made Drools natively compilable on GraalVM ⼚How we integrated Kogito with Quarkus: creating a Quarkus extension ⼚Enabling hot reload of rules, decision tables and processes ⼚One last demo
  • 5. 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
  • 6. AoT compilation with GraalVM ➱ Static analysis ➱ Closed world assumption ➱ Dead code elimination:      classes, fields, methods, branches
  • 7. 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
  • 8. 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 ); } }
  • 9. 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 ); } }
  • 10. 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
  • 11. 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
  • 12. 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)
  • 13. 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
  • 14. 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() )) )
  • 15. 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() )) )
  • 16. 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
  • 17. 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
  • 18. 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
  • 19. 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"));
  • 20. 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 }
  • 22. Introducing ➱ A Framework for writing (fast and lightweight) Java applications
  • 23. 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
  • 24. 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
  • 25. 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
  • 26. Compile generate Java sources in memory Integrating Quarkus and Kogito Writing a Quarkus extension public class KogitoAssetProcessor { @BuildStep(providesCapabilities = "io.quarkus.kogito") public void generateModel( ArchiveRootBuildItem root, BuildProducer<GeneratedBeanBuildItem> generatedBeans, LaunchModeBuildItem launchMode) throws IOException { LaunchMode launchMode = launchModeItem.getLaunchMode(); if (hotReload(launchMode)) { return; } ApplicationGenerator appGen = createApplicationGenerator(root, launchMode); Collection<GeneratedFile> generatedFiles = appGen.generate(); if (!generatedFiles.isEmpty()) { MemoryFileSystem trgMfs = new MemoryFileSystem(); CompilationResult result = compile( root, trgMfs, generatedFiles, generatedBeans, launchMode ); register( trgMfs, generatedBeans, launchMode, result ); } } } Avoid recompiling everything during an hot reload Generate executable model source files Register generated classes into Quarkus runtime
  • 27. Kogito hot reload public class KogitoCompilationProvider extends JavaCompilationProvider { @Override public final void compile(Set<File> filesToCompile, Context context) { File outputDirectory = context.getOutputDirectory(); try { ApplicationGenerator appGen = new ApplicationGenerator( appPackageName, outputDirectory ); Generator generator = addGenerator(appGen, filesToCompile, context); Collection<GeneratedFile> generatedFiles = generator.generate(); HashSet<File> generatedSourceFiles = new HashSet<>(); for (GeneratedFile file : generatedFiles) { Path path = pathOf(outputDirectory.getPath(), file.relativePath()); Files.write(path, file.contents()); generatedSourceFiles.add(path.toFile()); } super.compile(generatedSourceFiles, context); } catch (IOException e) { throw new KogitoCompilerException(e); } } } Write regenerated source in the file system Extends Java hot reload mechanism provided by Quarkus Regenerate executable model only for changed sources Pass the list of generated sources to super in order to recompile them
  • 28. A simple Quarkus-based REST endpoint using Kogito @Path("/candrink/{name}/{age}") public class CanDrinkResource { @Inject @Named("canDrinkKS") RuleUnit<SessionMemory> ruleUnit; @GET @Produces(MediaType.TEXT_PLAIN) public String canDrink( @PathParam("name") String name, @PathParam("age") int age ) { SessionMemory memory = new SessionMemory(); Result result = new Result(); memory.add(result); memory.add(new Person( name, age )); ruleUnit.evaluate(memory); return result.toString(); } }
  • 29. What’s next? Don’t miss Maciej Swiderski’s DevNationLive talk on the 5th of September: Event-driven business automation powered by cloud native Java ➱ Rule bases modularization via Rule Units ➱ Rule Units orchestration through jBPM workflows ➱ Seamless integration with Camel routes, Kafka streams, ... ➱ Automatic REST endpoint generation returning result of DRL queries
  • 30. Mario Fusco Red Hat – Principal Software Engineer mario.fusco@gmail.com twitter: @mariofusco Q A Thanks ... Questions?