<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ghassen hamdi</title>
    <description>The latest articles on DEV Community by Ghassen hamdi (@ghassen_hamdi_52915ac3bcd).</description>
    <link>https://dev.to/ghassen_hamdi_52915ac3bcd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3392924%2F18995dd6-575d-4feb-a7d5-13fded756e32.jpg</url>
      <title>DEV Community: Ghassen hamdi</title>
      <link>https://dev.to/ghassen_hamdi_52915ac3bcd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ghassen_hamdi_52915ac3bcd"/>
    <language>en</language>
    <item>
      <title>LWRE: A Lightweight Java Rule Engine for Scalable, Dynamic Business Logic</title>
      <dc:creator>Ghassen hamdi</dc:creator>
      <pubDate>Mon, 28 Jul 2025 05:13:57 +0000</pubDate>
      <link>https://dev.to/ghassen_hamdi_52915ac3bcd/lwre-a-lightweight-java-rule-engine-for-scalable-dynamic-business-logic-22gn</link>
      <guid>https://dev.to/ghassen_hamdi_52915ac3bcd/lwre-a-lightweight-java-rule-engine-for-scalable-dynamic-business-logic-22gn</guid>
      <description>&lt;p&gt;Hello Dev.to community! 👋 I’m thrilled to introduce LWRE (Lightweight Java Rule Engine), an open-source Java-based rule engine designed to tackle complex business logic with simplicity, performance, and scalability. If you’re building systems that require dynamic rule execution—think validation pipelines, decision trees, or workflow automation—LWRE is here to make your life easier. Check it out at HamdiGhassen/lwre (Apache 2.0 licensed), and if you find it valuable, please give it a ⭐ to help spread the word! 🌟.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is LWRE?
&lt;/h2&gt;

&lt;p&gt;LWRE is a Java rule engine that lets you define, compile, and execute business rules using a powerful Domain-Specific Language (DSL). It’s built for developers who need flexibility without sacrificing performance or reliability. Whether you’re managing microservices, validating user inputs, or orchestrating workflows, LWRE provides a robust framework with features like dependency management, parallel execution, and fault tolerance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Expressive DSL&lt;/strong&gt;: Define rules with a clean syntax, supporting imports, variables, retries, timeouts, and control flow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Compilation&lt;/strong&gt;: Uses Janino to compile rules into Java classes at runtime, with caching for efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Management&lt;/strong&gt;: Organizes rules into directed acyclic graphs (DAGs) for optimized execution order, with cycle detection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallel Execution&lt;/strong&gt;: Executes rule groups asynchronously using a thread pool, with configurable timeouts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fault Tolerance&lt;/strong&gt;: Supports retry policies with delays and conditions, plus a circuit breaker to prevent system overload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread Safety&lt;/strong&gt;: Built with &lt;code&gt;ConcurrentHashMap&lt;/code&gt;, thread-local pools, and synchronized methods for concurrent environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics &amp;amp; Tracing&lt;/strong&gt;: Tracks execution metrics and supports debugging with optional tracing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rule Versioning&lt;/strong&gt;: Enables safe updates and rollbacks for experimentation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Restricts access to dangerous classes (e.g., &lt;code&gt;java.lang.Runtime&lt;/code&gt;) and enforces timeouts to prevent infinite loops.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Choose LWRE?
&lt;/h2&gt;

&lt;p&gt;LWRE is lightweight and focused on simplicity, making it ideal for projects where you need dynamic rules without complex setup. Its DSL is intuitive, and its performance optimizations—like cached compilation and precomputed execution paths—ensure it scales well in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Java 17 or higher&lt;/li&gt;
&lt;li&gt;Maven for dependency management&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;Add the Janino dependency to your &lt;code&gt;pom.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.codehaus.janino&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;janino&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.1.12&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clone and build LWRE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/HamdiGhassen/lwre.git
&lt;span class="nb"&gt;cd &lt;/span&gt;lwre
mvn clean &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  In-Depth Example: User Validation Workflow
&lt;/h2&gt;

&lt;p&gt;Let’s walk through a practical example of using LWRE to validate a user and compute a credit score, with dependencies and retries. Below is a DSL defining two rules in a workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#GLOBAL
userId : String
creditThreshold : Integer

#HELPER
int computeCreditScore(int base) {
return base * 2 + 50;
}

#RULE CheckUser
#GROUP UserWorkflow
#PRIORITY 1
#TIMEOUT 500 ms

#USE
userId : String as user FROM Global
creditThreshold : Integer as threshold FROM Global

#PRODUCE
isValid : Boolean

#CONDITION
return user != null &amp;amp;&amp;amp; user.length() &amp;gt; 0;

#ACTION
isValid = true;

#FINAL
return isValid ? "User " + user + " is valid" : "Invalid user";

#RULE ComputeScore
#GROUP UserWorkflow
#PRIORITY 2
#NEXT_ON_SUCCESS Finalize
#USE
userId : String as user FROM Global
creditThreshold : Integer as threshold FROM Global
isValid : Boolean as isValid FROM RULE CheckUser

#PRODUCE
score : Integer

#CONDITION
return isValid &amp;amp;&amp;amp; threshold &amp;gt;= 100;

#ACTION
score = computeCreditScore(threshold);
System.out.println("Computed score for " + user + ": " + score);

#FINAL
return score;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CheckUser Rule&lt;/strong&gt;: Validates the &lt;code&gt;userId&lt;/code&gt; and sets &lt;code&gt;isValid&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ComputeScore Rule&lt;/strong&gt;: Depends on &lt;code&gt;CheckUser&lt;/code&gt; (via &lt;code&gt;isValid&lt;/code&gt;) and computes a credit score if the user is valid. It triggers a &lt;code&gt;Finalize&lt;/code&gt; rule (not shown) on success.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Management&lt;/strong&gt;: LWRE’s &lt;code&gt;RuleGraphProcessor&lt;/code&gt; ensures &lt;code&gt;CheckUser&lt;/code&gt; runs before &lt;code&gt;ComputeScore&lt;/code&gt; by building a DAG.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global &amp;amp; Helper&lt;/strong&gt;: Shared variables (&lt;code&gt;userId&lt;/code&gt;, &lt;code&gt;creditThreshold&lt;/code&gt;) and a reusable &lt;code&gt;computeCreditScore&lt;/code&gt; method are defined globally.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Running the Workflow
&lt;/h3&gt;

&lt;p&gt;Here’s how to execute this in Java:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.pulse.lwre.core.LWREngine&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Load DSL from file or string (dslContent)&lt;/span&gt;
        &lt;span class="nc"&gt;LWREngine&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LWREngine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dslContent&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;global&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"userId"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"john_doe"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;global&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"creditThreshold"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Enable tracing&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Execute synchronously&lt;/span&gt;
        &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeRules&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UserWorkflow"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Result: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Or execute asynchronously&lt;/span&gt;
        &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeRulesAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UserWorkflow"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenAccept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Async Result: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exceptionally&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;throwable&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;throwable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="o"&gt;});&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Output
&lt;/h3&gt;

&lt;p&gt;Assuming the DSL is loaded and executed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Computed score for john_doe: 350
Result: 350
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advanced Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dependency Management
&lt;/h3&gt;

&lt;p&gt;LWRE’s &lt;code&gt;RuleGraphProcessor&lt;/code&gt; uses topological sorting to determine rule execution order based on dependencies (e.g., &lt;code&gt;#USE ... FROM&lt;/code&gt; directives). It detects cycles to prevent infinite loops, ensuring robust workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Circuit Breaker
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;CircuitBreaker&lt;/code&gt; class monitors rule failures. If a rule exceeds a failure threshold, it temporarily halts execution, preventing system overload. This is critical for high-throughput systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance Optimizations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cached Compilation&lt;/strong&gt;: Rules are compiled once and cached, reducing overhead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Precomputed Paths&lt;/strong&gt;: Execution order is precomputed using DAGs, minimizing runtime decisions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread-Local Pools&lt;/strong&gt;: Context maps are reused to reduce memory allocation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallel Execution&lt;/strong&gt;: Independent rule groups run concurrently via &lt;code&gt;ForkJoinPool&lt;/code&gt;, with &lt;code&gt;ScheduledExecutorService&lt;/code&gt; enforcing timeouts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;p&gt;LWRE restricts access to dangerous classes (e.g., &lt;code&gt;java.lang.Runtime&lt;/code&gt;, &lt;code&gt;java.io.File&lt;/code&gt;) and methods (e.g., &lt;code&gt;exec&lt;/code&gt;, &lt;code&gt;exit&lt;/code&gt;). The &lt;code&gt;DSLParser&lt;/code&gt; validates syntax to prevent misuse, and timeouts ensure rules don’t hang.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Insights
&lt;/h2&gt;

&lt;p&gt;In internal tests, LWRE handles thousands of rules per second on a single thread, with parallel execution scaling linearly across cores. Compilation caching reduces rule execution latency by up to 80% after the first run. &lt;/p&gt;

&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Business Rules&lt;/strong&gt;: Implement pricing rules, discounts, or eligibility checks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Pipelines&lt;/strong&gt;: Validate and transform data in ETL processes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workflow Automation&lt;/strong&gt;: Coordinate tasks with dependencies and retries.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try LWRE Today!
&lt;/h2&gt;

&lt;p&gt;LWRE is a lightweight, powerful solution for dynamic rule execution in Java.It’s  secure  and optimized for performance. I invite you to explore the &lt;a href="https://github.com/HamdiGhassen/lwre" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;, try the examples, and contribute ideas or feedback. If you like what you see, a ⭐ on GitHub would help others discover this project! 🙌&lt;/p&gt;

&lt;p&gt;Have questions? Want to share how you’re using LWRE? Drop a comment below, open an issue on GitHub, or reach out to me directly. Let’s build something amazing together! 💻&lt;/p&gt;

</description>
      <category>java</category>
      <category>dsl</category>
      <category>ruleengine</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
