Create Clean PDF Java: Underline Annotations with GroupDocs
Introduction
Struggling with document management and collaboration in your Java applications? You’re not alone. Many developers face the challenge of implementing robust document annotation features that work reliably across different file formats.
In this guide, you’ll create clean PDF Java files and learn how to annotate PDF in Java using GroupDocs.Annotation. By the end of this tutorial, you’ll know exactly how to add underline annotations with comments, remove existing annotations, and integrate these features seamlessly into your projects.
What you’ll master in this guide:
- Setting up GroupDocs.Annotation in your Java project (the right way)
- Adding underline annotations with custom comments and styling
- Removing all annotations to create clean document versions
- Troubleshooting common issues developers encounter
- Optimizing performance for production applications
Whether you’re building a document review system, educational platform, or collaborative editing tool, this tutorial has you covered with practical, tested code examples.
Quick Answers
- How do I add an underline annotation? Use
UnderlineAnnotationandannotator.add()then save the document. - How can I create a clean PDF Java file? Load the annotated file, set
AnnotationType.NONEinSaveOptions, and save a new copy. - What libraries are required? GroupDocs.Annotation v25.2 (or newer) and its Maven repository.
- Do I need a license for production? Yes—apply a valid GroupDocs license to avoid watermarks.
- Can I process multiple documents efficiently? Wrap each
Annotatorin a try‑with‑resources block and dispose after each file.
How to create clean PDF Java files
Creating a clean PDF Java file means generating a version of the document without any annotations while preserving the original content. This is useful for final distribution, archival, or when you need to share a “clean” copy after a review cycle.
GroupDocs.Annotation makes this straightforward: load the annotated file, configure SaveOptions to exclude all annotation types, and save the result. The steps are illustrated later in the Removing Annotations section.
How to annotate PDF in Java using GroupDocs
GroupDocs.Annotation provides a rich API for annotate PDF in Java. It supports a wide range of annotation types, including highlights, stamps, and underlines. In this tutorial we focus on underline annotations because they are commonly used for emphasizing text while allowing threaded comments.
Prerequisites and Environment Setup
What You’ll Need Before Starting
Development Environment Requirements:
- Java Development Kit (JDK) 8 or higher (JDK 11+ recommended)
- Maven 3.6+ or Gradle 6.0+ for dependency management
- IDE such as IntelliJ IDEA, Eclipse, or VS Code with Java extensions
- At least 2 GB of available RAM (document processing can be memory‑intensive)
Knowledge Prerequisites: You should be comfortable with basic Java concepts—object initialization, method calls, and Maven dependencies. Prior experience with third‑party libraries will speed up adoption.
Testing Documents: Have a few sample PDFs ready. Text‑based PDFs work best; scanned images may require OCR before annotation.
Maven Setup: Getting GroupDocs Into Your Project
Here’s how to properly configure your Maven project (this trips up many developers on their first attempt):
<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>
Important: Version 25.2 is the latest stable release at the time of writing. Check the GroupDocs repository regularly for newer versions that include bug fixes and performance improvements.
Licensing Setup (Don’t Skip This)
For Development/Testing:
Download the free trial from the GroupDocs website. The trial includes all features but adds a watermark to processed documents.
For Production:
Purchase a license and apply it during application startup. Without a valid license, production builds will be limited.
Implementation Guide: Adding Underline Annotations
Understanding the Annotation Workflow
Before we dive into code, let’s walk through the four‑step workflow that occurs when you annotate PDF in Java:
- Document Loading –
Annotatorreads the file into memory. - Annotation Creation – Define properties such as position, style, and comments.
- Annotation Application – The library injects the annotation into the PDF’s structure.
- Document Saving – Persist the modified file, optionally preserving the original.
The process is non‑destructive; the source file remains untouched unless you overwrite it.
Step 1: Initialize the Annotator and Load Your Document
import com.groupdocs.annotation.Annotator;
// Load the document you want to annotate
Annotator annotator = new Annotator("YOUR_DOCUMENT_DIRECTORY/input.pdf");
Pro Tip: Use absolute paths while developing to avoid “file not found” errors. In production, consider loading resources from the classpath or a cloud storage bucket.
Step 2: Creating Comments and Replies (The Collaborative Part)
import com.groupdocs.annotation.models.Reply;
import java.util.Calendar;
import java.util.ArrayList;
import java.util.List;
Reply reply1 = new Reply();
reply1.setComment("First comment");
reply1.setRepliedOn(Calendar.getInstance().getTime());
Reply reply2 = new Reply();
reply2.setComment("Second comment");
reply2.setRepliedOn(Calendar.getInstance().getTime());
List<Reply> replies = new ArrayList<>();
replies.add(reply1);
replies.add(reply2);
Real‑World Use: Reviewers can discuss a specific clause by adding threaded replies, keeping the conversation tied to the exact annotation.
Step 3: Defining Annotation Coordinates (Getting the Position Right)
import com.groupdocs.annotation.models.Point;
Point point1 = new Point(80, 730);
Point point2 = new Point(240, 730);
Point point3 = new Point(80, 650);
Point point4 = new Point(240, 650);
List<Point> points = new ArrayList<>();
points.add(point1);
points.add(point2);
points.add(point3);
points.add(point4);
Coordinate System:
- Points 1 & 2 define the top edge of the underline.
- Points 3 & 4 define the bottom edge.
- The Y‑difference (730 vs 650) controls thickness.
Step 4: Creating and Configuring the Underline Annotation
import com.groupdocs.annotation.models.annotationmodels.UnderlineAnnotation;
UnderlineAnnotation underline = new UnderlineAnnotation();
underline.setCreatedOn(Calendar.getInstance().getTime());
underline.setFontColor(65535); // Yellow in ARGB format
underline.setMessage("This is an underline annotation");
underline.setOpacity(0.7f);
underline.setPageNumber(0);
underline.setPoints(points);
underline.setReplies(replies);
annotator.add(underline);
Color & Opacity Tips:
FontColoruses ARGB;65535(0x00FFFF) yields bright yellow.- For red, use
16711680(0xFF0000); for blue,255(0x0000FF). - Opacity values between 0.5 and 0.8 provide good readability without obscuring the text.
Step 5: Saving Your Annotated Document
String outputPath = "YOUR_OUTPUT_DIRECTORY/output.pdf";
annotator.save(outputPath);
annotator.dispose();
Memory Management: The dispose() call releases native resources and prevents memory leaks—critical when processing many files in a batch.
Removing Annotations: Creating Clean Document Versions
Sometimes you need a version of the PDF without any annotations—for example, when delivering the final approved contract. GroupDocs makes this easy.
Understanding Annotation Removal Options
You can:
- Remove all annotations (most common)
- Remove specific types (e.g., only highlights)
- Remove annotations by author or page
Step‑by‑Step Annotation Removal
Step 1: Load the Previously Annotated Document
Annotator annotator = new Annotator(outputPath);
Step 2: Configure Save Options for a Clean Output
import com.groupdocs.annotation.options.export.AnnotationType;
import com.groupdocs.annotation.options.export.SaveOptions;
SaveOptions saveOptions = new SaveOptions();
saveOptions.setAnnotationTypes(AnnotationType.NONE);
Step 3: Save the Clean Version
String noneAnnotationPath = Paths.get(outputPath).resolveSibling("none-annotation.pdf").toString();
annotator.save(noneAnnotationPath, saveOptions);
annotator.dispose();
This produces a clean PDF Java file that contains no annotation objects, perfect for final distribution.
Common Issues and Solutions
Problem 1: “Document not found” Errors
File inputFile = new File("path/to/your/document.pdf");
if (!inputFile.exists()) {
throw new IllegalArgumentException("Document not found: " + inputFile.getAbsolutePath());
}
if (!inputFile.canRead()) {
throw new IllegalArgumentException("Cannot read document: " + inputFile.getAbsolutePath());
}
Annotator annotator = new Annotator(inputFile.getAbsolutePath());
Problem 2: Annotations Appearing in Wrong Locations
// Test with a simple rectangle in the top‑left corner
Point point1 = new Point(10, 10); // Top‑left
Point point2 = new Point(100, 10); // Top‑right
Point point3 = new Point(10, 30); // Bottom‑left
Point point4 = new Point(100, 30); // Bottom‑right
Problem 3: Memory Issues with Large Documents
// Increase JVM heap size when launching the app, e.g., -Xmx2g
try (Annotator annotator = new Annotator("document.pdf")) {
// Annotation logic here
annotator.save("output.pdf");
}
Problem 4: Licensing Issues in Production
try {
License license = new License();
license.setLicense("path/to/your/license.lic");
System.out.println("License loaded successfully");
} catch (Exception e) {
System.err.println("License loading failed: " + e.getMessage());
// Handle the error appropriately
}
Performance Best Practices for Production Applications
Memory Management Strategies
try (Annotator annotator = new Annotator("input.pdf")) {
// Your annotation logic
annotator.save("output.pdf");
} // Annotator is automatically disposed here
List<String> documentPaths = Arrays.asList("doc1.pdf", "doc2.pdf", "doc3.pdf");
for (String docPath : documentPaths) {
try (Annotator annotator = new Annotator(docPath)) {
// Process one document at a time
annotator.add(createAnnotation());
annotator.save(getOutputPath(docPath));
}
// Memory is freed after each iteration
}
Threading Considerations
GroupDocs.Annotation is not thread‑safe by default. If your application processes documents concurrently:
- Never share an
Annotatorinstance across threads. - Synchronize file access or use a lock mechanism.
- Consider a pool of
Annotatorobjects if you need high throughput.
Caching Strategies
- Cache frequently used annotation templates.
- Reuse
Pointcollections for common coordinate sets. - Keep a template PDF in memory if you repeatedly annotate the same base document.
Real‑World Applications and Use Cases
Document Review Systems
- Legal Review: Underline contract clauses and add comments about risk.
- Compliance Audits: Highlight problematic sections in financial statements.
- Academic Peer Review: Professors underline passages needing clarification.
Educational Platforms
- Student Annotation Tools: Let learners underline key concepts in e‑books.
- Teacher Feedback: Provide inline comments directly on submitted assignments.
Quality Assurance Workflows
- Technical Documentation Review: Engineers underline sections that need updates.
- Standard Operating Procedures: Safety officers highlight critical steps.
Content Management Systems
- Editorial Workflow: Editors underline text that requires fact‑checking.
- Version Control: Track annotation history across document revisions.
Advanced Tips for Professional Implementation
Custom Annotation Styles
UnderlineAnnotation underline = new UnderlineAnnotation();
underline.setFontColor(16711680); // Red for urgent items
underline.setOpacity(0.5f); // Subtle highlighting
underline.setFontSize(12); // Consistent sizing
underline.setMessage("URGENT REVIEW REQUIRED");
Annotation Metadata for Tracking
underline.setCreatedBy("john.doe@company.com");
underline.setCreatedOn(Calendar.getInstance().getTime());
underline.setMessage("Legal review required - Contract clause 4.2");
Integration with User Management Systems
// Assume you have a method that returns the current authenticated user
String currentUser = getCurrentUser();
String userRole = getUserRole(currentUser);
// Apply role‑based styling
UnderlineAnnotation underline = new UnderlineAnnotation();
underline.setCreatedBy(currentUser);
underline.setFontColor(getRoleColor(userRole));
underline.setMessage(String.format("[%s] %s", userRole.toUpperCase(), commentText));
Troubleshooting Production Issues
Performance Monitoring
Watch these metrics in production:
- Heap usage – ensure
dispose()is called. - Processing time per document – log timestamps before/after
annotator.save(). - Error rate – capture exceptions and categorize them.
Common Production Gotchas
- File locking – ensure uploaded files are closed before annotation.
- Concurrent edits – implement optimistic locking or version checks.
- Large files (> 50 MB) – increase JVM timeout and consider streaming APIs.
Error Handling Best Practices
try (Annotator annotator = new Annotator(documentPath)) {
UnderlineAnnotation annotation = createAnnotation();
annotator.add(annotation);
annotator.save(outputPath);
} catch (Exception e) {
logger.error("Annotation failed for document: " + documentPath, e);
// Implement appropriate error recovery
throw new DocumentProcessingException("Failed to annotate document", e);
}
Conclusion
You now have everything needed to create clean PDF Java files and annotate PDF in Java with underline annotations using GroupDocs.Annotation. Remember to:
- Manage resources with try‑with‑resources or explicit
dispose(). - Validate coordinates early to avoid misplaced underlines.
- Implement robust error handling for production stability.
- Leverage role‑based styling and metadata to fit your workflow.
Next steps? Try adding other annotation types—highlights, stamps, or text replacements—to build a full‑featured document review solution.
Frequently Asked Questions
Q: How do I annotate multiple areas of text in a single operation?
A: Create several UnderlineAnnotation objects with different coordinates and add them sequentially using annotator.add().
Q: Can I annotate images within PDF documents?
A: Yes. Use the same coordinate system, ensuring the points lie inside the image bounds.
Q: What file formats besides PDF does GroupDocs.Annotation support?
A: Word (DOC/DOCX), Excel (XLS/XLSX), PowerPoint (PPT/PPTX), and image formats such as JPEG, PNG, TIFF.
Q: How do I handle very large documents without running out of memory?
A: Process documents one at a time, increase the JVM heap (-Xmx), and always dispose of Annotator instances promptly.
Q: Is it possible to extract existing annotations from a document?
A: Yes. Use annotator.get() to retrieve all annotations, then filter by type, author, or page as needed.
Last Updated: 2025-12-21
Tested With: GroupDocs.Annotation 25.2
Author: GroupDocs