AI Document Processing with Docling Java, Arconia, and Spring Boot

Docling is an open-source, privacy-focused solution for advanced document parsing. Using Docling Java and Arconia, you can integrate it with Spring Boot.

A Book on the Grass - Photo by Samar Mourya

Are you building RAG workflows? Do you need to extract structured data from PDF documents, slides, or scanned files, without the risk of hallucinations or privacy leaks? When building Generative AI applications, the quality of your results depends on the quality of your data. Faithful and efficient document processing is the foundation for accurate, reliable AI systems.

In this article, I'll first explore some of the main challenges of document processing solutions in the context of Generative AI systems. Then, I'll describe how Docling solves those challenges and introduce the brand-new Docling Java project, for which I'm one of the maintainers. Finally, I'll show you a practical example of integrating your Spring Boot application with Docling using the Arconia Docling library I created.

The Challenges of Document Processing

Processing documents of arbitrary formats has always been a challenging, yet fascinating task. That's especially true in application development, where we typically work with structured data. Converting PDF documents, images, or PowerPoint presentations to a structured data format that we can consume in our applications enables many use cases. More recently, Retrieval Augmented Generation (RAG) workflows, part of LLM-powered applications, led to new ways of processing documents.

Using Generative AI (GenAI) models such as GPT-5, Gemini, or LLaVA for extracting structured data from arbitrary documents is a common and convenient way to build RAG or Agentic systems. However, GenAI-based document processing has a few downsides.

  • First, it's usually resource-intensive and not always possible to run on your local machine or resource-constrained systems such as edge devices. Therefore, if you aim at running such a system on-premises, your choices might be limited.
  • Second, different models have different licenses and terms of service. If available only as SaaS in the cloud, there are also concerns regarding data privacy.
  • Finally, and most importantly, GenAI models are prone to hallucinations. If you use a GenAI model to convert a document, be ready for it to make stuff up and include content that wasn't in the original document in the result.

How could we solve these challenges? Docling!

Why Docling

Docling is an open-source project started by the AI for knowledge team at IBM Research Zurich and later donated to the Linux Foundation AI & Data.

Docling turns messy PDFs, DOCX, and slides into clean, structured data—ready for RAG, GenAI apps, or anything downstream. Complex layouts? Tables? Formulas? It handles them, so you don’t have to.

How does Docling solve the three main challenges mentioned in the previous section?

  1. Docling is designed to run on commodity hardware so that you can run it efficiently on your local machine and in resource-constrained environments, such as edge devices.
  2. Docling is published with a permissive, open-source license (the MIT License). Since you can run it freely on your own hardware, even in air-gapped environments, you retain complete control over your data and don't need to worry about third parties gaining access to your private information.
  3. Docling document processing is based on specialised machine learning models trained to perform tasks such as layout analysis, table recognition, and optical character recognition (OCR). This design guarantees a faithful conversion of a document, without the risk of generating made-up content.
💡
If you'd like to learn more about Docling's architecture, I recommend reading the paper by the team at IBM Research that created the project: Docling: An Efficient Open-Source Toolkit for AI-driven Document Conversion.
The Docling mascot (a duck) leaning on a pile of documents with different formats, while holding in their hands a single file representing all the input in a unified, structured format.
Image from docling.ai.

One of the key features of Docling is its extensibility, which makes it straightforward to customise your document processing pipelines and integrate with third-party frameworks. Even the models used by Docling are customisable, including support for Visual Language Models (VLM) like Granite Docling for end-to-end document processing, and Automatic Speech Recognition (ASR) models for processing audio files.

Another key feature is that Docling uses a unified formatDoclingDocument, to represent any input document in a structured way, without losing any information or metadata, unlike lossy formats such as Markdown or HTML. For this reason, Docling is a great tool to prepare structured data, ready to be consumed by GenAI applications.

Docling is available as a Python package that you can use as a CLI or integrate into your Python applications. Wait! Wasn't this an article about Java? Yes, indeed!

The secret is that Docling can also be run as an API service via the Docling Serve project. And we definitely know how to call an HTTP API from Java, don't we?

Introducing Docling Java

When I learned about the Docling Serve project, I immediately wanted to try to integrate it with my Spring Boot applications. That's how Arconia Docling came to be. It provided a Java SDK for calling the Docling Serve API and consuming Docling's document processing features. It also included Spring Boot auto-configuration and a convenient Arconia Dev Service based on Testcontainers to run a Docling Serve instance during the application lifecycle.

Around the same period, my fellow Java Champions Eric Deandrea and Alex Soto were working on a similar solution for Quarkus Docling. I'm glad that Eric reached out to join forces and create common Docling support for Java, ultimately leading to the creation of the official Docling Java project under the Docling organization.

I was happy to join this new project as a maintainer and contribute the core APIs and client code I had developed for Arconia Docling to the new Docling Java project. This week, we got the first official release of Docling Java. I want to thank everyone who made it possible, especially Eric for driving this process from the very beginning and working towards this first release, Alex, Michele Dolfi and the rest of the Docling team at IBM for supporting this initiative.

We now have a common foundation for integrating our Java applications with Docling! That enables the wide Java community to try out Docling and ensures the portability of Docling-based solutions across frameworks such as Spring Boot and Quarkus, thanks to a common SDK.

Docling Java is currently composed of a few modules, which are all framework-agnostic and usable in any Java application:

  • The Docling Serve API defines the core APIs for communicating with a Docling Serve backend. It serves as the foundation for projects like Arconia Docling and Quarkus Docling.
  • The Docling Serve Client provides a reference HTTP Client implementation based on the Docling Serve API and used to communicate with a Docling Serve backend. It's based on Java's built-in HttpClient and supports both Jackson 2 and Jackson 3 for JSON parsing.
  • The Docling Testcontainers module provides a DoclingServeContainer you can use with Testcontainers to spin up a Docling Serve container instance during development and testing. It serves as the foundation for the Docling Dev Service provided by Arconia Docling and Quarkus Docling.

Starting from version 0.19.0, Arconia Docling is based on the Docling Serve API and Docling Testcontainers modules from the Docling Java project.

💡
If you were using previous versions of Arconia Docling, some code changes are required to migrate to the new Docling Java implementation. The good news is that I automated the refactoring for you using OpenRewrite. Check out the Upgrading Arconia page for instructions on automatically upgrading to the latest version without making any manual code changes.

It's time to see Arconia Docling in action. Let's go!

Quick Start

Let's build a practical example to demonstrate how Arconia Docling simplifies document processing in a Spring Boot application. We'll explore how to process documents from an HTTP source and from a local file.

The complete source code for this example is available on GitHub.

1. Project Setup

Start by creating a new Spring Boot project. You can use Spring Initializr or set it up manually. From the Spring Initializr, choose the following options: Spring Web, Actuator.

For this example, I'll use Spring Boot 3.5, Gradle, and Java 25. Here's how the dependencies section of your build.gradle file should look:

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-actuator'
  implementation 'org.springframework.boot:spring-boot-starter-web'

  testImplementation 'org.springframework.boot:spring-boot-starter-test'
  testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

Additionally, we add Arconia Docling. You could specify the version directly in the dependency declaration, but I recommend using a BOM to manage versions consistently across your project:

dependencies {
  implementation 'io.arconia:arconia-docling-spring-boot-starter'
  testAndDevelopmentOnly 'io.arconia:arconia-dev-services-docling'
}

dependencyManagement {
  imports {
    mavenBom "io.arconia:arconia-bom:0.19.0"
  }
}

The Arconia Docling starter brings Spring Boot auto-configuration for the Docling Java API. The Docling Dev Service dependency provisions a local Docling Serve instance for development and testing only.

💡
Notice the testAndDevelopmentOnly scope for the Arconia Dev Service dependency. That ensures the service is only available during development and testing, and is wholly excluded from production builds: precisely what you want for a development tool.

If your project utilises Spring Boot DevTools for live-restart support during development, Arconia will ensure the Docling Serve instance remains running between code changes, eliminating the need to restart after every change.

2. Using the Docling Java API

For our initial example, let's define a DocumentProcessingController to expose an HTTP endpoint we can call to convert a document from an HTTP source.

Arconia Docling provides an auto-configured DoclingServeApi (from the Docling Java API), which you can autowire into the controller and use it to interact with a Docling Serve instance.

@RestController
@RequestMapping("/convert")
class DocumentProcessingController {

  private final DoclingServeApi doclingServeApi;

  DocumentProcessingController(DoclingServeApi doclingServeApi) {
    this.doclingServeApi = doclingServeApi;
  }

  @GetMapping("/http")
  String convertDocumentFromHttp(@RequestParam("url") String url) {
    ConvertDocumentResponse response = doclingServeApi
      .convertSource(ConvertDocumentRequest.builder()
        .source(HttpSource.builder().url(URI.create(url)).build())
        .build());
      return response.getDocument().getMarkdownContent();
  }

}

We build a ConvertDocumentRequest to specify the URI from which to fetch the document to convert, which is the only required argument. There are many options you can define to customise the conversion process. Check out the documentation for more information.

The result is a ConvertDocumentResponse object, which includes the converted document and additional metadata. By default, Docling converts the document to Markdown, which we extract and return to the caller.

The DoclingServeApi also lets you specify a local file to convert instead of a URI. For this example, add a file to the src/main/resources/documents folder of your application. You can use the story.pdf file included in the accompanying GitHub repository.

Next, read the file into the application using the Spring Framework's convenient Resource abstraction, and pass the Base64-encoded representation to Docling.

@RestController
@RequestMapping("/convert")
class DocumentProcessingController {

  ...
  
  @GetMapping("/file")
  String convertDocumentFromFile() throws IOException {
    Resource file = new ClassPathResource("documents/story.pdf");
    String base64File = Base64.getEncoder().encodeToString(file.getContentAsByteArray());
    ConvertDocumentResponse response = doclingServeApi
      .convertSource(ConvertDocumentRequest.builder()
        .source(FileSource.builder()
          .filename("story.pdf")
          .base64String(base64File)
          .build())
        .build());
    return response.getDocument().getMarkdownContent();
  }

}

3. Run the Application

It's time to see the example in action. First, make sure you have a container runtime available on your machine, such as Podman or Docker, since that's required for Testcontainers to work. Then, fire up your app using the standard Spring Boot command for Gradle:

./gradlew bootRun

Or, if you prefer using the Arconia CLI:

arconia dev

When you run the application, Arconia Dev Services will automatically start a local Docling Serve instance using Testcontainers and configure the application to connect to it. That means you can convert documents locally using Docling with no manual setup required.

💡
If you'd like to learn more about Arconia Dev Services and how it works, refer to the dedicated article.

If you have multiple Spring Boot applications running in your development environment with the Docling Dev Service, Arconia will reuse the same instance across applications for efficiency. You can read more about sharing dev services in the Arconia documentation.

💡
When running the application in production, you can easily configure the URL for a production Docling Serve instance via the arconia.docling.url property. Refer to the documentation for more information.

4. Process a Document

Let's verify the application is working as expected. For this example, I'll use httpie, a command-line HTTP client that makes it easy to interact with HTTP APIs.

From a Terminal window, call the /convert/http endpoint with a URL to a web page you'd like to convert.

http :8080/convert/http url="https://docs.arconia.io/arconia-cli/latest/update/spring-boot/"

You should see the equivalent Markdown representation in the response.

Then, try converting a local file by calling the /convert/file endpoint.

http :8080/convert/file

You should see the equivalent Markdown representation of the story.pdf document in the response.

5. Monitor the Health of the Docling Serve API

Whenever we integrate a Spring Boot application with an external service, it's essential to monitor the integration to ensure it remains healthy. Spring Boot Actuator offers a dedicated endpoint (/actuator/health) to inspect the health of each component and integration used by the application.

Arconia Docling extends the Actuator Health endpoint with additional status details about the Docling integration. You have already included the Spring Boot Actuator dependency in your project. All that remains is to configure the application to enable the inclusion of health information for each integration component, which is turned off by default for security reasons.

⚠️
Before enabling any Actuator endpoint in production, make sure they are properly secured!

Open your application configuration file and add the following:

management:
  endpoint:
    health:
      show-components: always

Finally, rerun the application and call the Health endpoint.

http :8080/actuator/health

You should see health information about the Docling integration in the response:

{
    "status": "UP",
    "components": {
        ...
        "docling": {
            "status": "UP"
        },
        ...
        }
    },
}

💡
If you'd like to learn more about the Arconia Docling support for Actuator, refer to the documentation.

6. Inspect the Docling Serve UI

When running your Spring Boot application in dev mode, the Arconia Docling Dev Service also makes the Docling Serve UI available.

During the startup phase, Arconia will show the URL to access the Docling Serve UI in your application logs. You should see something like the following:

...Docling Serve UI: http://localhost:<port>/ui

If you open that URL in a web browser, you'll be able to perform the same document conversion operations from a convenient graphical user interface.

Screenshot of the GUI for Docling Serve, available at http://localhost:<port>/ui. It offers the same options as the API, but as a graphical form.

Docling Serve also provides access to the API documentation, available at http://localhost:<port>/docs.

Screenshot of the OpenAPI documentation for Docling Serve, available at http://localhost:<port>/docs.

7. Observing the Docling Integration

Arconia Docling relies on the standard RestClient from the Spring Framework to interact with the Docling Serve API. That means all HTTP interactions are instrumented and observable via metrics and traces.

You can extend your Spring Boot application with Arconia OpenTelemetry to get full observability out of the box, as explained in the dedicated article.

A screenshot of Grafana, showing an OpenTelemetry trace of the HTTP interaction between the Spring Boot application and the Docling Serve backend.

I plan to extend Arconia Docling with additional instrumentation to extract even more insights from Docling. Stay tuned!

Bonus: Running Arconia Docling from JBang

JBang is an incredible tool for running Java applications via a simple command, without the usual setup involving dependencies, build tools, and more. In this bonus section, I want to show you how incredibly easy it is to run a simple Spring Boot application for processing documents using Arconia Docling.

First, make sure you have JBang installed on your machine following the instructions in the project documentation. That's the only dependency you need. JBang takes care of everything else, including installing a Java 25 distribution if one is not yet available on your machine.

Then, create an Application.java file containing the following:

//usr/bin/env jbang "$0" "$@" ; exit $?
//JAVA 25
//DEPS io.arconia:arconia-docling-spring-boot-starter:0.19.0
//DEPS io.arconia:arconia-dev-services-docling:0.19.0

package io.arconia.docling;

import ai.docling.api.serve.DoclingServeApi;
import ai.docling.api.serve.convert.request.*;
import ai.docling.api.serve.convert.request.source.HttpSource;
import java.net.URI;
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Application {
    void main(String[] args) {
        var application = new SpringApplication(Application.class);
        application.setWebApplicationType(WebApplicationType.NONE);
        application.run(args);
    }

    @Bean
    CommandLineRunner convert(DoclingServeApi doclingServeApi) {
        return _ -> {
            var url = "https://docs.arconia.io/arconia/latest/integrations/docling";
            var response = doclingServeApi.convertSource(
                ConvertDocumentRequest.builder()
                    .source(HttpSource.builder()
                        .url(URI.create(url))
                        .build())
                    .build());
            IO.println(response.getDocument().getMarkdownContent());
        };
    }
};

Finally, run the application with JBang:

jbang Application.java

The application will use Docling (provisioned as a Dev Service) to process the document at the URL configured in the code, print its Markdown representation, and then exit.

Conclusion

In this article, I briefly analysed the main challenges of document processing solutions based on Generative AI models. Then, I described how Docling solves those challenges and introduced the brand-new Docling Java project, for which I'm one of the maintainers. Finally, I showed you a practical example of integrating your Spring Boot application with Docling using the Arconia Docling library I created.

The integration currently offers basic functionality, but more is in the making. We'll for sure extend the capabilities of the Java SDK to get even more out of the Docling integration, especially in the context of GenAI applications.

As an active contributor to Spring AI, I'm also working on integrating Docling with the data ingestion pipeline APIs offered by Spring AI to enable its use in your Retrieval Augmented Generation (RAG) workflows and agentic applications. Stay tuned!

Are you using Docling? What's your current experience with processing documents from your Java applications? I'd love to hear from you! Share your experience on Bluesky or LinkedIn. And if you'd like to contribute to the Arconia framework, feel free to reach out on our GitHub project!

First version published on November 23rd, 2025.

Cover picture from Pexels.