Skip to content

build!: leave the s3: crawler client to the fess-storage-s3 plugin - #204

Merged
marevol merged 1 commit into
masterfrom
feat/unregister-s3-client
Sep 10, 2026
Merged

marevol merged 1 commit into
masterfrom
feat/unregister-s3-client

Conversation

@marevol

@marevol marevol commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

First of three PRs that move the S3 storage backend out of the Fess distribution, following what codelibs/fess#3424 and #203 did for Google Cloud Storage. Merge this one first, and let its snapshot publish before the Fess side lands.

S3Client and the s3: URL handler stay here and keep compiling against the AWS SDK; only the registration moves. The SDK itself leaves the war through an exclusion on the Fess side, and ships in the new fess-storage-s3 plugin, which declares the s3Client component and registers it through crawlerClientCreator — the way fess-crawler-playwright registers playwrightClient.

Why the registration cannot stay here

clientFactory resolves its component references when the factory is created, not when a client is first used. A reference to s3Client therefore makes every CrawlerClientFactory fail to build wherever the SDK is absent, which is every installation without the plugin. That is the same reason the gcsClient registration was removed in #203.

Verified

A LastaDi container was booted on a plain JVM with crawler/client.xml, crawler/mimetype.xml and fess_storage.xml, on a class path built the way Fess builds one — WEB-INF/classes, then the war's runtime jars with the AWS SDK excluded, then the plugin jar.

With this change, clientFactory builds and maps s3://bucket/key to org.codelibs.fess.crawler.client.s3.S3Client — the class from this library, registered by the plugin.

Without it, using the current crawler/client.xml against the same plugin:

TooManyRegistrationComponentException
[Component Key] s3Client
[Registered Components]
  componentName: s3Client  definedDiXml: crawler/client.xml
  componentName: s3Client  (from the plugin's crawler/client++.xml)

clientFactory fails to build there, so every crawl dies — which is what makes the merge order a requirement rather than a preference, and why the plugin is paired with a Fess version.

Also in this change

The gcs: comment being replaced still named fess-lib-gcs, which was renamed to fess-storage-gcs before it was ever published. Both protocols now share one comment.

No test changes: the S3 tests here build their own container with .singleton("s3Client", S3Client.class) rather than reading crawler/client.xml, so none of them pins the registration. crawler/client.xml is not read by any test in this repository.

S3Client and the s3: URL handler stay in this library, but the AWS SDK they
need is 30 jars that only installations crawling S3 ever load. Fess ships it
in the fess-storage-s3 plugin, which declares the s3Client component and
registers it through crawlerClientCreator, the way fess-crawler-playwright
registers playwrightClient and fess-storage-gcs registers gcsClient.

The registration cannot stay here. clientFactory resolves its component
references when the factory is created, not when a client is first used, so a
reference to s3Client would make every CrawlerClientFactory fail to build
wherever the SDK is absent -- which is every installation without the plugin.
The class itself keeps compiling against the SDK and costs a few tens of KiB,
so nothing moves out of this library.

The gcs: comment this replaces still named fess-lib-gcs, which was renamed to
fess-storage-gcs before it was published; both protocols now share one comment.
@marevol marevol self-assigned this Sep 10, 2026
@marevol marevol added this to the 15.9.0 milestone Sep 10, 2026
@marevol
marevol merged commit 1863a6e into master Sep 10, 2026
1 check passed
marevol added a commit to codelibs/fess-parent that referenced this pull request Sep 10, 2026
…lished (#80)

These two repositories are how one repository in this family sees another's
change, and Maven's default updatePolicy for a snapshot is daily. A build whose
local repository already resolved a -SNAPSHOT earlier the same day never asks
again, so a CI job that caches ~/.m2 cannot see a sibling's snapshot published
minutes ago. updatePolicy always removes that window.

Measured, not assumed. codelibs/fess-crawler#204 merged at 02:48:54 and its
snapshot deployed at 02:49:31. codelibs/fess#3428, which depends on it, was
re-run at 02:59:29 -- ten minutes after the fix was published -- and failed with

  DiXmlParseFailureException: crawler/client.xml included by app.xml
  Caused by: NoClassDefFoundError: software/amazon/awssdk/auth/credentials/AwsCredentials

because it built against the previous fess-crawler-lasta. The job log contains
no request to maven.codelibs.org at all: not one "Downloading from
codelibs.org.snapshot" line, while "Cache restored from key: Linux-maven-..."
sits at the top. The published jar was correct the whole time.

Reproduced and fixed locally on the same shape of cache. Before, the resolved
fess-crawler-lasta-15.9.0-SNAPSHOT.jar declared one s3Client component; after
installing this pom and resolving once, it declares none and names the plugin
that took over, and the timestamped build the fix landed in appears in ~/.m2.
The Fess branch's DI container then built clientFactory and mapped
s3://bucket/key, using nothing but published artifacts.

Every consumer inherits this, which is the point: the plugin repositories'
CI installs this pom from source and then resolves org.codelibs.fess:fess from
these repositories, so they are in the same window whenever core publishes.

The cost is one metadata request per snapshot dependency per build. Offline
builds skip it, and a release build has no snapshot dependencies to check.
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