How to Highlight PDF Java from FTP – Add Annotation to PDF from FTP in Java

When you need to highlight PDF Java files that live on an FTP server, downloading the document first is often wasteful. In this tutorial you’ll see how to stream a PDF straight from FTP, apply a highlight annotation, and save the result—all without creating intermediate local files. We’ll walk through the required libraries, show the exact API calls (place‑holder code blocks are kept unchanged), and give you practical tips for scaling this pattern in production environments.

Quick Answers

  • Can I annotate a PDF without downloading it first? Yes – stream the file directly from FTP and annotate in memory.
  • Which library handles the annotation? GroupDocs.Annotation for Java provides a fluent API for highlights, notes, and shapes.
  • Do I need a license for production? A full GroupDocs license is required for production deployments.
  • What Java version is required? JDK 8 or higher is supported.
  • Is FTP the only storage option? No – the same streaming approach works with S3, Azure Blob, or local file systems.

What is “how to add annotation” in the context of PDFs?

Adding annotation means programmatically inserting visual marks—such as highlights, notes, or shapes—into a PDF document. With GroupDocs.Annotation you can do this directly on an input stream, which makes it perfect for remote sources like FTP servers.

Why Choose This Approach for PDF FTP Annotation?

Load the PDF from FTP, apply a highlight, and write it back in a single pipeline. This eliminates local‑disk I/O, reduces network traffic, and keeps version control simple. In large‑scale environments the pattern can process hundreds of documents per minute while keeping memory usage under 100 MB per file.

Prerequisites and Environment Setup

Before you start, ensure you have:

  • JDK 8 or newer installed.
  • Apache Commons Net library (provides the FTPClient class).
  • GroupDocs.Annotation for Java library (latest release recommended).
  • Maven or Gradle for dependency management.
  • Valid FTP credentials with read/write permissions.

Setting Up GroupDocs.Annotation for Java

Maven Configuration

Add the repository and dependency to your pom.xml file:

<repositories>
   <repository>
      <id>repository.groupdocs.com</id>
      <name>GroupDocs Repository</name>
      <url>https://releases.groupdocs.com/annotation/java/</url>
   </repository>
</repositories>
<dependencies>
   <dependency>
      <groupId>com.groupdocs</groupId>
      <artifactId>groupdocs-annotation</artifactId>
      <version>25.2</version>
   </dependency>
</dependencies>

License Setup Options

GroupDocs offers three licensing models:

  1. Free Trial – Perfect for proof‑of‑concept work.
  2. Temporary License – Removes trial limits while you evaluate.
  3. Full License – Required for any production deployment.

Pro tip: Start with the free trial, then upgrade once you confirm the workflow meets your performance targets.

Complete Implementation Guide

Below is a step‑by‑step walkthrough that shows how to add annotation to a PDF retrieved from an FTP server.

Step 1: Loading Documents from FTP Server

FTPClient is Apache Commons Net’s class for handling FTP connections. It abstracts the low‑level protocol and lets you retrieve files as streams.

import org.apache.commons.net.ftp.FTPClient;
import java.io.IOException;
import java.io.InputStream;

public static InputStream getFileFromFtp(String server, String filePath) throws IOException {
    // Initialize FTP client
    FTPClient client = new FTPClient();
    
    // Connect to the FTP server
    client.connect(server);
    
    // Retrieve the specified file as an input stream
    InputStream inputStream = client.retrieveFileStream(filePath);
    
    // Disconnect from the FTP server
    client.disconnect();
    
    return inputStream;
}

What’s happening?

  • FTPClient opens a connection, logs in, and streams the remote PDF.
  • The returned InputStream avoids creating a temporary file on disk.
  • For secure environments, replace FTPClient with FTPSClient to enable TLS encryption.

FTPSClient extends FTPClient to provide FTP over TLS for secure transfers.

Step 2: Adding Annotations to Your PDF

Annotator is the core class in GroupDocs.Annotation that works directly with an InputStream. It creates, modifies, and saves annotations without loading the whole document into memory.

PdfLoadOptions configures how a PDF is loaded, such as password handling and page range.
Rectangle defines the position and size of the annotation on a page.

import com.groupdocs.annotation.Annotator;
import com.groupdocs.annotation.models.Rectangle;
import com.groupdocs.annotation.models.annotationmodels.AreaAnnotation;
import java.io.InputStream;

public static void addAnnotationAndSave(InputStream inputStream, String outputPath) {
    // Initialize Annotator with the provided InputStream
    final Annotator annotator = new Annotator(inputStream);
    
    // Create a new Area Annotation
    AreaAnnotation area = new AreaAnnotation();
    
    // Set the position and size of the annotation (100x100 at coordinates 100,100)
    area.setBox(new Rectangle(100, 100, 100, 100));
    
    // Set a background color for the annotation
    area.setBackgroundColor(65535); // Yellow color in ARGB format
    
    // Add the annotation to the document
    annotator.add(area);
    
    // Save the annotated document to the specified output path
    annotator.save(outputPath);
    
    // Dispose of resources used by Annotator
    annotator.dispose();
}

Key points

  • Annotator accepts the PDF stream and a PdfLoadOptions object.
  • Rectangle defines the highlight’s position and size on the page.
  • Colors are expressed as ARGB integers; 65535 corresponds to bright yellow.

Step 3: Putting It All Together

The main method demonstrates the full workflow—from FTP retrieval to saving the highlighted PDF.

public class PDFAnnotationFromFTP {
    public static void main(String[] args) {
        try {
            // Load PDF from FTP server
            InputStream pdfStream = getFileFromFtp("ftp.example.com", "/documents/report.pdf");
            
            // Add annotations and save
            addAnnotationAndSave(pdfStream, "annotated_report.pdf");
            
            System.out.println("PDF successfully annotated from FTP!");
            
        } catch (IOException e) {
            System.err.println("Error processing PDF: " + e.getMessage());
        }
    }
}

Running this program produces annotated_report.pdf with a yellow highlight placed at the coordinates you specified.

Advanced Annotation Techniques

Beyond simple area highlights, GroupDocs.Annotation supports a wide range of annotation types, each useful for different business scenarios.

Text Annotations for Detailed Comments

TextAnnotation lets you attach free‑form notes to any page region.

TextAnnotation textAnnotation = new TextAnnotation();
textAnnotation.setBox(new Rectangle(200, 200, 100, 50));
textAnnotation.setText("Important: Review this section carefully");
textAnnotation.setFontColor(16711680); // Red text
annotator.add(textAnnotation);

Point Annotations for Quick Notes

PointAnnotation creates a pinpoint marker that can be used for checklist items or error flags.

PointAnnotation pointAnnotation = new PointAnnotation();
pointAnnotation.setBox(new Rectangle(300, 150, 0, 0));
pointAnnotation.setText("Check this calculation");
annotator.add(pointAnnotation);

Real‑World Use Cases and Applications

Understanding where highlight pdf java adds value helps you decide when to adopt this pattern.

ScenarioHow Annotation Helps
Legal Document ReviewHighlight clauses, add side‑notes, keep a full audit trail without copying files locally.
Engineering Report ProcessingMark critical measurements, attach safety warnings, and share annotated PDFs with remote teams instantly.
Educational Content ManagementTeachers can annotate student submissions stored on FTP, delivering feedback in seconds.
Business IntelligenceFlag key performance indicators in financial PDFs, then generate executive summaries automatically.

Performance Optimization and Best Practices

Memory Management Tips

try‑with‑resources guarantees that streams and the Annotator are closed promptly, preventing memory leaks.

try (Annotator annotator = new Annotator(inputStream)) {
    // Your annotation code here
    annotator.add(annotation);
    annotator.save(outputPath);
} // Automatic resource cleanup
  • Release each stream as soon as you’re done with it.
  • For PDFs exceeding 200 pages, increase the JVM heap (-Xmx2g) or process pages in batches using Annotator’s page‑level API.

Network Optimization Strategies

FTP Connection Pooling

Reusing a single FTPClient instance across multiple files reduces handshake overhead and improves throughput.

FTPClient client = new FTPClient();
client.connect(server);
client.login(username, password);

for (String filePath : filePaths) {
    InputStream stream = client.retrieveFileStream(filePath);
    processAndAnnotate(stream);
}

client.disconnect();
  • Enable passive mode (client.enterLocalPassiveMode()) to traverse firewalls.
  • Implement exponential back‑off retries to handle transient network hiccups gracefully.

Robust Error Handling

Anticipate I/O failures and provide clear recovery paths.

IOException is an exception that signals a failure during input or output operations.

public static InputStream getFileFromFtpWithRetry(String server, String filePath, int maxRetries) {
    for (int attempt = 1; attempt <= maxRetries; attempt++) {
        try {
            return getFileFromFtp(server, filePath);
        } catch (IOException e) {
            if (attempt == maxRetries) {
                throw new RuntimeException("Failed to retrieve file after " + maxRetries + " attempts", e);
            }
            // Wait before retry
            try {
                Thread.sleep(1000 * attempt); // Exponential backoff
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("Interrupted during retry", ie);
            }
        }
    }
    return null;
}
  • Catch IOException and retry up to three times.
  • Log the file name, FTP response code, and stack trace for audit purposes.

Troubleshooting Common Issues

IssueLikely CauseSolution
Connection timed outWrong server/port or firewall blockingVerify the FTP address, open port 21, and enable passive mode.
Authentication failureBad credentials or insufficient permissionsDouble‑check username/password and ensure the account can read the target directory.
“Document format not supported”Corrupted file or non‑PDF contentConfirm the file is a valid PDF and set FTP binary mode (FTP.BINARY_FILE_TYPE).
Annotations not appearingCoordinates outside page bounds or security restrictionsUse page dimensions from PdfInfo to calculate valid rectangles; remove password protection before annotating.
Color not showingIncorrect ARGB valueUse known values: Red = 0xFFFF0000, Green = 0xFF00FF00, Blue = 0xFF0000FF, Yellow = 0xFFFFFF00.

PdfInfo provides metadata about the PDF, including page sizes and count.

Security Considerations for Production Use

  • Never hard‑code credentials – store them in environment variables or a secrets manager.
  • Prefer FTPS (FTP over TLS) to encrypt data in transit.
  • Validate file type and size before processing to guard against malicious payloads.
  • Log every access – maintain an audit trail for compliance and forensic analysis.

Frequently Asked Questions

Q: Can I use this approach with cloud storage services like AWS S3 or Google Drive?
A: Absolutely. Swap the FTP retrieval code with the appropriate SDK call; the annotation logic stays exactly the same.

Q: Which file formats does GroupDocs.Annotation support besides PDF?
A: GroupDocs.Annotation supports 50+ formats, including DOCX, XLSX, PPTX, JPEG, PNG, and CAD files.

Q: How do I handle very large PDFs without exhausting memory?
A: Stream the file, increase the JVM heap if needed, and use the page‑level API to process one page at a time.

Q: Is it possible to read existing annotations from a PDF loaded from FTP?
A: Yes. Call annotator.get() after loading the stream to retrieve all current annotations before adding new ones.

Q: What’s the best way to process hundreds of documents efficiently?
A: Combine FTP connection pooling, Java’s CompletableFuture for asynchronous, non‑blocking execution, and a message queue (e.g., RabbitMQ) to distribute work across multiple worker nodes.

CompletableFuture enables asynchronous, non‑blocking execution of tasks in Java.

What’s Next?

Start by integrating the streaming annotation flow into your existing document‑management service. Then experiment with additional annotation types—stamps, watermarks, and custom shapes—to enrich the user experience. Finally, expose a simple REST endpoint that accepts an FTP path, applies a highlight, and returns the annotated PDF in the response body. This end‑to‑end pipeline will give you a scalable, real‑time PDF processing engine.

Resources and Further Learning


Last Updated: 2026-06-26
Tested With: GroupDocs.Annotation 25.2 for Java
Author: GroupDocs