<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yu Han</title>
    <description>The latest articles on DEV Community by Yu Han (@hannyu).</description>
    <link>https://dev.to/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>DEV Community: Yu Han</title>
      <link>https://dev.to/hannyu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hannyu"/>
    <language>en</language>
    <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://dev.to/hannyu/a-new-jsonschema2jojo-online-tool-1leh</link>
      <guid>https://dev.to/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://dev.to/hannyu/-2efp</link>
      <guid>https://dev.to/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://dev.to/hannyu/generating-java-from-json-schema-6kf</link>
      <guid>https://dev.to/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://dev.to/hannyu/sjf4j-120-jackson-3-support-instance-based-runtime-and-more-predictable-json-semantics-532b</link>
      <guid>https://dev.to/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://dev.to/hannyu/we-benchmarked-jsonpath-in-javaresult-up-to-7x-faster-without-changing-your-data-model-2gfa</link>
      <guid>https://dev.to/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://dev.to/hannyu/sjf4j-vs-jayway-jsonpath-up-to-7x-faster-in-java-benchmarks-2aof</link>
      <guid>https://dev.to/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://dev.to/hannyu/sjf4j-a-structured-json-facade-for-java-2n0f</link>
      <guid>https://dev.to/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://dev.to/hannyu/-223o</link>
      <guid>https://dev.to/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>
    <item>
      <title>JSON Patch in Java — Without Converting Everything to JsonNode</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Wed, 04 Mar 2026 11:26:02 +0000</pubDate>
      <link>https://dev.to/hannyu/json-patch-in-java-without-converting-everything-to-jsonnode-ji9</link>
      <guid>https://dev.to/hannyu/json-patch-in-java-without-converting-everything-to-jsonnode-ji9</guid>
      <description>&lt;p&gt;Partial updates are everywhere.&lt;/p&gt;

&lt;p&gt;Modern APIs frequently support HTTP &lt;code&gt;PATCH&lt;/code&gt;, and JSON Patch (defined in RFC 6902) has become a standard way to describe structural changes to JSON documents.&lt;/p&gt;

&lt;p&gt;A typical patch looks 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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"op"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"replace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&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 Zhang"&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;"op"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/scores/physics"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;91&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;Conceptually, it’s simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;replace a value&lt;/li&gt;
&lt;li&gt;add a value&lt;/li&gt;
&lt;li&gt;remove something&lt;/li&gt;
&lt;li&gt;move something&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JSON Patch is elegant.&lt;/p&gt;

&lt;p&gt;But when using it in Java, things often become… slightly less elegant.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Usual Java Workflow
&lt;/h3&gt;

&lt;p&gt;Most JSON Patch libraries operate on JSON tree models.&lt;/p&gt;

&lt;p&gt;Which means your code typically looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POJO
 ↓
JsonNode
 ↓
apply patch
 ↓
JsonNode
 ↓
POJO
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In practice this means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;converting your objects into JSON trees&lt;/li&gt;
&lt;li&gt;applying the patch&lt;/li&gt;
&lt;li&gt;converting everything back&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This works, but it introduces &lt;strong&gt;extra layers and conversions&lt;/strong&gt; that aren't really related to the domain model.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Different Approach
&lt;/h3&gt;

&lt;p&gt;Instead of operating on a JSON tree, &lt;strong&gt;SJF4J applies patch operations directly to the object graph&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Object Graph
    ↓
apply patch
    ↓
Object Graph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;This works because SJF4J uses a unified structural model called &lt;strong&gt;OBNT (Object-Based Node Tree)&lt;/strong&gt;, where native Java objects themselves act as the JSON structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Model
&lt;/h3&gt;

&lt;p&gt;Let’s start with a simple 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="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="c1"&gt;// Getters and setters&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class extends &lt;code&gt;JsonObject&lt;/code&gt;, which means it behaves both as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a typed Java object&lt;/li&gt;
&lt;li&gt;a dynamic JSON structure&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Parsing JSON
&lt;/h3&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;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""
{
  "name": "Alice",
  "scores": {
    "math": 59
  }
}
"""&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;student&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;Student&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;Now &lt;code&gt;student&lt;/code&gt; behaves like a normal Java 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="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it also supports JSON-semantic APIs:&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;getInteger&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="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getIntegerByPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.scores.math"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Defining a JSON Patch
&lt;/h3&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": "/name", "value": "Alice Zhang" },
  { "op": "add", "path": "/scores/physics", "value": 91 }
]
"""&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Applying the Patch&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;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;student&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After applying the patch:&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;getName&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Alice Zhang&lt;/span&gt;

&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getIntegerByPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.scores.physics"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 91&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The object graph is updated &lt;strong&gt;in place&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nested Updates Work Naturally
&lt;/h3&gt;

&lt;p&gt;JSON Patch paths work naturally with nested structures.&lt;/p&gt;

&lt;p&gt;Example:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"op"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"add"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/friends/0/scores/music"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Applying this patch will automatically update nested objects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparing Approaches
&lt;/h3&gt;

&lt;p&gt;When patches operate directly on object graphs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fewer conversions happen&lt;/li&gt;
&lt;li&gt;less intermediate structure is required&lt;/li&gt;
&lt;li&gt;the code stays closer to the domain model&lt;/li&gt;
&lt;li&gt;higher performance&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why JSON Patch Fits This Model
&lt;/h3&gt;

&lt;p&gt;JSON Patch is fundamentally a &lt;strong&gt;structural transformation language&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It describes changes in terms of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;paths&lt;/li&gt;
&lt;li&gt;operations&lt;/li&gt;
&lt;li&gt;values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That makes it a natural fit for a structural object model rather than a serialization layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;JSON Patch is a powerful standard for partial updates.&lt;/p&gt;

&lt;p&gt;But the developer experience depends heavily on how it's implemented.&lt;/p&gt;

&lt;p&gt;When patch operations work directly on Java object graphs instead of JSON trees, they become significantly simpler to use.&lt;/p&gt;




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

&lt;p&gt;&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;a href="https://sjf4j.org" rel="noopener noreferrer"&gt;https://sjf4j.org&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>json</category>
    </item>
    <item>
      <title>2x Faster JSON Schema Validation in Java (Without JsonNode)</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Wed, 25 Feb 2026 08:53:06 +0000</pubDate>
      <link>https://dev.to/hannyu/2x-faster-json-schema-validation-in-java-without-jsonnode-1p98</link>
      <guid>https://dev.to/hannyu/2x-faster-json-schema-validation-in-java-without-jsonnode-1p98</guid>
      <description>&lt;p&gt;Most JSON Schema libraries in Java follow the same pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validate a JSON string&lt;/li&gt;
&lt;li&gt;Or validate a JsonNode&lt;/li&gt;
&lt;li&gt;Or validate some library-specific tree model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which makes sense — JSON Schema was designed for JSON documents.&lt;/p&gt;

&lt;p&gt;But in real applications, we rarely live in JSON strings.&lt;br&gt;
We live in Java objects.&lt;/p&gt;

&lt;p&gt;So the usual flow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POJO → serialize → JsonNode → validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works. It’s common.&lt;br&gt;
But it’s not the only possible model.&lt;/p&gt;
&lt;h2&gt;
  
  
  A Slightly Different Mental Model
&lt;/h2&gt;

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

&lt;blockquote&gt;
&lt;p&gt;“JSON Schema validates JSON.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“JSON Schema validates structured data.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That includes: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POJOs&lt;/code&gt; / &lt;code&gt;JOJOs&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Map&lt;/code&gt; / &lt;code&gt;List&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;primitive values&lt;/li&gt;
&lt;li&gt;any Java objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;SJF4J&lt;/strong&gt; treats these as first-class schema nodes via an Object-Based Node Tree model.&lt;br&gt;
There is no mandatory &lt;code&gt;JsonNode&lt;/code&gt; layer in between.&lt;/p&gt;

&lt;p&gt;So 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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&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;user&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;Can be validated 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",
  "required": ["id"],
  "properties": {
    "id": { "type": "integer" },
    "user": { "format": "email" }
  }
}
"""&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;compile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&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;Order&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;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"alice@example.com"&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;schema&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;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No serialization.&lt;br&gt;
No JsonNode.&lt;br&gt;
No adapter layer.&lt;/p&gt;

&lt;p&gt;Just validate the object.&lt;/p&gt;


&lt;h2&gt;
  
  
  JSON Schema + JSR 380: Not Competitors
&lt;/h2&gt;

&lt;p&gt;JSR 380 (Bean Validation) is excellent for core invariants:&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;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@NotNull&lt;/span&gt;
    &lt;span class="nd"&gt;@Email&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it’s:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Annotation-driven&lt;/li&gt;
&lt;li&gt;Static&lt;/li&gt;
&lt;li&gt;Bound to compiled code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JSON Schema handles a different layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runtime-configurable validation&lt;/li&gt;
&lt;li&gt;Conditional logic (&lt;code&gt;if/then/else&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Structural policies&lt;/li&gt;
&lt;li&gt;Externalized contracts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With SJF4J, you can layer JSON Schema directly onto your domain 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"],
  "properties": {
    "id": { "type": "integer" },
    "user": { "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;Order&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;user&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;And validate it without converting anything:&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="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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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;In practice, the split becomes very clean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSR 380 → domain invariants&lt;/li&gt;
&lt;li&gt;JSON Schema → runtime contracts &amp;amp; policies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They complement each other instead of overlapping.&lt;/p&gt;




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

&lt;p&gt;In local &lt;a href="https://bowtie.report/" rel="noopener noreferrer"&gt;bowtie&lt;/a&gt; runs against the official JSON Schema test suite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SJF4J performs roughly &lt;strong&gt;2× faster than networknt’s validator&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Currently among the fastest Java JSON Schema validators in bowtie benchmarks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By validating native objects directly, SJF4J avoids:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Serialization&lt;/li&gt;
&lt;li&gt;Re-parsing&lt;/li&gt;
&lt;li&gt;Intermediate tree construction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The simpler model isn’t slower.&lt;br&gt;
In many cases, it’s measurably faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Small Architectural Shift
&lt;/h2&gt;

&lt;p&gt;Most JSON tooling in Java assumes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JSON is primary. Objects are derived.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This flips that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Structured data is primary. JSON is just a representation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once validation operates directly on native objects, a surprising amount of glue code disappears.&lt;/p&gt;

&lt;p&gt;Not dramatically.&lt;br&gt;
Not heroically.&lt;br&gt;
Just quietly.&lt;/p&gt;

&lt;p&gt;And after writing more adapter layers than I care to admit, I’ve learned to appreciate quiet improvements.&lt;/p&gt;




&lt;p&gt;If you’re curious:&lt;/p&gt;

&lt;p&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>programming</category>
      <category>java</category>
      <category>json</category>
      <category>opensource</category>
    </item>
    <item>
      <title>SJF4J in 5 Minutes: A Practical JSON Facade for Java</title>
      <dc:creator>Yu Han</dc:creator>
      <pubDate>Tue, 06 Jan 2026 11:51:02 +0000</pubDate>
      <link>https://dev.to/hannyu/sjf4j-in-5-minutes-a-practical-json-facade-for-java-j73</link>
      <guid>https://dev.to/hannyu/sjf4j-in-5-minutes-a-practical-json-facade-for-java-j73</guid>
      <description>&lt;p&gt;JSON handling in Java is rarely simple.&lt;/p&gt;

&lt;p&gt;In real-world applications, data constantly moves between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;POJOs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Map&lt;/code&gt; / &lt;code&gt;List&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;JSON strings&lt;/li&gt;
&lt;li&gt;configuration files&lt;/li&gt;
&lt;li&gt;APIs with evolving schemas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Java developers are often forced into a painful decision:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Either type safety, or flexibility — but not both.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;SJF4J (Simple JSON Facade for Java)&lt;/strong&gt; is built to remove that trade-off.&lt;/p&gt;




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

&lt;p&gt;SJF4J is a lightweight facade over popular JSON libraries (Jackson, Gson, Fastjson2) and related formats (YAML, Properties).&lt;/p&gt;

&lt;p&gt;It provides a &lt;strong&gt;unified semantic layer for structured data processing&lt;/strong&gt;, fully grounded in JSON specifications.&lt;/p&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; replace your JSON parser — it unifies how you work with structured data &lt;em&gt;above&lt;/em&gt; them.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Idea: Object-Based Node Tree
&lt;/h2&gt;

&lt;p&gt;Instead of introducing a custom JSON AST, SJF4J treats &lt;strong&gt;existing Java objects as JSON nodes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is called the &lt;strong&gt;Object-Based Node Tree (OBNT)&lt;/strong&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;JSON objects → &lt;code&gt;JsonObject&lt;/code&gt;, &lt;code&gt;Map&lt;/code&gt;, POJOs&lt;/li&gt;
&lt;li&gt;JSON arrays → &lt;code&gt;JsonArray&lt;/code&gt;, &lt;code&gt;List&lt;/code&gt;, arrays&lt;/li&gt;
&lt;li&gt;JSON values → native Java types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything stays &lt;strong&gt;plain Java&lt;/strong&gt; — with JSON semantics layered on top.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;JsonObject&lt;/span&gt; &lt;span class="n"&gt;jo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&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;"""
{
  "id": 1,
  "active": true
}
"""&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;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;              &lt;span class="c1"&gt;// type-safe&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAsString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"active"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Boolean → String&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SJF4J offers three access levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;getXxx&lt;/code&gt; → type-safe access&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;getAsXxx&lt;/code&gt; → semantic, cross-type conversion&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You choose strictness per call.&lt;/p&gt;




&lt;h2&gt;
  
  
  Path-Based Access (RFC-Compliant)
&lt;/h2&gt;

&lt;p&gt;SJF4J fully supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON Path (RFC 9535)&lt;/li&gt;
&lt;li&gt;JSON Pointer (RFC 6901)
&lt;/li&gt;
&lt;/ul&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getByPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.user.name"&lt;/span&gt;&lt;span class="o"&gt;);&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;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jo&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[*].id"&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;The same path API works across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;li&gt;Maps / Lists&lt;/li&gt;
&lt;li&gt;POJOs&lt;/li&gt;
&lt;li&gt;Hybrid object graphs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Dynamic + Typed: JOJO
&lt;/h2&gt;

&lt;p&gt;SJF4J introduces JOJO (JSON Object Java Object) —&lt;br&gt;
a domain object that extends JsonObject.&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;class&lt;/span&gt; &lt;span class="nc"&gt;User&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="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="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;               &lt;span class="c1"&gt;// typed&lt;/span&gt;
&lt;span class="n"&gt;user&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;"age"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// dynamic&lt;/span&gt;
&lt;span class="n"&gt;user&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;"$..name"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// JSON semantics&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can start dynamic and gradually add structure — without breaking APIs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Declarative Transformation with JsonPatch
&lt;/h2&gt;

&lt;p&gt;SJF4J supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON Patch (RFC 6902)&lt;/li&gt;
&lt;li&gt;JSON Merge Patch (RFC 7386)
&lt;/li&gt;
&lt;/ul&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;diff&lt;/span&gt;&lt;span class="o"&gt;(&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;target&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;source&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Patches work uniformly across POJOs, Maps, Lists, and JSON objects.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Does SJF4J Shine?
&lt;/h2&gt;

&lt;p&gt;SJF4J is ideal if you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work with evolving or semi-structured data&lt;/li&gt;
&lt;li&gt;Need both flexibility and type safety&lt;/li&gt;
&lt;li&gt;Want one API across multiple JSON libraries&lt;/li&gt;
&lt;li&gt;Care about JSON specifications&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;SJF4J makes JSON-oriented Java development possible — without early lock-in or excessive boilerplate.&lt;/p&gt;

&lt;p&gt;It is small, composable, and specification-driven.&lt;/p&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;/p&gt;

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