Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Apache Fop Laravel Package

goetas/apache-fop

PHP wrapper for Apache FOP that renders XSL-FO documents into PDF and other output formats. It offers a simple API to run FOP transformations and integrate FO-based PDF generation into Laravel or any PHP application.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — poor as packaged, salvageable as a pattern. The core issue is a framework mismatch: goetas/apache-fop is a Symfony2 bundle (Bundle subclass, DI service definitions, Configuration tree, compiler passes). Laravel has no bundle/extension concept, so none of the package's intended integration surface is usable. What remains of value is roughly a few hundred lines of glue: a wrapper that shells out to the Apache FOP CLI, assembles arguments (input XML, XSLT/FO stylesheet, output path), and returns a file handle. That logic is trivially reimplementable in a Laravel service provider — which raises the central TPM question: are we adopting a dependency, or copying ~300 lines of abandoned code?

Integration feasibility — blocked before it starts, in the common case. The bundle's composer.json will constrain symfony/framework-bundle/symfony/http-kernel to the 2.x line. Laravel 8+ ships Symfony 5/6 components; Laravel 5.x/6.x ship Symfony 3/4. Composer will refuse to resolve, and forcing it via --ignore-platform-reqs or aliasing invites runtime breakage from autoloaded Symfony classes. The realistic path is not installing the bundle at all and instead treating the repo as reference implementation. Second-order dependency: Apache FOP is a JVM application. This introduces a second runtime (JDK/JRE) into the deployment image, plus FOP's own config (fop.xconf, font directories), which is an infrastructure concern the PHP ecosystem normally avoids.

Technical risk — high, concentrated in abandonment.

  • Last release 2017-05-24; no PHP 7.4/8.x verification, no typed properties, likely deprecation noise or fatal errors on modern PHP.
  • 8 stars, 0 dependents. There is no community to absorb a bug report, no fork to inherit, no security response. Effectively a solo-archive.
  • Symfony 2 reached end-of-life in November 2018; the bundle's integration contract targets an EOL framework regardless of how clean the wrapper code is.
  • Supply-chain: an unmaintained transitive dependency in the PDF generation path is a compliance flag for regulated environments, even if the code is LGPL/MIT and Apache FOP itself is Apache-2.0 and healthy.
  • Mitigant: Apache FOP upstream is actively maintained (2.x line). The risk is entirely in the PHP wrapper, not the rendering engine.

Key questions for the spike.

  1. Is XSL-FO genuinely required — PDF/A, precise pagination, footnotes, multi-column, barcodes, CJK/RTL, accessibility tagging — or would Browsershot/Puppeteer, DomPDF, or mPDF satisfy the layout requirements at far lower operational cost?
  2. Do we already operate a JVM in the target environment? If not, what is the container-size and cold-start cost of adding one?
  3. Expected render volume and P95 latency budget — is this request-path or asynchronous?
  4. Can we maintain a vendored fork, or is the goal to write our own thin FOP client and drop the dependency entirely?
  5. Does the team own XSLT/XSL-FO authoring skill, or is the stylesheet an outsourced artifact?

Integration Approach

Stack fit — treat the package as a design reference, not a dependency. Do not composer require the bundle. If the wrapper logic is worth keeping, vendor it under app/Support/Fop/ with attribution, strip all Symfony imports, and expose it as a singleton bound in a FopServiceProvider. The public surface we actually need is narrow: render(string $xmlPath, string $xsltPath, string $outputPath): string.

Migration path.

  1. Prove the engine outside PHP first. Install Apache FOP 2.x + a JRE, hand-run fop -xml data.xml -xsl style.xsl -pdf out.pdf. If that pipeline cannot produce an acceptable artifact, the PHP layer is irrelevant and the initiative stops here — cheapest possible kill point.
  2. Then prove the contract in PHP. Write a ~200-line Laravel-native client: Process (Symfony Process is already a Laravel dependency, no version conflict), explicit binary path from config, -c fop.xconf, timeout, and temp-directory isolation.
  3. Then harden: config file at config/fop.php, font path assertions at boot, and a health check that verifies JVM + FOP presence.

Compatibility. Pin FOP version in the container image (Dockerfile), not in composer.json. Configure JVM heap (-Xmx) via FOP_OPTS/JAVA_TOOL_OPTIONS — this becomes an ops-owned knob. Ensure the PHP process user has write access to a dedicated /tmp/fop with a cleanup policy.

Sequencing.

  • Phase 0 (1–2 days): spike — engine feasibility + artifact review with the business owner of the document.
  • Phase 1 (1 week): thin Laravel wrapper + feature test asserting a byte-identical or visually-diffed PDF fixture.
  • Phase 2: move generation behind a queued job; return signed URLs from object storage rather than streaming.
  • Phase 3: add observability — render duration, failure taxonomy, JVM exit codes — before scaling volume.

Explicit non-goal: do not attempt to register the GoetasApacheFopBundle in Laravel via a shim. The shim cost exceeds the rewrite cost and locks us to Symfony 2 semantics.

Operational Impact

Maintenance — this becomes an owned fork on day one. There is no upgrade path, no CVE feed, and no issue tracker we can lean on. Budget an ongoing ownership line: one engineer responsible for the vendored code, FOP version bumps, and font assets. Counterweight: the vendored surface is small and the engine (Apache FOP) carries its own upstream maintenance, so the total cost is bounded — but it is ours, not a vendor's.

Support. No upstream support of any kind. Internal runbooks must cover: JVM not found, FOP config not found, font missing (silent substitution → wrong glyphs, a nasty class of bug), malformed XSLT, and non-zero FOP exit codes. The 8-star / 0-dependent profile means we cannot validate our usage against anyone else's.

Scaling. Two dimensions:

  • PHP side scales normally — stateless workers, horizontal.
  • JVM side is the constraint. FOP CLI has no persistent daemon mode; each render pays JVM cold-start (roughly 0.5–2s before any layout work) and a fresh heap. At high volume this dominates latency. Options, in order of preference: (a) keep volume low and accept it, (b) batch documents per JVM invocation, (c) run FOP as a long-lived servlet/service and call it over HTTP, which discards the package's model entirely. Do not discover this at 10× traffic — decide the ceiling during Phase 0.
  • Container images grow by the JRE + FOP distribution (hundreds of MB); plan registry and cold-pull implications.

Failure modes.

Mode Signal Blast radius
JVM OOM on large documents Non-zero exit, stderr heap dump Single render fails; retries amplify load
Subprocess hang (pathological XSLT) No exit within timeout Worker thread pinned — must set a hard timeout
Missing/misnamed font Successful render, wrong glyphs Silent data-integrity bug, worst case
Temp file leak Disk growth Host-level degradation over days
Composer resolution conflict Install-time failure Blocks CI entirely if the bundle is required

The silent font-substitution case is the one to escalate to the business: renders succeed and corrupt documents go out.

Ramp-up. XSL-FO/XSLT 1.0 is a specialized, declining skill; expect a real learning curve for any engineer asked to modify templates, and near-zero availability of new hires with it. Mitigation: keep stylesheets in version control with golden-file visual diffs, and treat template authoring as a named-owner responsibility rather than general team knowledge.

TPM recommendation. Score 0.41 with zero dependents reflects reality. Do not adopt the bundle. Fund a one-week spike to validate Apache FOP itself against the actual document requirements; if FOP clears, build a ~200-line Laravel client and treat this package purely as a reference. If the requirement is ordinary HTML-to-PDF, stop now and use a maintained PHP-native or headless-browser path — the JVM dependency, the XSL-FO skills gap, and permanent fork ownership are not worth paying for anything less than genuine XSL-FO capability.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource