DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • How To Extract a ZIP File and Remove Password Protection in Java
  • Using Python Libraries in Java
  • Using Lombok Library With JDK 23
  • Introduction to Polymorphism With Database Engines in NoSQL Using Jakarta NoSQL

Trending

  • Comprehensive Guide to Property-Based Testing in Go: Principles and Implementation
  • Automatic Code Transformation With OpenRewrite
  • The Full-Stack Developer's Blind Spot: Why Data Cleansing Shouldn't Be an Afterthought
  • AI's Dilemma: When to Retrain and When to Unlearn?
  1. DZone
  2. Coding
  3. Java
  4. Revolutionize JSON Parsing in Java With Manifold

Revolutionize JSON Parsing in Java With Manifold

Parsing JSON in Java (and other formats) can be as easy as in JavaScript. It can do much more while keeping the type-safety and deep IDE integration.

By 
Shai Almog user avatar
Shai Almog
DZone Core CORE ·
May. 03, 23 · Tutorial
Likes (6)
Comment
Save
Tweet
Share
6.7K Views

Join the DZone community and get the full member experience.

Join For Free

Java developers have often envied JavaScript for its ease of parsing JSON. Although Java offers more robustness, it tends to involve more work and boilerplate code. Thanks to the Manifold project, Java now has the potential to outshine JavaScript in parsing and processing JSON files. Manifold is a revolutionary set of language extensions for Java that completely changes the way we handle JSON (and much more).
Modern Java: Make Java JSON Manifold, Part 1

Getting Started With Manifold

The code for this tutorial can be found on my GitHub page. Manifold is relatively young but already vast in its capabilities. You can learn more about the project on their website and Slack channel. To begin, you'll need to install the Manifold plugin, which is currently only available for JetBrains IDEs. The project supports LTS releases of Java, including the latest JDK 19.

We can install the plugin from IntelliJ/IDEAs settings UI by navigating to the marketplace and searching for Manifold. The plugin makes sure the IDE doesn’t collide with the work done by the Maven/Gradle plugin.

Manifold plugin

Manifold consists of multiple smaller projects, each offering a custom language extension. Today, we'll discuss one such extension, but there's much more to explore.

Setting Up a Maven Project

To demonstrate Manifold, we'll use a simple Maven project (it also works with Gradle). We first need to paste the current Manifold version from their website and add the necessary dependencies. The main dependency for JSON is the manifold-json-rt dependency. Other dependencies can be added for YAML, XML, and CSV support. We need to add this to the pom.xml file in the project.

I'm aware of the irony where the boilerplate reduction for JSON starts with a great deal of configuration in the Maven build script. But this is configuration, not "actual code" and it's mostly copy and paste. Notice that if you want to reduce this code the Gradle equivalent code is terse by comparison.

This line needs to go into the properties section:

<manifold.version>2023.1.5</manifold.version>


The dependencies we use are these:

<dependencies>
   <dependency>
       <groupId>systems.manifold</groupId>
       <artifactId>manifold-json-rt</artifactId>
       <version>${manifold.version}</version>
   </dependency>


The compilation plugin is the boilerplate that weaves Manifold into the bytecode and makes it seamless for us. It’s the last part of the pom setup:

<build>
   <plugins>
       <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-compiler-plugin</artifactId>
           <version>3.8.0</version>
           <configuration>
               <source>19</source>
               <target>19</target>
               <encoding>UTF-8</encoding>
               <compilerArgs>
                   <!-- Configure manifold plugin-->
                   <arg>-Xplugin:Manifold</arg>
               </compilerArgs>

               <!-- Add the processor path for the plugin -->
               <annotationProcessorPaths>
                   <path>
                       <groupId>systems.manifold</groupId>
                       <artifactId>manifold-json</artifactId>
                       <version>${manifold.version}</version>
                   </path>
               </annotationProcessorPaths>
           </configuration>
       </plugin>
   </plugins>
</build>


With the setup complete, let's dive into the code.

Parsing JSON With Manifold

We place a sample JSON file in the project directory under the resources hierarchy. I placed this file under src/main/resources/com/debugagent/json/Test.json:

{
  "firstName": "Shai",
  "surname": "Almog",
  "website": "https://debugagent.com/",
  "active": true,
  "details":[
    {"key": "value"}
  ]
}


In the main class, we refresh the Maven project, and you'll notice a new Test class appears. This class is dynamically created by Manifold based on the JSON file. If you change the JSON and refresh Maven, everything updates seamlessly. It’s important to understand that Manifold isn’t a code generator. It compiles the JSON we just wrote into bytecode.

The Test class comes with several built-in capabilities, such as a type-safe builder API that lets you construct JSON objects using builder methods. You can also generate nested objects and convert the JSON to a string by using the write() and toJson() methods.

It means we can now write:

Test test = Test.builder().withFirstName("Someone")
        .withSurname("Surname")
        .withActive(true)
        .withDetails(List.of(
                Test.details.detailsItem.builder().
                        withKey("Value 1").build()
        ))
        .build();


Which will printout the following JSON:

{
  "firstName": "Someone",
  "surname": "Surname",
  "active": true,
  "details": [
    {
      "key": "Value 1"
    }
  ]
}


We can similarly read a JSON file using code such as this:

Test readObject = Test.load().fromJson("""
        {
          "firstName": "Someone",
          "surname": "Surname",
          "active": true,
          "details": [
            {
              "key": "Value 1"
            }
          ]
        }
        """);


Note the use of Java 15 TextBlock syntax for writing a long string. The load() method returns an object that includes various APIs for reading the JSON. In this case, it is read from a String but there are APIs for reading it from a URL, file, etc.

Manifold supports various formats, including CSV, XML, and YAML, allowing you to generate and parse any of these formats without writing any boilerplate code or sacrificing type safety. In order to add that support we will need to add additional dependencies to the pom.xml file:

   <dependency>
       <groupId>systems.manifold</groupId>
       <artifactId>manifold-csv-rt</artifactId>
       <version>${manifold.version}</version>
   </dependency>
   <dependency>
       <groupId>systems.manifold</groupId>
       <artifactId>manifold-xml-rt</artifactId>
       <version>${manifold.version}</version>
   </dependency>
   <dependency>
       <groupId>systems.manifold</groupId>
       <artifactId>manifold-yaml-rt</artifactId>
       <version>${manifold.version}</version>
   </dependency>


With these additional dependencies, this code will print out the same data as the JSON file. With test.write().toCsv() the output would be:

"firstName","surname","active","details"
"Someone","Surname","true","[manifold.json.rt.api.DataBindings@71070b9c]"


Notice that the Comma Separated Values (CSV) output doesn’t include hierarchy information. That’s a limitation of the CSV format and not the fault of Manifold.

With test.write().toXml() the output is familiar and surprisingly concise:

<root_object firstName="Someone" surname="Surname" active="true">
  <details key="Value 1"/>
</root_object>


With test.write().toYaml() we again get a familiar printout:

firstName: Someone
surname: Surname
active: true
details:
- key: Value 1


Working With JSON Schema

Manifold also works seamlessly with JSON schema, allowing you to enforce strict rules and constraints. This is particularly useful when working with dates and enums. Manifold seamlessly creates/updates byte code that adheres to the schema, making it much easier to work with complex JSON data.

This schema is copied and pasted from the Manifold GitHub project:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/schemas/User.json",
  "type": "object",
  "definitions": {
    "Gender": {
      "type": "string",
      "enum": ["male", "female"]
    }
  },
  "properties": {
    "name": {
      "type": "string",
      "description": "User's full name.",
      "maxLength": 80
    },
    "email": {
      "description": "User's email.",
      "type": "string",
      "format": "email"
    },
    "date_of_birth": {
      "type": "string",
      "description": "Date of uses birth in the one and only date standard: ISO 8601.",
      "format": "date"
    },
    "gender": {
      "$ref" : "#/definitions/Gender"
    }
  },
  "required": ["name", "email"]
}


It’s a relatively simple schema, but I’d like to turn your attention to several things here. It defines name and email as required. This is why when we try to create a User object using a builder in Manifold, the build() method requires both parameters:

User.builder("Name", "email@domain.com")   


That is just the start. The schema includes a date. Dates are a painful prospect in JSON, the standardization is poor and fraught with issues. The schema also includes a gender field which is effectively an enum. This is all converted to type-safe semantics using common Java classes such as LocalDate:

User u = User.builder("Name", "email@domain.com")
       .withDate_of_birth(LocalDate.of(1999, 10, 11))
       .withGender(User.Gender.male)
       .build();


That can be made even shorter with static imports but the gist of the idea is clear. JSON is effectively native to Java in Manifold.

Video

The Tip of The Iceberg

Manifold is a powerful and exciting project. It revolutionizes JSON parsing in Java but that’s just one tiny portion of what it can do!

We've only scratched the surface of its capabilities in this post. In the next article, we'll dive deeper into Manifold and explore some additional unexpected features.

Please share your experience and thoughts about Manifold in the comments section. If you have any questions, don't hesitate to ask.

Apache Maven JSON Java (programming language) Java compiler

Published at DZone with permission of Shai Almog, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How To Extract a ZIP File and Remove Password Protection in Java
  • Using Python Libraries in Java
  • Using Lombok Library With JDK 23
  • Introduction to Polymorphism With Database Engines in NoSQL Using Jakarta NoSQL

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!