Skip to content

Bundle commons-codec with common.eval to complete commons-csv's closure#66

Merged
khatchad merged 1 commit into
masterfrom
issue-64-commons-codec-dependency
Jun 25, 2026
Merged

Bundle commons-codec with common.eval to complete commons-csv's closure#66
khatchad merged 1 commit into
masterfrom
issue-64-commons-codec-dependency

Conversation

@khatchad

@khatchad khatchad commented Jun 25, 2026

Copy link
Copy Markdown
Member

Problem

The commons-io fix in v5.6.0 (#65) got the bundled commons-csv past its first missing transitive dependency, but commons-csv 1.12.0's runtime closure is both commons-io and commons-codec. It references org.apache.commons.codec.binary.Base64OutputStream, so a materialized product now fails one step further under strict OSGi classloading:

java.lang.NoClassDefFoundError: org/apache/commons/codec/binary/Base64OutputStream
  at edu.cuny.citytech.refactoring.common.eval.handlers.EvaluateRefactoringHandler.createCSVPrinter(EvaluateRefactoringHandler.java:24)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.codec.binary.Base64OutputStream
  cannot be found by edu.cuny.citytech.refactoring.common.eval_5.6.0

Why Bundling (Not Option 2)

commons-csv's own OSGi manifest enumerates its complete runtime closure via Import-Package: exactly org.apache.commons.codec.binary and the org.apache.commons.io.* packages. So the closure is bounded (io plus codec), not open-ended whack-a-mole. Bundling keeps common.eval self-contained, which is the most robust posture for the materialized headless product that surfaced this (the bundle carries its entire commons-csv closure in its own classloader, rather than depending on the product to assemble extra bundles correctly).

Option 2 (depend on the org.apache.commons.csv bundle) is feasible via a Tycho 5 Maven target location, but it moves three jars out of common.eval and makes the product responsible for including them, more surface area for this same class of failure, to solve a closure problem that is already proven bounded.

Fix

Bundle commons-codec 1.17.1 the same way commons-io and commons-csv are bundled:

  • Add lib/commons-codec-1.17.1.jar (plus sources/javadoc) to lib/.
  • Add it to Bundle-ClassPath (META-INF/MANIFEST.MF).
  • Add it to bin.includes (build.properties) so Tycho packages it.
  • Add the lib entry with source/javadoc attachments (.classpath) for IDE development.

commons-codec is not exported. It stays private to this bundle's classloader, so it does not split-package with a product's own commons-codec bundle.

Maintenance note: on each future commons-csv upgrade, re-check the csv jar's manifest Import-Package and bundle any newly added transitive dependency.

Re #64.

🤖 Generated with Claude Code

The commons-io fix in v5.6.0 (#65) got the bundled commons-csv past its first
missing transitive dependency, but commons-csv 1.12.0's runtime closure is
both commons-io and commons-codec: it references
org.apache.commons.codec.binary.Base64OutputStream, yielding a second
NoClassDefFoundError under strict OSGi classloading in a materialized product.

commons-csv's own OSGi manifest enumerates its complete runtime closure via
Import-Package: exactly org.apache.commons.codec.binary and the
org.apache.commons.io.* packages. So the closure is bounded (io plus codec),
not open-ended. Bundle commons-codec 1.17.1 the same way commons-io and
commons-csv are bundled: self-contained, private to this bundle's classloader
(not exported), so common.eval carries its entire commons-csv closure inside
its own classloader regardless of what else the product assembles.

Maintenance note: on each future commons-csv upgrade, re-check the csv jar's
manifest Import-Package and bundle any newly added transitive dependency.

Re #64.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015jRmWZMAqpMDjsKmTATy3A
@khatchad
khatchad merged commit 731ad00 into master Jun 25, 2026
5 checks passed
@khatchad
khatchad deleted the issue-64-commons-codec-dependency branch June 25, 2026 00:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant