<?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>Forem: Yu Han</title>
    <description>The latest articles on Forem by Yu Han (@hannyu).</description>
    <link>https://forem.com/hannyu</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%2F3695478%2F1408961a-08f6-449c-ae0d-167d9795cb8f.jpg</url>
      <title>Forem: Yu Han</title>
      <link>https://forem.com/hannyu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hannyu"/>
    <language>en</language>
    <item>
      <title>SJF4J makes Java JSON Schema validation fast not just by validating quickly, but by avoiding the extra JSON-tree step entirely.</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Wed, 13 May 2026 08:40:39 +0000</pubDate>
      <link>https://forem.com/hannyu/sjf4j-makes-java-json-schema-validation-fast-not-just-by-validating-quickly-but-by-avoiding-the-1jdn</link>
      <guid>https://forem.com/hannyu/sjf4j-makes-java-json-schema-validation-fast-not-just-by-validating-quickly-but-by-avoiding-the-1jdn</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/hannyu/is-sjf4j-the-fastest-json-schema-validator-for-java-fhb" class="crayons-story__hidden-navigation-link"&gt;Is SJF4J the fastest JSON Schema validator for Java?&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/hannyu" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3695478%2F1408961a-08f6-449c-ae0d-167d9795cb8f.jpg" alt="hannyu profile" class="crayons-avatar__image" width="96" height="96"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/hannyu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Yu Han
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Yu Han
                
              
              &lt;div id="story-author-preview-content-3661399" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/hannyu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3695478%2F1408961a-08f6-449c-ae0d-167d9795cb8f.jpg" class="crayons-avatar__image" alt="" width="96" height="96"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Yu Han&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/hannyu/is-sjf4j-the-fastest-json-schema-validator-for-java-fhb" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;May 13&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/hannyu/is-sjf4j-the-fastest-json-schema-validator-for-java-fhb" id="article-link-3661399"&gt;
          Is SJF4J the fastest JSON Schema validator for Java?
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/java"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;java&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/jsonschema"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;jsonschema&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/performance"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;performance&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/hannyu/is-sjf4j-the-fastest-json-schema-validator-for-java-fhb" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt; reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/hannyu/is-sjf4j-the-fastest-json-schema-validator-for-java-fhb#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Is SJF4J the fastest JSON Schema validator for Java?</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Wed, 13 May 2026 08:38:55 +0000</pubDate>
      <link>https://forem.com/hannyu/is-sjf4j-the-fastest-json-schema-validator-for-java-fhb</link>
      <guid>https://forem.com/hannyu/is-sjf4j-the-fastest-json-schema-validator-for-java-fhb</guid>
      <description>&lt;p&gt;If you benchmark JSON Schema validators in Java, one question matters more than it first appears:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;does the validator work directly on your Java object graph, or does it first force you through a JSON tree?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SJF4J is built around the first path.&lt;/p&gt;

&lt;p&gt;That is why the recent independent benchmark work from Creek Service is interesting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22v202g2zo0p7s1vwnfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22v202g2zo0p7s1vwnfs.png" alt="validation performance" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because SJF4J's story is not just "we are fast".&lt;/p&gt;

&lt;p&gt;It is: &lt;strong&gt;we avoid work that many Java validation pipelines still force you to do.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  An independent signal worth paying attention to
&lt;/h2&gt;

&lt;p&gt;Creek Service maintains an independent comparison of JVM JSON Schema validators:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.creekservice.org/json-schema-validation-comparison/" rel="noopener noreferrer"&gt;JSON Schema validator comparison&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.creekservice.org/json-schema-validation-comparison/performance" rel="noopener noreferrer"&gt;Performance comparison&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What makes this benchmark especially useful is that it looks at validation from two angles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;pure validation&lt;/strong&gt; against the JSON Schema test suite&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;serde-style workflows&lt;/strong&gt;, where data is serialized, validated, read back, validated again, and deserialized&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first tells you whether a validator is strong at validation itself.&lt;br&gt;
The second tells you how it behaves in something much closer to a real application pipeline.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why this is good news for SJF4J
&lt;/h2&gt;

&lt;p&gt;Creek Service's results reinforce two things SJF4J has been designed around from the start.&lt;/p&gt;
&lt;h3&gt;
  
  
  1) SJF4J is fast at pure validation
&lt;/h3&gt;

&lt;p&gt;First: SJF4J is simply strong at &lt;strong&gt;pure validation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That matters because the baseline job of a validator is still the same:&lt;/p&gt;

&lt;p&gt;if you already have the schema and already have the data, validation should be fast and boring.&lt;/p&gt;

&lt;p&gt;That alone already puts it in very serious company.&lt;/p&gt;
&lt;h3&gt;
  
  
  2) SJF4J gets more interesting as the workflow gets more real
&lt;/h3&gt;

&lt;p&gt;This is the part that makes SJF4J more than just another validator with a benchmark chart.&lt;/p&gt;

&lt;p&gt;Most validators are still easiest to understand as &lt;strong&gt;JSON validators&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;SJF4J is better understood as a &lt;strong&gt;structural data processor for Java object graphs&lt;/strong&gt; that also includes JSON Schema validation.&lt;/p&gt;

&lt;p&gt;Instead, it can validate directly over:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Map&lt;/code&gt; / &lt;code&gt;List&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POJO&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JOJO&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;other OBNT-compatible object graphs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when your application is already working with Java objects, SJF4J does &lt;strong&gt;not&lt;/strong&gt; need an extra parse/build pass just to begin validation.&lt;/p&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;less conversion, less representation switching, less wasted work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And that is exactly the kind of advantage that shows up in serde-style benchmarks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptqzho3z8o1oen3e8j0e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptqzho3z8o1oen3e8j0e.png" alt="serde benchmark chart" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Why this matters beyond benchmark screenshots
&lt;/h2&gt;

&lt;p&gt;Because the real question is not just:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;who wins a benchmark?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is also:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;who forces the least unnecessary work into my application?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In many Java systems, validation is not an isolated toy benchmark. It sits inside a larger flow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP request handling&lt;/li&gt;
&lt;li&gt;event ingestion&lt;/li&gt;
&lt;li&gt;Kafka or queue consumers&lt;/li&gt;
&lt;li&gt;persistence pipelines&lt;/li&gt;
&lt;li&gt;DTO ↔ domain transformations&lt;/li&gt;
&lt;li&gt;configuration or document processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your validation layer keeps forcing this shape:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;POJO -&amp;gt; JSON/tree -&amp;gt; validation -&amp;gt; POJO/domain&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;then the validator is only part of the cost story.&lt;/p&gt;

&lt;p&gt;SJF4J reduces that friction by keeping validation inside the same structural processing model used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;parsing&lt;/li&gt;
&lt;li&gt;navigating&lt;/li&gt;
&lt;li&gt;patching&lt;/li&gt;
&lt;li&gt;mapping&lt;/li&gt;
&lt;li&gt;validating&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That gives you a simpler developer model and, very often, a faster runtime path.&lt;/p&gt;
&lt;h2&gt;
  
  
  A quick example
&lt;/h2&gt;

&lt;p&gt;With SJF4J, schema validation can sit directly on top of a Java model:&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="nd"&gt;@ValidJsonSchema&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""
{
  "type": "object",
  "required": ["id", "email"],
  "properties": {
    "id": { "type": "integer" },
    "email": { "type": "string", "format": "email" }
  }
}
"""&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;UserDto&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;SchemaValidator&lt;/span&gt; &lt;span class="n"&gt;validator&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;SchemaValidator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;ValidationResult&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;validator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userDto&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or you can compile a reusable schema plan explicitly and validate native Java data directly:&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="nc"&gt;JsonSchema&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JsonSchema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""
{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "age": { "type": "integer", "minimum": 0 }
  },
  "required": ["name"]
}
"""&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;SchemaPlan&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createPlan&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ada"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"age"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isValid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key point is not just the API.&lt;/p&gt;

&lt;p&gt;The key point is this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;validation happens over the object graph you already have.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SJF4J is not just a validator benchmark story
&lt;/h2&gt;

&lt;p&gt;Another reason this matters: SJF4J is not a one-feature library.&lt;/p&gt;

&lt;p&gt;It provides one structural model and one API family across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON / YAML / Properties parsing&lt;/li&gt;
&lt;li&gt;JSON Path navigation&lt;/li&gt;
&lt;li&gt;JSON Patch / Merge Patch processing&lt;/li&gt;
&lt;li&gt;JSON Schema validation&lt;/li&gt;
&lt;li&gt;object graph mapping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if your application needs more than "just validate a schema", SJF4J can simplify more of the pipeline instead of becoming one more isolated dependency with one narrow responsibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to look next
&lt;/h2&gt;

&lt;p&gt;If you want to explore SJF4J further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/sjf4j-projects/sjf4j" rel="noopener noreferrer"&gt;sjf4j-projects/sjf4j&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://sjf4j.org" rel="noopener noreferrer"&gt;https://sjf4j.org&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Validation guide: &lt;a href="https://sjf4j.org/docs/validating" rel="noopener noreferrer"&gt;https://sjf4j.org/docs/validating&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Benchmarks: &lt;a href="https://sjf4j.org/docs/benchmarks" rel="noopener noreferrer"&gt;https://sjf4j.org/docs/benchmarks&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you want the benchmark context directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creek Service comparison: &lt;a href="https://www.creekservice.org/json-schema-validation-comparison/" rel="noopener noreferrer"&gt;https://www.creekservice.org/json-schema-validation-comparison/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Creek Service performance page: &lt;a href="https://www.creekservice.org/json-schema-validation-comparison/performance" rel="noopener noreferrer"&gt;https://www.creekservice.org/json-schema-validation-comparison/performance&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final takeaway
&lt;/h2&gt;

&lt;p&gt;Creek Service's independent benchmark is a good reminder that JSON Schema performance is not only about raw validation speed.&lt;/p&gt;

&lt;p&gt;It is also about &lt;strong&gt;how much extra work your validation architecture forces you to do&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;SJF4J performs well in pure validation.&lt;/p&gt;

&lt;p&gt;But the more important point is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;when your data is already in Java object graphs, validating those object graphs directly is often the better design.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the design SJF4J is built around.&lt;/p&gt;

&lt;p&gt;And that may be exactly why it feels so fast in real Java workloads.&lt;/p&gt;

</description>
      <category>java</category>
      <category>jsonschema</category>
      <category>opensource</category>
      <category>performance</category>
    </item>
    <item>
      <title>Stop switching between POJO and JsonNode in Java. 
What if your objects themselves were the JSON tree?</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Sun, 26 Apr 2026 13:31:15 +0000</pubDate>
      <link>https://forem.com/hannyu/stop-switching-between-pojo-and-jsonnode-in-java-what-if-your-objects-themselves-were-the-json-3anm</link>
      <guid>https://forem.com/hannyu/stop-switching-between-pojo-and-jsonnode-in-java-what-if-your-objects-themselves-were-the-json-3anm</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/hannyu/beyond-pojo-and-jsonnode-a-more-cohesive-way-to-handle-json-in-java-j4a" class="crayons-story__hidden-navigation-link"&gt;Beyond POJO and JsonNode: A More Cohesive Way to Handle JSON in Java&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/hannyu" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3695478%2F1408961a-08f6-449c-ae0d-167d9795cb8f.jpg" alt="hannyu profile" class="crayons-avatar__image" width="96" height="96"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/hannyu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Yu Han
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Yu Han
                
              
              &lt;div id="story-author-preview-content-3553364" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/hannyu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3695478%2F1408961a-08f6-449c-ae0d-167d9795cb8f.jpg" class="crayons-avatar__image" alt="" width="96" height="96"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Yu Han&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/hannyu/beyond-pojo-and-jsonnode-a-more-cohesive-way-to-handle-json-in-java-j4a" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 26&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/hannyu/beyond-pojo-and-jsonnode-a-more-cohesive-way-to-handle-json-in-java-j4a" id="article-link-3553364"&gt;
          Beyond POJO and JsonNode: A More Cohesive Way to Handle JSON in Java
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/java"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;java&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/json"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;json&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/hannyu/beyond-pojo-and-jsonnode-a-more-cohesive-way-to-handle-json-in-java-j4a" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt; reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/hannyu/beyond-pojo-and-jsonnode-a-more-cohesive-way-to-handle-json-in-java-j4a#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Beyond POJO and JsonNode: A More Cohesive Way to Handle JSON in Java</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Sun, 26 Apr 2026 13:24:54 +0000</pubDate>
      <link>https://forem.com/hannyu/beyond-pojo-and-jsonnode-a-more-cohesive-way-to-handle-json-in-java-j4a</link>
      <guid>https://forem.com/hannyu/beyond-pojo-and-jsonnode-a-more-cohesive-way-to-handle-json-in-java-j4a</guid>
      <description>&lt;p&gt;Jackson is excellent at binding JSON to POJOs, but in real projects, JSON handling rarely ends at deserialization. After binding, we often still need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;query nested fields&lt;/li&gt;
&lt;li&gt;preserve unknown properties&lt;/li&gt;
&lt;li&gt;apply partial updates&lt;/li&gt;
&lt;li&gt;validate data against JSON Schema&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is when many codebases begin to bounce between two models—and the cost is not just conceptual, but structural.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;POJO&lt;/strong&gt; for typed business logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;JsonNode&lt;/code&gt;&lt;/strong&gt; for structural operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every transition between POJO and JsonNode introduces friction: data copying, lost type information, or duplicated logic.&lt;/p&gt;

&lt;p&gt;This article focuses on a question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If Jackson already handles JSON-to-POJO mapping well, why do we still end up converting back to &lt;code&gt;JsonNode&lt;/code&gt; for path access, patching, or validation?&lt;br&gt;&lt;br&gt;
And more importantly: what if we didn’t have to switch models at all?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where the friction starts
&lt;/h2&gt;

&lt;p&gt;A POJO is great for representing a stable Java model. But operations like JSON Path, JSON Patch, and JSON Schema are inherently structural.&lt;/p&gt;

&lt;p&gt;That leads to a familiar pattern:&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="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is clean and natural. But later, requirements change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we need to read &lt;code&gt;$.customer.address.city&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;PATCH&lt;/code&gt; request updates &lt;code&gt;/items/0/price&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;the payload contains fields the POJO does not declare&lt;/li&gt;
&lt;li&gt;validation rules are described as JSON Schema rather than Java annotations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the code shifts to tree mode:&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="nc"&gt;JsonNode&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readTree&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"customer"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"address"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"city"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;asText&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works too. The problem is not either API on its own. The real friction comes from &lt;strong&gt;switching models inside the same workflow&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Over time, the codebase becomes fragmented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business logic talks in fields and getters&lt;/li&gt;
&lt;li&gt;structural logic talks in tree nodes&lt;/li&gt;
&lt;li&gt;patching introduces another abstraction&lt;/li&gt;
&lt;li&gt;validation may rely on yet another model&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A more cohesive direction
&lt;/h2&gt;

&lt;p&gt;In most JSON libraries, once the workflow becomes structural, we usually move into a dedicated tree model such as &lt;code&gt;JsonNode&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;SJF4J takes a different route: it removes the need for a separate tree model altogether.&lt;br&gt;&lt;br&gt;
Instead of introducing an AST like JsonNode, it treats ordinary Java objects themselves as nodes in a JSON-semantic tree.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faok519upljr4nocdw55b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faok519upljr4nocdw55b.png" alt="Figure: OBNT lets plain Java objects participate directly in a JSON-semantic tree, instead of forcing everything into a separate AST first." width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In practice, that means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a JSON object can be represented by &lt;code&gt;Map&lt;/code&gt;, &lt;code&gt;JsonObject&lt;/code&gt;, &lt;code&gt;POJO&lt;/code&gt;, or &lt;code&gt;JOJO&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a JSON array can be represented by &lt;code&gt;List&lt;/code&gt;, &lt;code&gt;JsonArray&lt;/code&gt;, Java arrays, or &lt;code&gt;Set&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a JSON value can be represented by &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Number&lt;/code&gt;, &lt;code&gt;Boolean&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt;, or adapted value types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the key design move.&lt;/p&gt;

&lt;p&gt;Once these runtime objects participate in the same structural model, operations such as JsonPath, JsonPatch, and JsonSchema no longer need a separate tree representation in order to work. The object graph itself becomes the thing we navigate, patch, validate, and map.&lt;/p&gt;

&lt;p&gt;So the real shift is not just “one more JSON library.” It is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;instead of switching from Java objects to a JSON tree when the workflow becomes more structural,&lt;br&gt;&lt;br&gt;
SJF4J keeps the object graph itself structurally available from the beginning.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Why JOJO is a useful middle ground
&lt;/h2&gt;

&lt;p&gt;One practical consequence of OBNT is &lt;strong&gt;JOJO&lt;/strong&gt;: a typed Java object that also behaves like a JSON object.&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;items&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;p&gt;Then you can work with the same object in multiple ways:&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="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&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;Sjf4j&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;                                     &lt;span class="c1"&gt;// typed access&lt;/span&gt;
&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getStringByPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.customer.address.city"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// path access&lt;/span&gt;
&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sourceSystem"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;                   &lt;span class="c1"&gt;// dynamic property&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful because many real payloads are only &lt;strong&gt;mostly stable&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In practice, upstream systems evolve faster than your Java model.&lt;/p&gt;

&lt;p&gt;Some fields belong to the core Java model. Others are optional, evolving, or owned by upstream systems. A plain POJO can feel too closed for that. A raw tree can feel too loose. JOJO sits comfortably in between.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small example
&lt;/h2&gt;

&lt;p&gt;Imagine an external order payload like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A1001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Shanghai"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"P1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sourceSystem"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"partner-x"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a closed POJO model, &lt;code&gt;sourceSystem&lt;/code&gt; may be ignored unless it is modeled explicitly.&lt;/p&gt;

&lt;p&gt;With JOJO:&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="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sourceSystem"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getStringByPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.customer.address.city"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is a small difference in code, but a big difference in modeling style: typed fields and flexible JSON-style access can live together.&lt;/p&gt;

&lt;h2&gt;
  
  
  JsonPath becomes more than a convenience
&lt;/h2&gt;

&lt;p&gt;Because the object graph itself is navigable, JsonPath is no longer an add-on—it becomes a natural way to interact with your data.&lt;/p&gt;

&lt;p&gt;With direct field access:&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="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCustomer&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAddress&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCity&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is perfectly fine when the structure is fixed and shallow.&lt;/p&gt;

&lt;p&gt;But once the data becomes deeper, more dynamic, or only partially known, path-based access can be much cleaner:&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="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getStringByPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.customer.address.city"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also scales naturally to bulk queries:&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="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.items[*].price"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or filtered queries:&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="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;skus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.items[?@.price &amp;gt;= 100].sku"&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="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No, this is not the same as direct field access in absolute raw speed. But that trade-off is often worth it. Like many higher-level abstractions in Java, it introduces some overhead while saving code, reducing traversal boilerplate, and improving flexibility.&lt;/p&gt;

&lt;p&gt;Learn more → &lt;a href="https://sjf4j.org/docs/navigating" rel="noopener noreferrer"&gt;Navigating (JSON Path)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Patch fits naturally too
&lt;/h2&gt;

&lt;p&gt;Once the object graph is treated structurally, patching no longer feels bolted on.&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="nc"&gt;JsonPatch&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JsonPatch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""
[
  { "op": "replace", "path": "/customer/name", "value": "Alice Zhang" },
  { "op": "add", "path": "/items/0/discount", "value": 15 }
]
"""&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or direct path mutation:&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="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ensurePutByPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.shipping.trackingNo"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"SF123456"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is especially useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP PATCH endpoints&lt;/li&gt;
&lt;li&gt;partial state updates&lt;/li&gt;
&lt;li&gt;integration events&lt;/li&gt;
&lt;li&gt;targeted nested mutations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn more → &lt;a href="https://sjf4j.org/docs/patching" rel="noopener noreferrer"&gt;Patching (JSON Patch)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Validation stays in the same flow
&lt;/h2&gt;

&lt;p&gt;Schema validation also becomes easier to place in the workflow when it operates on the same runtime structure:&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="nc"&gt;SchemaValidator&lt;/span&gt; &lt;span class="n"&gt;validator&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;SchemaValidator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;isValid&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The benefit is not only fewer conversion steps. More importantly, query, mutation, and validation all operate with the same structural semantics.&lt;/p&gt;

&lt;p&gt;Learn more → &lt;a href="https://sjf4j.org/docs/validating" rel="noopener noreferrer"&gt;Validating (JSON Schema)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;JSON in Java is not just about converting strings into objects.&lt;/p&gt;

&lt;p&gt;It is about how those objects participate in the rest of your system.&lt;/p&gt;

&lt;p&gt;By treating ordinary objects as part of a JSON-semantic tree, SJF4J removes an entire layer of indirection—and with it, a surprising amount of complexity.&lt;/p&gt;

&lt;p&gt;Project links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/sjf4j-projects/sjf4j" rel="noopener noreferrer"&gt;https://github.com/sjf4j-projects/sjf4j&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://sjf4j.org" rel="noopener noreferrer"&gt;https://sjf4j.org&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>json</category>
      <category>opensource</category>
    </item>
    <item>
      <title>A new jsonschema2jojo online tool!</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Tue, 21 Apr 2026 00:08:37 +0000</pubDate>
      <link>https://forem.com/hannyu/a-new-jsonschema2jojo-online-tool-1leh</link>
      <guid>https://forem.com/hannyu/a-new-jsonschema2jojo-online-tool-1leh</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/hannyu/generating-java-from-json-schema-6kf" class="crayons-story__hidden-navigation-link"&gt;Generating Java from JSON Schema&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/hannyu" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3695478%2F1408961a-08f6-449c-ae0d-167d9795cb8f.jpg" alt="hannyu profile" class="crayons-avatar__image" width="96" height="96"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/hannyu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Yu Han
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Yu Han
                
              
              &lt;div id="story-author-preview-content-3525686" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/hannyu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3695478%2F1408961a-08f6-449c-ae0d-167d9795cb8f.jpg" class="crayons-avatar__image" alt="" width="96" height="96"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Yu Han&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/hannyu/generating-java-from-json-schema-6kf" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 20&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/hannyu/generating-java-from-json-schema-6kf" id="article-link-3525686"&gt;
          Generating Java from JSON Schema
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/java"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;java&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/jsonschema"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;jsonschema&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/productivity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;productivity&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/hannyu/generating-java-from-json-schema-6kf" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt; reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/hannyu/generating-java-from-json-schema-6kf#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Tue, 21 Apr 2026 00:06:28 +0000</pubDate>
      <link>https://forem.com/hannyu/-2efp</link>
      <guid>https://forem.com/hannyu/-2efp</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/hannyu/generating-java-from-json-schema-6kf" class="crayons-story__hidden-navigation-link"&gt;Generating Java from JSON Schema&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/hannyu" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3695478%2F1408961a-08f6-449c-ae0d-167d9795cb8f.jpg" alt="hannyu profile" class="crayons-avatar__image" width="96" height="96"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/hannyu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Yu Han
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Yu Han
                
              
              &lt;div id="story-author-preview-content-3525686" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/hannyu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3695478%2F1408961a-08f6-449c-ae0d-167d9795cb8f.jpg" class="crayons-avatar__image" alt="" width="96" height="96"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Yu Han&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/hannyu/generating-java-from-json-schema-6kf" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 20&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/hannyu/generating-java-from-json-schema-6kf" id="article-link-3525686"&gt;
          Generating Java from JSON Schema
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/java"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;java&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/jsonschema"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;jsonschema&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/productivity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;productivity&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/hannyu/generating-java-from-json-schema-6kf" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt; reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/hannyu/generating-java-from-json-schema-6kf#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Generating Java from JSON Schema</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Mon, 20 Apr 2026 08:01:06 +0000</pubDate>
      <link>https://forem.com/hannyu/generating-java-from-json-schema-6kf</link>
      <guid>https://forem.com/hannyu/generating-java-from-json-schema-6kf</guid>
      <description>&lt;p&gt;A new browser-based tool on &lt;strong&gt;&lt;a href="https://sjf4j.org/generator" rel="noopener noreferrer"&gt;sjf4j.org&lt;/a&gt;&lt;/strong&gt; turns JSON Schema into Java scaffolding directly in the browser.&lt;/p&gt;

&lt;p&gt;Paste a schema, tune the generation strategy, and get Java output immediately.&lt;/p&gt;

&lt;p&gt;What makes it more interesting than a basic schema-to-POJO converter is that it exposes modeling decisions directly.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Schema-to-code is not only about mapping types. It is also about deciding what should become part of a stable Java API, and what should remain flexible.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Try it here
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;Tool:&lt;/strong&gt; &lt;a href="https://sjf4j.org/generator" rel="noopener noreferrer"&gt;https://sjf4j.org/generator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhaz9uc2eqfcjffaeedoa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhaz9uc2eqfcjffaeedoa.png" alt="Screenshot goes here" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What the tool does
&lt;/h2&gt;

&lt;p&gt;The generator is a browser-based playground for turning JSON Schema into Java scaffolding.&lt;/p&gt;

&lt;p&gt;It currently supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;package and class name configuration&lt;/li&gt;
&lt;li&gt;primitive / number / date-time mapping choices&lt;/li&gt;
&lt;li&gt;string enum → Java enum generation&lt;/li&gt;
&lt;li&gt;nested object → inner class generation&lt;/li&gt;
&lt;li&gt;required-field-aware generation&lt;/li&gt;
&lt;li&gt;validation annotations such as &lt;code&gt;@NotNull&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;JavaDoc generation from schema metadata&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allOf&lt;/code&gt; flattening for object schemas&lt;/li&gt;
&lt;li&gt;local &lt;code&gt;$ref&lt;/code&gt; expansion&lt;/li&gt;
&lt;li&gt;deterministic import and member ordering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the strongest parts of the tool is its customization model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;global configuration&lt;/strong&gt; for overall generation behavior&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;property-by-property overrides&lt;/strong&gt; in the &lt;strong&gt;Parsed Properties&lt;/strong&gt; panel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the tool does not force one all-or-nothing rule across the whole schema. A project can start with a global baseline, then adjust selected members one by one.&lt;/p&gt;
&lt;h2&gt;
  
  
  A simple example
&lt;/h2&gt;

&lt;p&gt;Given a schema like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://json-schema.org/draft/2020-12/schema"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Order"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Checkout order created by the storefront."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"createdAt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Business order identifier."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Total amount in the settlement currency."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"createdAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"date-time"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"paid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"boolean"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"array"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"quantity"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"integer"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the default JOJO-oriented settings, the generated Java can look like this:&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="nd"&gt;@Getter&lt;/span&gt; &lt;span class="nd"&gt;@Setter&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;Order&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/**
     * JSON shape:
     * &amp;lt;pre&amp;gt;
     * {
     *   "id": "string",
     *   "amount": "number",
     *   "createdAt": "string(date-time)",
     *   "paid": "boolean",
     *   "customer": {
     *     "id": "string",
     *     "email": "string"
     *   },
     *   "items": [
     *     {
     *       "sku": "string",
     *       "quantity": "integer"
     *     }
     *   ]
     * }
     * &amp;lt;/pre&amp;gt;
     */&lt;/span&gt;
    &lt;span class="nd"&gt;@NotNull&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;@NotNull&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;@NotNull&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;OffsetDateTime&lt;/span&gt; &lt;span class="n"&gt;createdAt&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;paid&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;@NotNull&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;@NotNull&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ItemsItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;JsonPath&lt;/span&gt; &lt;span class="no"&gt;PATH_CUSTOMER_EMAIL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JsonPath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.customer.email"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getCustomerEmail&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;PATH_CUSTOMER_EMAIL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getItemsSku&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;itemsIndex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;getStringByPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.items["&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;itemsIndex&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"].sku"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Getter&lt;/span&gt; &lt;span class="nd"&gt;@Setter&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Customer&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;@NotNull&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nd"&gt;@NotNull&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Getter&lt;/span&gt; &lt;span class="nd"&gt;@Setter&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ItemsItem&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;@NotNull&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sku&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nd"&gt;@NotNull&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;quantity&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;p&gt;This is closer to a real API shape: nested objects, arrays, required members, generated inner classes, validation annotations, and root-level path accessors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why modeling choices matter
&lt;/h2&gt;

&lt;p&gt;The generator is not designed as a “turn every JSON property into a field” machine.&lt;/p&gt;

&lt;p&gt;In real systems, the harder question is usually:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which parts of this schema should become a stable Java contract, and which parts should stay flexible?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is why the tool exposes decisions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JOJO vs POJO&lt;/strong&gt; modeling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;field vs property&lt;/strong&gt; generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;path accessor&lt;/strong&gt; generation on the root model&lt;/li&gt;
&lt;li&gt;per-property type overrides&lt;/li&gt;
&lt;li&gt;global defaults plus property-by-property adjustments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters when the input schema comes from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a third-party API that changes often&lt;/li&gt;
&lt;li&gt;an event payload with optional extension fields&lt;/li&gt;
&lt;li&gt;an internal contract that is stable in some places and fluid in others&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why JOJO is interesting here
&lt;/h2&gt;

&lt;p&gt;This generator is part of the broader &lt;strong&gt;SJF4J&lt;/strong&gt; ecosystem, so it can generate models that fit naturally into SJF4J’s structural APIs.&lt;/p&gt;

&lt;p&gt;If an object is modeled as a &lt;strong&gt;JOJO&lt;/strong&gt;, it extends &lt;code&gt;org.sjf4j.JsonObject&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That gives you an interesting hybrid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;typed Java members where you want a stable contract&lt;/li&gt;
&lt;li&gt;dynamic JSON-style access where you still need flexibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, the generator can produce root-level descendant accessors such as:&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="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getCustomerEmail&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;PATH_CUSTOMER_EMAIL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getItemsSku&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;itemsIndex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;getStringByPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.items["&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;itemsIndex&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"].sku"&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;p&gt;That is a different direction from classic schema-to-POJO generators. It is useful when the generated model is not just a DTO, but part of a larger JSON-processing workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Global configuration and per-property tuning
&lt;/h2&gt;

&lt;p&gt;Customization happens at two levels.&lt;/p&gt;

&lt;p&gt;At the &lt;strong&gt;global&lt;/strong&gt; level, the generator can define the overall baseline for a file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;package and class name&lt;/li&gt;
&lt;li&gt;JOJO or POJO preference&lt;/li&gt;
&lt;li&gt;field-generation strategy&lt;/li&gt;
&lt;li&gt;accessor strategy&lt;/li&gt;
&lt;li&gt;path-accessor strategy&lt;/li&gt;
&lt;li&gt;integer / number / boolean / enum / date-time mapping&lt;/li&gt;
&lt;li&gt;object-leaf mapping&lt;/li&gt;
&lt;li&gt;validation namespace and annotations&lt;/li&gt;
&lt;li&gt;JavaDoc generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the &lt;strong&gt;property&lt;/strong&gt; level, the Parsed Properties panel can refine specific members:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;switch between &lt;strong&gt;field&lt;/strong&gt; and &lt;strong&gt;property&lt;/strong&gt; generation&lt;/li&gt;
&lt;li&gt;override the generated &lt;strong&gt;Java type&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;enable or disable &lt;strong&gt;by-path getter/setter&lt;/strong&gt; generation for eligible paths&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That makes the tool flexible enough for mixed schemas, where most properties follow one rule but a few important members need a different Java contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this fits in SJF4J
&lt;/h2&gt;

&lt;p&gt;If you have not seen &lt;strong&gt;SJF4J&lt;/strong&gt; before, it is a &lt;strong&gt;unified JSON-semantic processing layer for Java&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It provides one structural model across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;parsing&lt;/li&gt;
&lt;li&gt;modeling&lt;/li&gt;
&lt;li&gt;JSON Path navigation&lt;/li&gt;
&lt;li&gt;JSON Patch / Merge Patch&lt;/li&gt;
&lt;li&gt;JSON Schema validation&lt;/li&gt;
&lt;li&gt;mapping / transformation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, that means you can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;start from a JSON Schema&lt;/li&gt;
&lt;li&gt;generate a Java model&lt;/li&gt;
&lt;li&gt;parse payloads into that model&lt;/li&gt;
&lt;li&gt;navigate it with JSON Path&lt;/li&gt;
&lt;li&gt;validate it with JSON Schema&lt;/li&gt;
&lt;li&gt;keep dynamic structure where needed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That end-to-end flow is why this generator fits naturally on the SJF4J site instead of being treated as an isolated utility.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few implementation details worth keeping explicit
&lt;/h2&gt;

&lt;p&gt;Some current baseline behaviors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nested object schemas generate as &lt;code&gt;public static&lt;/code&gt; inner classes&lt;/li&gt;
&lt;li&gt;nested enums are generated inside the owning class&lt;/li&gt;
&lt;li&gt;imports are deduplicated and sorted&lt;/li&gt;
&lt;li&gt;object &lt;code&gt;allOf&lt;/code&gt; is flattened before rendering&lt;/li&gt;
&lt;li&gt;circular local &lt;code&gt;$ref&lt;/code&gt; chains are rejected&lt;/li&gt;
&lt;li&gt;unsupported non-local &lt;code&gt;$ref&lt;/code&gt; is ignored for now&lt;/li&gt;
&lt;li&gt;root path accessors are generated only when the root model is a JOJO&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, the tool tries to be predictable first, and flexible second — but without hiding the rules.&lt;/p&gt;

&lt;p&gt;Another useful detail: &lt;strong&gt;the full generation rules are published on the page itself&lt;/strong&gt;. So the tool is not a black box. The page also works as a spec-like baseline and regression target: the rules are explicit enough to be reused as an AI prompt, allowing an LLM to reproduce a similar generator — or help design a more optimized one on top of the same contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is useful
&lt;/h2&gt;

&lt;p&gt;The practical value is simple: &lt;strong&gt;the first draft of a Java model should be fast to get, but not locked into the wrong abstraction too early.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you only need quick scaffolding, the generator already helps.&lt;/p&gt;

&lt;p&gt;If you care about long-term maintainability, the more useful part is that it makes the trade-offs visible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;strict vs flexible object modeling&lt;/li&gt;
&lt;li&gt;field-backed vs dynamic property-backed members&lt;/li&gt;
&lt;li&gt;plain DTO generation vs JSON-semantic access patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it and tell me what is missing
&lt;/h2&gt;

&lt;p&gt;If you want to try it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Generator:&lt;/strong&gt; &lt;a href="https://sjf4j.org/generator" rel="noopener noreferrer"&gt;https://sjf4j.org/generator&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SJF4J docs:&lt;/strong&gt; &lt;a href="https://sjf4j.org/docs/getting_started" rel="noopener noreferrer"&gt;https://sjf4j.org/docs/getting_started&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/sjf4j-projects/sjf4j" rel="noopener noreferrer"&gt;https://github.com/sjf4j-projects/sjf4j&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are already working with JSON Schema, Java DTO generation, or mixed typed/dynamic payloads, useful feedback would include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nullable handling&lt;/li&gt;
&lt;li&gt;multi-file output layout&lt;/li&gt;
&lt;li&gt;more &lt;code&gt;$ref&lt;/code&gt; composition cases&lt;/li&gt;
&lt;li&gt;better defaults for boxed vs primitive types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Schema-to-code is easy to automate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Designing good Java boundaries is still the hard part.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>jsonschema</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>SJF4J 1.2.0: Jackson 3 Support, Instance-Based Runtime, and More Predictable JSON Semantics</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Sun, 12 Apr 2026 00:13:48 +0000</pubDate>
      <link>https://forem.com/hannyu/sjf4j-120-jackson-3-support-instance-based-runtime-and-more-predictable-json-semantics-532b</link>
      <guid>https://forem.com/hannyu/sjf4j-120-jackson-3-support-instance-based-runtime-and-more-predictable-json-semantics-532b</guid>
      <description>&lt;p&gt;Java already has excellent JSON libraries. So why build another layer on top?&lt;/p&gt;

&lt;p&gt;Because in real applications, JSON work is rarely just "parse this string into a POJO". It quickly expands into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;navigating nested structures&lt;/li&gt;
&lt;li&gt;applying JSON Patch or Merge Patch&lt;/li&gt;
&lt;li&gt;validating with JSON Schema&lt;/li&gt;
&lt;li&gt;mapping between object graphs&lt;/li&gt;
&lt;li&gt;keeping behavior consistent across Jackson, Gson, Fastjson2, JSON-P, YAML, and in-memory nodes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the problem space SJF4J is trying to solve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SJF4J&lt;/strong&gt; is a lightweight structural processing framework for Java that provides a unified JSON-semantic layer across different backends and data shapes. It works with regular POJOs, dynamic JSON-like structures, JSON Path, JSON Patch, JSON Schema, and multiple runtime backends, while keeping the programming model consistent.&lt;/p&gt;

&lt;p&gt;Version &lt;strong&gt;1.2.0&lt;/strong&gt; is an important release. It adds &lt;strong&gt;Jackson 3 support&lt;/strong&gt;, introduces a cleaner &lt;strong&gt;instance-based runtime API&lt;/strong&gt;, and tightens semantic consistency in several areas that matter in production systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SJF4J Is
&lt;/h2&gt;

&lt;p&gt;SJF4J is not trying to replace Jackson or Gson.&lt;/p&gt;

&lt;p&gt;Instead, it sits one level above them and gives you a consistent structural API for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;modeling object-based node trees&lt;/li&gt;
&lt;li&gt;parsing JSON and YAML&lt;/li&gt;
&lt;li&gt;navigating with JSON Path and JSON Pointer&lt;/li&gt;
&lt;li&gt;patching with JSON Patch and Merge Patch&lt;/li&gt;
&lt;li&gt;validating with JSON Schema Draft 2020-12&lt;/li&gt;
&lt;li&gt;mapping across native object graphs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also supports runtime backend auto-detection, so the same SJF4J-facing code can work across multiple JSON libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s New in 1.2.0
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Jackson 3 support
&lt;/h3&gt;

&lt;p&gt;SJF4J 1.2.0 adds &lt;strong&gt;Jackson 3 facade integration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At runtime, SJF4J can automatically select an available backend in this priority order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jackson 3&lt;/li&gt;
&lt;li&gt;Jackson 2&lt;/li&gt;
&lt;li&gt;Gson&lt;/li&gt;
&lt;li&gt;Fastjson2&lt;/li&gt;
&lt;li&gt;JSON-P&lt;/li&gt;
&lt;li&gt;built-in simple fallback&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. &lt;code&gt;Sjf4j&lt;/code&gt; is now instance-based
&lt;/h2&gt;

&lt;p&gt;This is the biggest API change in 1.2.0.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Sjf4j.global()&lt;/code&gt; for shared process-wide defaults&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;new Sjf4j()&lt;/code&gt; for a fresh default instance&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Sjf4j.builder()&lt;/code&gt; for explicit runtime configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Migration example
&lt;/h3&gt;

&lt;p&gt;Before:&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="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Sjf4j&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After:&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="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Sjf4j&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="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want an isolated runtime instead of global defaults:&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="nc"&gt;Sjf4j&lt;/span&gt; &lt;span class="n"&gt;sjf4j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Sjf4j&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;jsonFacade&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;Jackson3JsonFacade&lt;/span&gt;&lt;span class="o"&gt;())&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="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sjf4j&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This change makes runtime configuration more explicit and easier to reason about, especially in applications that care about isolation, testing, or framework integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. &lt;code&gt;@NodeBinding&lt;/code&gt; makes POJO binding rules explicit
&lt;/h2&gt;

&lt;p&gt;Another important addition in 1.2.0 is &lt;code&gt;@NodeBinding&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It moves binding behavior like naming strategy and access policy onto the type itself, instead of relying on mutable global behavior.&lt;/p&gt;

&lt;p&gt;For example:&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="nd"&gt;@NodeBinding&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;naming&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NamingStrategy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SNAKE_CASE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserProfile&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;userName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;loginCount&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;p&gt;Now JSON like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"han"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"login_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can map cleanly without per-field annotations.&lt;/p&gt;

&lt;p&gt;You can also control access strategy:&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="nd"&gt;@NodeBinding&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AccessStrategy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FIELD_BASED&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PrivateUserProfile&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;userName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;loginCount&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;p&gt;This is a good example of SJF4J’s overall direction in 1.2.0: make semantics more explicit, cacheable, and predictable.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Better consistency for containers and object graph conversion
&lt;/h2&gt;

&lt;p&gt;SJF4J 1.2.0 improves how it handles concrete container types such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Map&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;List&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Set&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In previous edge cases, framework-level conversion could fall back to generic mutable containers even when more specific target container information was available. In 1.2.0, container metadata and factory paths are improved so declared concrete container implementations are preserved more consistently when supported.&lt;/p&gt;

&lt;p&gt;This matters when your application logic depends on more than just the abstract interface type.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. More correct behavior in Path, Patch, and Schema
&lt;/h2&gt;

&lt;p&gt;This release also includes a long list of semantic fixes across some of the hardest parts of structured data processing.&lt;/p&gt;

&lt;h3&gt;
  
  
  JSON Schema Draft 2020-12
&lt;/h3&gt;

&lt;p&gt;SJF4J already supports JSON Schema Draft 2020-12, and 1.2.0 improves several edge cases in compilation and validation, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unknown keywords and formats&lt;/li&gt;
&lt;li&gt;relative &lt;code&gt;$ref&lt;/code&gt; resolution&lt;/li&gt;
&lt;li&gt;local schemas without root &lt;code&gt;$id&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;null&lt;/code&gt; subschema handling&lt;/li&gt;
&lt;li&gt;Unicode code point length for strings&lt;/li&gt;
&lt;li&gt;stricter format checks for hostname, IPv6, URI template, and relative JSON Pointer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For teams using schema validation in production APIs, these details are much more important than flashy surface-level features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;p&gt;If you want to try it:&lt;/p&gt;

&lt;h3&gt;
  
  
  Gradle
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"org.sjf4j:sjf4j:1.2.0"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Maven
&lt;/h3&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.sjf4j&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;sjf4j&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;1.2.0&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;Then start with the global runtime:&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="nc"&gt;Sjf4j&lt;/span&gt; &lt;span class="n"&gt;sjf4j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Sjf4j&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="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sjf4j&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;SJF4J 1.2.0 feels like a solid step forward for Java developers who want a single structural programming model across different JSON backends and data-processing tasks.&lt;/p&gt;

&lt;p&gt;If your application only needs plain Jackson databinding, you probably do not need another abstraction layer.&lt;/p&gt;

&lt;p&gt;But if your system combines parsing, path navigation, patching, schema validation, dynamic fields, and backend flexibility, SJF4J is solving a real problem, and 1.2.0 makes that solution cleaner and more production-friendly.&lt;/p&gt;

&lt;p&gt;Project links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/sjf4j-projects/sjf4j" rel="noopener noreferrer"&gt;https://github.com/sjf4j-projects/sjf4j&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://sjf4j.org" rel="noopener noreferrer"&gt;https://sjf4j.org&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>json</category>
    </item>
    <item>
      <title>We benchmarked JSONPath in Java.
Result: up to **7x faster** — without changing your data model.</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Sun, 29 Mar 2026 02:42:55 +0000</pubDate>
      <link>https://forem.com/hannyu/we-benchmarked-jsonpath-in-javaresult-up-to-7x-faster-without-changing-your-data-model-2gfa</link>
      <guid>https://forem.com/hannyu/we-benchmarked-jsonpath-in-javaresult-up-to-7x-faster-without-changing-your-data-model-2gfa</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/hannyu/sjf4j-vs-jayway-jsonpath-up-to-7x-faster-in-java-benchmarks-2aof" class="crayons-story__hidden-navigation-link"&gt;SJF4J vs Jayway JsonPath: Up to 7x Faster in Java Benchmarks&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/hannyu" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3695478%2F1408961a-08f6-449c-ae0d-167d9795cb8f.jpg" alt="hannyu profile" class="crayons-avatar__image" width="96" height="96"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/hannyu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Yu Han
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Yu Han
                
              
              &lt;div id="story-author-preview-content-3422950" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/hannyu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3695478%2F1408961a-08f6-449c-ae0d-167d9795cb8f.jpg" class="crayons-avatar__image" alt="" width="96" height="96"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Yu Han&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/hannyu/sjf4j-vs-jayway-jsonpath-up-to-7x-faster-in-java-benchmarks-2aof" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 29&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/hannyu/sjf4j-vs-jayway-jsonpath-up-to-7x-faster-in-java-benchmarks-2aof" id="article-link-3422950"&gt;
          SJF4J vs Jayway JsonPath: Up to 7x Faster in Java Benchmarks
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/java"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;java&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/json"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;json&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/performance"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;performance&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/hannyu/sjf4j-vs-jayway-jsonpath-up-to-7x-faster-in-java-benchmarks-2aof#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>java</category>
      <category>json</category>
      <category>performance</category>
      <category>opensource</category>
    </item>
    <item>
      <title>SJF4J vs Jayway JsonPath: Up to 7x Faster in Java Benchmarks</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Sun, 29 Mar 2026 02:41:24 +0000</pubDate>
      <link>https://forem.com/hannyu/sjf4j-vs-jayway-jsonpath-up-to-7x-faster-in-java-benchmarks-2aof</link>
      <guid>https://forem.com/hannyu/sjf4j-vs-jayway-jsonpath-up-to-7x-faster-in-java-benchmarks-2aof</guid>
      <description>&lt;p&gt;We benchmarked JSONPath in Java.&lt;/p&gt;

&lt;p&gt;SJF4J: &lt;a href="https://github.com/sjf4j-projects/sjf4j" rel="noopener noreferrer"&gt;https://github.com/sjf4j-projects/sjf4j&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Jayway JsonPath: &lt;a href="https://github.com/json-path/JsonPath" rel="noopener noreferrer"&gt;https://github.com/json-path/JsonPath&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SJF4J is up to 7x faster.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here’s what we found.&lt;/p&gt;




&lt;h2&gt;
  
  
  Benchmark Setup
&lt;/h2&gt;

&lt;p&gt;We built a JMH benchmark suite comparing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SJF4J v1.5.0&lt;/li&gt;
&lt;li&gt;Jayway JsonPath v2.9.0 &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Across three workload shapes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Path compilation
&lt;/li&gt;
&lt;li&gt;Query on shared JsonNode
&lt;/li&gt;
&lt;li&gt;Query on Map/List object graphs
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JMH config:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;5 × 300ms warmup
&lt;/li&gt;
&lt;li&gt;8 × 300ms measurement
&lt;/li&gt;
&lt;li&gt;2 forks
&lt;/li&gt;
&lt;li&gt;1 thread
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Expressions used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;$.store.book[1].price&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$.store.bicycle.color&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$.store.book[*].author&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$..price&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$.store.book[?(@.price &amp;gt; 10)].title&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$.store.book[0,2].title&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Headline Results
&lt;/h2&gt;

&lt;p&gt;Geometric mean (lower is better):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Benchmark group&lt;/th&gt;
&lt;th&gt;SJF4J&lt;/th&gt;
&lt;th&gt;Jayway&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;compile&lt;/td&gt;
&lt;td&gt;97 ns/op&lt;/td&gt;
&lt;td&gt;125 ns/op&lt;/td&gt;
&lt;td&gt;SJF4J 1.28x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;query_definite&lt;/td&gt;
&lt;td&gt;100 ns/op&lt;/td&gt;
&lt;td&gt;237 ns/op&lt;/td&gt;
&lt;td&gt;SJF4J 2.38x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;query_indefinite&lt;/td&gt;
&lt;td&gt;656 ns/op&lt;/td&gt;
&lt;td&gt;1294 ns/op&lt;/td&gt;
&lt;td&gt;SJF4J 1.97x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;query_map_list_definite&lt;/td&gt;
&lt;td&gt;31 ns/op&lt;/td&gt;
&lt;td&gt;200 ns/op&lt;/td&gt;
&lt;td&gt;SJF4J 6.38x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;query_map_list_indefinite&lt;/td&gt;
&lt;td&gt;280 ns/op&lt;/td&gt;
&lt;td&gt;1301 ns/op&lt;/td&gt;
&lt;td&gt;SJF4J 4.65x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;~2x faster on typical queries
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;up to 7x faster on Map/List&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;faster compilation as well
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1) Query on Shared JsonNode
&lt;/h2&gt;

&lt;p&gt;This is the fairest comparison: both libraries query the same parsed tree.&lt;/p&gt;

&lt;h3&gt;
  
  
  Definite paths
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;SJF4J&lt;/th&gt;
&lt;th&gt;Jayway&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.book[1].price&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;111 ns/op&lt;/td&gt;
&lt;td&gt;260 ns/op&lt;/td&gt;
&lt;td&gt;2.35x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.bicycle.color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;90 ns/op&lt;/td&gt;
&lt;td&gt;216 ns/op&lt;/td&gt;
&lt;td&gt;2.40x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Indefinite paths
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;SJF4J&lt;/th&gt;
&lt;th&gt;Jayway&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.book[*].author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;342 ns/op&lt;/td&gt;
&lt;td&gt;910 ns/op&lt;/td&gt;
&lt;td&gt;2.66x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$..price&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1736 ns/op&lt;/td&gt;
&lt;td&gt;3877 ns/op&lt;/td&gt;
&lt;td&gt;2.23x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.book[?(@.price &amp;gt; 10)].title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1292 ns/op&lt;/td&gt;
&lt;td&gt;1660 ns/op&lt;/td&gt;
&lt;td&gt;1.29x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.book[0,2].title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;242 ns/op&lt;/td&gt;
&lt;td&gt;478 ns/op&lt;/td&gt;
&lt;td&gt;1.98x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Conclusion:&lt;/p&gt;

&lt;p&gt;SJF4J is consistently faster as a JSONPath engine.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 2) Query on Map/List Object Graphs
&lt;/h2&gt;

&lt;p&gt;This is where the gap becomes much larger.&lt;/p&gt;

&lt;p&gt;Both libraries support Map/List style object graphs, so this is still a fair comparison.&lt;/p&gt;

&lt;h3&gt;
  
  
  Definite paths
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;SJF4J&lt;/th&gt;
&lt;th&gt;Jayway&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.book[1].price&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;37 ns/op&lt;/td&gt;
&lt;td&gt;280 ns/op&lt;/td&gt;
&lt;td&gt;7.50x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.bicycle.color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;26 ns/op&lt;/td&gt;
&lt;td&gt;142 ns/op&lt;/td&gt;
&lt;td&gt;5.42x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Indefinite paths
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;SJF4J&lt;/th&gt;
&lt;th&gt;Jayway&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.book[*].author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;135 ns/op&lt;/td&gt;
&lt;td&gt;1045 ns/op&lt;/td&gt;
&lt;td&gt;7.73x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$..price&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;543 ns/op&lt;/td&gt;
&lt;td&gt;2495 ns/op&lt;/td&gt;
&lt;td&gt;4.59x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.book[?(@.price &amp;gt; 10)].title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;823 ns/op&lt;/td&gt;
&lt;td&gt;1836 ns/op&lt;/td&gt;
&lt;td&gt;2.23x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.book[0,2].title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;102 ns/op&lt;/td&gt;
&lt;td&gt;598 ns/op&lt;/td&gt;
&lt;td&gt;5.89x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Takeaway:&lt;/p&gt;

&lt;p&gt;If your application already works on Map/List object graphs,&lt;br&gt;&lt;br&gt;
this is the strongest result in the entire benchmark.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔥 3) Native Object Graphs: POJO / JOJO
&lt;/h2&gt;

&lt;p&gt;This is where SJF4J goes beyond traditional JSONPath libraries.&lt;/p&gt;

&lt;p&gt;Instead of forcing everything into a JSON AST, SJF4J runs directly on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Map / List
&lt;/li&gt;
&lt;li&gt;JOJO (JSON Object + Java Object hybrid)
&lt;/li&gt;
&lt;li&gt;POJO
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Jayway does not support this model natively.&lt;/p&gt;

&lt;p&gt;So here we compare SJF4J across different object representations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Geometric mean
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Benchmark group&lt;/th&gt;
&lt;th&gt;Map/List&lt;/th&gt;
&lt;th&gt;JOJO&lt;/th&gt;
&lt;th&gt;POJO&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;definite&lt;/td&gt;
&lt;td&gt;31 ns/op&lt;/td&gt;
&lt;td&gt;43 ns/op&lt;/td&gt;
&lt;td&gt;94 ns/op&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;indefinite&lt;/td&gt;
&lt;td&gt;270 ns/op&lt;/td&gt;
&lt;td&gt;373 ns/op&lt;/td&gt;
&lt;td&gt;554 ns/op&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Representative results
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;Map/List&lt;/th&gt;
&lt;th&gt;JOJO&lt;/th&gt;
&lt;th&gt;POJO&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.book[1].price&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;37 ns/op&lt;/td&gt;
&lt;td&gt;46 ns/op&lt;/td&gt;
&lt;td&gt;102 ns/op&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.bicycle.color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;26 ns/op&lt;/td&gt;
&lt;td&gt;40 ns/op&lt;/td&gt;
&lt;td&gt;87 ns/op&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.book[*].author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;131 ns/op&lt;/td&gt;
&lt;td&gt;196 ns/op&lt;/td&gt;
&lt;td&gt;374 ns/op&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$..price&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;496 ns/op&lt;/td&gt;
&lt;td&gt;914 ns/op&lt;/td&gt;
&lt;td&gt;955 ns/op&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$.store.book[?(@.price &amp;gt; 10)].title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;807 ns/op&lt;/td&gt;
&lt;td&gt;876 ns/op&lt;/td&gt;
&lt;td&gt;1100 ns/op&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What this shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Map/List is fastest (no abstraction)&lt;/li&gt;
&lt;li&gt;JOJO adds minimal overhead&lt;/li&gt;
&lt;li&gt;POJO is slower, but still practical&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key insight:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can run JSONPath directly on your domain model.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No conversion. No intermediate tree.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Means in Practice
&lt;/h2&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;POJO → JsonNode → JSONPath → result&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can do:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;POJO → JSONPath → result&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This removes an entire layer from your data processing pipeline.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Is SJF4J Faster?
&lt;/h2&gt;

&lt;p&gt;The performance difference mainly comes from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no forced conversion into a dedicated AST
&lt;/li&gt;
&lt;li&gt;direct execution on native Java object graphs
&lt;/li&gt;
&lt;li&gt;lower abstraction overhead in path evaluation
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short:&lt;/p&gt;

&lt;p&gt;SJF4J avoids work that other libraries must do first.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bottom Line
&lt;/h2&gt;

&lt;p&gt;Jayway is fine for basic JSONPath usage.&lt;/p&gt;

&lt;p&gt;But if performance matters, especially on Map/List or POJO object graphs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SJF4J is simply faster.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/sjf4j-projects/sjf4j" rel="noopener noreferrer"&gt;https://github.com/sjf4j-projects/sjf4j&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Benchmark source: JsonPathCompareBenchmark.java&lt;/p&gt;

</description>
      <category>java</category>
      <category>json</category>
      <category>performance</category>
      <category>opensource</category>
    </item>
    <item>
      <title>SJF4J: A Structured JSON Facade for Java</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Mon, 23 Mar 2026 11:17:34 +0000</pubDate>
      <link>https://forem.com/hannyu/sjf4j-a-structured-json-facade-for-java-2n0f</link>
      <guid>https://forem.com/hannyu/sjf4j-a-structured-json-facade-for-java-2n0f</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Working with JSON in Java usually means choosing between two approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data binding (POJO)&lt;/strong&gt; — strong typing, but rigid&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tree model (JsonNode / Map)&lt;/strong&gt; — flexible, but unstructured&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most libraries force you to pick one and live with the trade-offs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SJF4J (Simple JSON Facade for Java)&lt;/strong&gt; takes a different approach:&lt;br&gt;
it introduces a unified JSON-semantic layer that supports both structured and dynamic access — without locking you into a single model.&lt;/p&gt;


&lt;h2&gt;
  
  
  What SJF4J Is
&lt;/h2&gt;

&lt;p&gt;SJF4J is not a JSON parser.&lt;br&gt;
It is a &lt;strong&gt;facade layer&lt;/strong&gt; built on top of existing parsers (e.g., Jackson), providing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unified node model&lt;/li&gt;
&lt;li&gt;Structured + dynamic access&lt;/li&gt;
&lt;li&gt;Schema-aware capabilities&lt;/li&gt;
&lt;li&gt;JSON-semantic operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to make JSON handling more &lt;strong&gt;consistent, expressive, and extensible&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Core Idea: Unified Node Semantics
&lt;/h2&gt;

&lt;p&gt;In SJF4J, all JSON values are treated as &lt;strong&gt;nodes&lt;/strong&gt; with consistent behavior.&lt;/p&gt;

&lt;p&gt;You can operate on them via:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Object-oriented APIs (&lt;code&gt;JsonObject&lt;/code&gt;, &lt;code&gt;JsonArray&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Static utilities (&lt;code&gt;Nodes&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two access styles are supported:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;toXxx()&lt;/code&gt; → type-safe access&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;asXxx()&lt;/code&gt; → semantic conversion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This removes the need to constantly switch between parsing styles.&lt;/p&gt;


&lt;h2&gt;
  
  
  Structured + Dynamic in One Model
&lt;/h2&gt;

&lt;p&gt;A key feature is that SJF4J does not force a strict boundary between POJO and dynamic JSON.&lt;/p&gt;

&lt;p&gt;You can define structured fields while still allowing flexible extensions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;friends&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;p&gt;This is neither a traditional POJO nor a raw JSON tree — it’s a hybrid model.&lt;/p&gt;

&lt;p&gt;SJF4J calls this pattern &lt;strong&gt;JOJO (JSON Object Java Object)&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Path and Patch Support
&lt;/h2&gt;

&lt;p&gt;SJF4J includes built-in support for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON Path-like navigation&lt;/li&gt;
&lt;li&gt;Patch-style updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows you to manipulate deeply nested structures without manual traversal.&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="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putByPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.profile.name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Schema Integration
&lt;/h2&gt;

&lt;p&gt;SJF4J integrates JSON Schema as a runtime concept:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validate data dynamically&lt;/li&gt;
&lt;li&gt;Support conditional rules&lt;/li&gt;
&lt;li&gt;Separate domain invariants from runtime constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This complements traditional validation approaches like Jakarta Bean Validation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Not Just Use Jackson or Gson?
&lt;/h2&gt;

&lt;p&gt;Jackson and Gson are excellent libraries, but they focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Serialization / deserialization&lt;/li&gt;
&lt;li&gt;Data binding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SJF4J focuses on a different layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON as a &lt;strong&gt;structured data model&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Cross-cutting operations (path, patch, schema)&lt;/li&gt;
&lt;li&gt;Hybrid static + dynamic access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It does not replace existing libraries — it builds on top of them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;p&gt;SJF4J operates on top of existing parsers, so performance depends on the underlying implementation.&lt;/p&gt;

&lt;p&gt;In typical scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overhead is modest&lt;/li&gt;
&lt;li&gt;In some cases (e.g., JOJO + optimized IO), performance can be comparable or even slightly better&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The design goal is &lt;strong&gt;capability without significant cost&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  When It Makes Sense
&lt;/h2&gt;

&lt;p&gt;SJF4J is useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON structure is partially dynamic&lt;/li&gt;
&lt;li&gt;You need both typed access and flexible fields&lt;/li&gt;
&lt;li&gt;You work with evolving schemas&lt;/li&gt;
&lt;li&gt;You want a unified model for JSON operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It may be less necessary if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your schema is completely static&lt;/li&gt;
&lt;li&gt;You only need simple serialization/deserialization&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;SJF4J explores a different layer in the JSON stack:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Not parsing, not binding — but structuring.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It provides a way to treat JSON as a &lt;strong&gt;first-class data model&lt;/strong&gt; in Java, combining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Structure&lt;/li&gt;
&lt;li&gt;Flexibility&lt;/li&gt;
&lt;li&gt;Semantic operations&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Project:&lt;/strong&gt; &lt;a href="https://github.com/sjf4j-projects/sjf4j" rel="noopener noreferrer"&gt;https://github.com/sjf4j-projects/sjf4j&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>json</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Thu, 05 Mar 2026 00:42:41 +0000</pubDate>
      <link>https://forem.com/hannyu/-223o</link>
      <guid>https://forem.com/hannyu/-223o</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/hannyu" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3695478%2F1408961a-08f6-449c-ae0d-167d9795cb8f.jpg" alt="hannyu"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/hannyu/json-patch-in-java-without-converting-everything-to-jsonnode-ji9" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;JSON Patch in Java — Without Converting Everything to JsonNode&lt;/h2&gt;
      &lt;h3&gt;Yu Han ・ Mar 4&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#java&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#json&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>java</category>
      <category>json</category>
    </item>
  </channel>
</rss>
