Why planning this Migration matters
PDF generation is a core deliverable in many ColdFusion applications—think invoices, statements, labels, reports, and contracts. As ColdFusion versions evolve, so do the PDF engines, Security baselines, and packaging model. Migrating your PDF generation services reduces runtime risk, unlocks better HTML/CSS support, and improves Performance and maintainability. It’s also an opportunity to standardize fonts, stabilize layouts, and prepare for Containerization and CI/CD.
Prerequisites / Before You Start
Supported versions and components
- Target ColdFusion release selected and licensed (e.g., ColdFusion 2018, 2021, or 2023).
- Java version supported by your target ColdFusion version (match Adobe’s matrix).
- Decide on your rendering engine:
- cfdocument (iText-based)
- cfhtmltopdf with the PDFg add-on service
- External renderer (e.g., headless Chrome/wkhtmltopdf) orchestrated by CFML
Backups and exports
- Full file-System backup of the current ColdFusion installation:
- cfusion/wwwroot (or your webroot)
- cfusion/lib, cfusion/bin, cfusion/logs
- Any custom Java libraries or OSGi bundles
- Configuration backups:
- ColdFusion Administrator export (CFArchive/CAR) if available in your version
- Or use the cfsetup CLI (CF2021/2023):
- Export settings, datasources, mail servers, Security, and PDF settings
- Application codebase (Git repo or compressed snapshot)
- PDF templates, images, CSS, fonts, and watermark/background assets
- If using a remote PDF service or third-party tool, export its config and SSL certificates
Dependencies and assets
- Fonts required for Unicode/CJK/RTL or brand typography
- Images and SVGs stored locally or in a CDN (confirm access and HTTPS)
- Certificates for HTTPS calls to external assets (import into the JVM truststore if needed)
- OS packages needed by headless rendering (e.g., fontconfig, freetype, system fonts, NSS libraries)
- Network access to UNC paths or NFS mounts if used in code
Security and Compliance
- Security sandbox settings that allow file I/O where needed
- Data classification for content embedded in PDFs (PII, financial)
- PDF/A or archival Compliance requirements
- FIPS, TLS, and cipher requirements
- Service account credentials for Windows/Linux services if accessing network shares
Choosing your PDF generation approach
Option A: Stay with cfdocument
- Pros:
- Simple Migration (often drop-in)
- Stable API: cfdocument, cfpdf, cfpdfform
- No separate service to install
- Cons:
- HTML/CSS support is limited compared to modern engines
- Advanced layouts (flexbox/grid) may need workarounds
Option B: Migrate to cfhtmltopdf + PDFg service
- Pros:
- Better HTML5/CSS3 rendering fidelity than cfdocument
- Headers/footers, page breaks, and pagination control via cfhtmltopdf/cfhtmltopdfitem
- Centralized Scaling with the add-on service, plus failover
- Cons:
- Requires installing and maintaining the PDFg add-on service
- Additional ports, SSL, and OS library considerations
Option C: External renderer (wkhtmltopdf or headless Chrome via command line or microservice)
- Pros:
- Maximum flexibility; identical output to your browser’s engine (Chromium)
- Can be containerized and scaled independently
- Cons:
- You own orchestration, upgrades, and Integration patterns
- Additional Error handling and security responsibilities
Quick decision matrix
| Requirement | cfdocument | cfhtmltopdf + PDFg | External (Chrome/wkhtmltopdf) |
|---|---|---|---|
| Minimal changes | Strong | Moderate | Moderate/High |
| Modern CSS support | Fair | Good | Excellent |
| Operational overhead | Low | Medium | Medium/High |
| Horizontal scale | Fair | Good | Excellent |
| Air-gapped/locked-down env | Strong | Moderate | Varies |
Step-by-step Migration guide
1) Inventory and classify current PDF use cases
- Collect all cfdocument, cfhtmltopdf, cfpdf usage:
- Search your codebase for cfdocument, cfhtmltopdf, cfpdf, cfpdfform.
- Classify templates by complexity:
- Simple (static content, basic CSS)
- Medium (dynamic tables, images, page breaks)
- Complex (multi-language, SVG, barcodes, signatures, heavy layout)
- Identify dependencies:
- Fonts, CSS frameworks, images, dynamic charts, QR/barcodes
- External assets (CDN, S3/Azure, internal HTTPS endpoints)
Output: a spreadsheet mapping template -> engine -> assets -> complexity -> test case link.
2) Stand up your target environment
- Install the target ColdFusion version on a staging server or container.
- Align Java version to ColdFusion’s support matrix.
- Harden baseline:
- Configure datasources, mail, caches, request tuning (max threads, timeouts)
- Apply latest security updates and hotfixes
3) Install PDF packages and PDFg, as applicable
For CF2021/2023 modular packaging:
- List and install packages:
Windows
cfpm.bat list
cfpm.bat install pdf
cfpm.bat install htmltopdf
Linux/macOS
./cfpm.sh list
./cfpm.sh install pdf
./cfpm.sh install htmltopdf
- Install the ColdFusion PDFg add-on service on the same or separate host(s). During installation, note the service ports and SSL settings.
4) Configure the PDFg connection (if using cfhtmltopdf)
- In ColdFusion Administrator:
- Navigate to HTML to PDF / PDF Service settings
- Set PDFg host, port, protocol (HTTP/HTTPS)
- Optional: configure multiple servers for failover
- Set connection/read timeouts and maximum concurrent conversions
- Validate service health:
- Check PDFg logs and confirm the service is reachable from the CF server
- Open outbound firewall rules if the PDFg service is remote
5) Update code paths and templates
- If staying with cfdocument, ensure localurl is set where you reference local files:
- Migrating from cfdocument to cfhtmltopdf:
#renderedHtml#
- Merging PDFs still uses cfpdf:
<cfpdf action=”merge”
source=”#expandPath(‘/pdf/a.pdf’)#,#expandPath(‘/pdf/b.pdf’)#”
destination=”#expandPath(‘/pdf/merged.pdf’)#”
overwrite=”true” />
Tip: For large HTML, avoid generating massive strings. Stream parts or write temporary HTML files, then pass a file path.
6) Fonts and internationalization
- Install required fonts on the OS and ensure they are discoverable by fontconfig (Linux).
- Reference fonts in your CSS with explicit font-family fallbacks:
@font-face {
font-family: ‘AcmeSans’;
src: url(‘/assets/fonts/AcmeSans-Regular.ttf’) format(‘truetype’);
font-weight: 400; font-style: normal;
}
body { font-family: ‘AcmeSans’, ‘Noto Sans’, Arial, sans-serif; }
- For CJK or RTL scripts, install the Noto family or equivalent and verify glyph coverage.
- Use utf-8 throughout and ensure your HTML declares the charset.
7) Resource paths, HTTPS, and Sandbox security
- Prefer absolute URLs or localurl=”yes” to resolve local assets.
- If fetching assets over HTTPS:
- Import your organization’s CA chain into the ColdFusion JVM truststore:
- keytool -importcert -keystore cacerts -file yourCA.cer
- Import your organization’s CA chain into the ColdFusion JVM truststore:
- For network shares:
- Run services under domain accounts with proper ACLs
- Use UNC paths, not mapped drives
- Review sandbox permissions to allow reading templates, fonts, and images.
8) Performance tuning and capacity
- ColdFusion JVM heap:
- Size heap to handle peak concurrent renders; PDF generation is memory intensive.
- Example JVM args (adjust to your environment):
-Xms2g
-Xmx4g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
- PDFg concurrency:
- In Administrator, set max concurrent conversions conservatively, then scale after testing.
- Template Optimization:
- Minimize large inline images; use compressed formats
- Use print CSS to hide nonessential elements
- Avoid heavy box-shadow or filters when not necessary
9) Automated tests and visual regression
- Unit-level verification:
- Extract text with PDFBox or cfpdf action=”extracttext” and assert key content
- Pixel/visual diff:
- Render to images (e.g., Ghostscript or pdfium) and compare against baselines
- Performance:
- Time-to-first-byte and total render time at various sizes and concurrencies
- Internationalization:
- Include multilingual test PDFs for each script and compare glyph coverage
10) Deployment and rollback
- Blue/green or canary Deployment for PDF endpoints
- Keep both engines available behind feature flags for a release window
- Rollback plan:
- Toggles to revert to the prior engine
- Restore prior config and backups if needed
11) Observability and logging
- Enable sufficient logging in ColdFusion and the PDFg service
- Aggregate logs to your SIEM
- Track:
- Render failures and timeouts
- Average render time and size
- Out-of-memory or GC pressure
- Use ColdFusion Performance monitoring Toolset or a third-party APM for insights
Risks, Common Issues, and How to Avoid Them
- Missing fonts cause tofu/garbled characters
- Mitigation: Install required fonts, define @font-face, provide fallbacks, and test multilingual documents.
- Different CSS support changes layout
- Mitigation: Add print stylesheets; avoid browser-specific CSS; test nested flexbox/grid for cfdocument; prefer cfhtmltopdf for complex layouts.
- External asset failures (SSL/TLS, DNS, timeouts)
- Mitigation: Import CA certs, configure truststores, add retries/timeouts, and host critical assets locally or via a highly available CDN.
- Long render times or timeouts on complex pages
- Mitigation: Simplify DOM/CSS, paginate properly, limit images, and increase service timeouts with careful Benchmarking.
- Sandbox/file permissions break local asset loading
- Mitigation: Configure sandbox rules; use localurl=”yes”; run services with least-privilege accounts that still have required access.
- Version incompatibilities between CF and Java
- Mitigation: Match Adobe’s supported Java versions; pin Java to the recommended build; retest after JVM updates.
- PDFg add-on service not reachable
- Mitigation: Validate host/port/SSL; open firewall rules; use health checks; define multiple PDFg servers for failover.
- Memory pressure and JVM crashes
- Mitigation: Right-size heap; set GC tuning; use performance monitors; isolate large batch jobs to off-peak windows.
Post-Migration Checklist / Validation Steps
- Functionality
- Can all endpoints that generate PDFs still return expected content?
- Headers, footers, watermarks, bookmarks, and hyperlinks behave as expected.
- Visual
- Layouts match baselines or acceptable deltas documented.
- Fonts and glyphs render correctly across languages.
- Performance
- Median and p95 render times meet SLAs.
- Throughput and concurrency validated under load.
- Security and compliance
- TLS truststore configured; no mixed-content errors.
- PDFs meet any PDF/A or accessibility requirements you track.
- Operations
- Logs show no recurring errors; alert thresholds set.
- Backups and retention policies confirmed for generated documents.
- Runbooks updated: restart procedures, failover, incident steps.
- Cost and scale
- If using external renderer or PDFg clusters, capacity and autoscaling verified.
- Sign-off
- Stakeholders review sample PDFs; QA test suite passes.
- Feature flag final switch and rollback plan documented.
Configuration snippets and reference
Sample Docker Compose (ColdFusion + external headless Chrome)
version: ‘3.9’
services:
coldfusion:
image: adobecoldfusion:2023.0
environment:
- acceptEULA=YES
ports: - “8500:8500”
depends_on: - chrome
volumes: - ./app:/app
chrome:
image: ghcr.io/puppeteer/puppeteer:latest
shm_size: ‘1gb’
command: [“bash”, “-c”, “google-chrome-stable –headless –remote-Debugging-address=0.0.0.0 –remote-Debugging-port=9222 –no-sandbox”]
ports: - “9222:9222”
You can call Chromium from CFML via cfexecute or an HTTP controller microservice. Validate security boundaries when doing so.
Windows service management (PDFg add-on)
sc query “ColdFusion PDFg Add-on Service”
sc stop “ColdFusion PDFg Add-on Service”
sc start “ColdFusion PDFg Add-on Service”
Confirm the exact service name created by your installer/version.
Useful CFML snippets
- Save to a temp file then serve:
<cfset tmp = getTempDirectory() & createUUID() & “.pdf”>
#html#
- Merge and secure a PDF:
<cfpdf action=”protect”
source=”merged.pdf” destination=”secured.pdf” overwrite=”true”
ownerpassword=”StrongPass123″
permissions=”print,copy” />
- Extract text for assertions:
FAQ
Do I have to use the PDFg add-on to generate PDFs with ColdFusion?
No. You can continue using cfdocument without the add-on. However, cfhtmltopdf relies on the PDFg service. If you want modern HTML/CSS fidelity without PDFg, consider orchestrating an external renderer like headless Chrome, but that adds operational complexity.
Will my cfdocument output change when upgrading ColdFusion?
Possibly. Even with the same tag, internal libraries and CSS handling can differ between versions. Plan for visual regression testing, particularly around pagination, fonts, and positioning. Keep print-specific CSS and minimize complex layout tricks.
How do I fix missing characters or boxes in multilingual PDFs?
Install and reference fonts that include the required glyphs (e.g., Noto families for CJK, Arabic, Hebrew). Define @font-face, ensure the files are accessible to the rendering engine, and verify that your HTML/CSS sets the intended font-family. Confirm UTF-8 encoding.
Can I scale PDF generation horizontally?
Yes. With cfhtmltopdf, deploy multiple PDFg instances and configure failover in ColdFusion Administrator. For external engines, run multiple replicas behind a load balancer. Also consider queueing batch jobs to smooth spikes.
Is there a recommended way to test PDF correctness automatically?
Combine text extraction checks (with cfpdf or PDFBox) for content verification and image-based diffing for layout regression. Run these in CI on representative templates and data, and maintain approved baseline artifacts for Comparison.
