Skip to content

Conversation

@kwin
Copy link
Member

@kwin kwin commented Sep 16, 2025

This closes #1587

Following this checklist to help us incorporate your
contribution quickly and easily:

  • Your pull request should address just one issue, without pulling in other changes.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Each commit in the pull request should have a meaningful subject line and body.
    Note that commits might be squashed by a maintainer on merge.
  • Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied.
    This may not always be possible but is a best-practice.
  • Run mvn verify to make sure basic checks pass.
    A more thorough check will be performed on your pull request automatically.
  • You have run the integration tests successfully (mvn -Prun-its verify).

If your pull request is about ~20 lines of code you don't need to sign an
Individual Contributor License Agreement if you are unsure
please ask on the developers list.

To make clear that you license your contribution under
the Apache License Version 2.0, January 2004
you have to acknowledge this by using the following check-box.

@kwin kwin requested a review from cstamas September 16, 2025 15:22
@kwin kwin force-pushed the feature/doc-deployment branch 4 times, most recently from 86c0641 to 1c7deb6 Compare September 16, 2025 16:13
@kwin kwin force-pushed the feature/doc-deployment branch from 1c7deb6 to a91fab8 Compare September 16, 2025 17:04
@cstamas
Copy link
Member

cstamas commented Sep 16, 2025

The "Maven way" of wanted topic "deploy API using PUT by default for HTTP" is true IF following conditions are true:

  • last connector in pipeline (mvn3 does not have it, but similar thing happens effectively, while mvn4 has dedicated API for this for programmatic construction) is basic connector
  • transport being used is some of HTTP implementations (apache, jdk or jetty) -- usually transport selection happens based 0n RemoteRepository#getProtocol() (but as always, there are exceptions)

In that case, one can say that "deploy" call maps to HTTP PUT method for each artifact and metadata.

under the License.
-->

Deploying artifacts and related metadata to a (remote) repository can be achieved via Resolver API with method [`org.eclipse.aether.RepositorySystem.deploy(RepositorySystemSession session, DeployRequest request)`](https://github.com/apache/maven-resolver/blob/master/maven-resolver-api/src/main/java/org/eclipse/aether/RepositorySystem.java). This writes/uploads the given artifact(s) including metadata to the given repository leveraging a [`RepositoryConnector`](https://github.com/apache/maven-resolver/blob/master/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/RepositoryConnector.java).
Copy link
Member Author

@kwin kwin Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about checksums? Are they treated as separate artifacts like signatures?

Copy link
Member

@cstamas cstamas Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, checksums are feature of basic connector (check out M2 layout, that one contains the "configured" checksums), and they are opaquely (to client) being uploaded (on deploy) or being asked for (on consume) by basic connector. No client code should ever mangle with them (while deploying or resolving).

Though, as they are treated/cached in same was as artifacts and metadata, they are stored in local repository (on consume), and also, they can be explicitly resolved too by same calls as artifacts or metadata is resolved.

In short: checksums are NOT separate artifacts (even if they do behave like "separate artifacts" in some respect), but there are important differences. In general, you should NOT assume they are separate artifacts, you should leave their handling to basic connector: the role of basic connector among others, is that when it returns from a call with downloaded artifact, you KNOW the checksums are checked and are okay (according to session config like checksum policy and configured checksum algs), otherwise basic connector fails the call.

Copy link
Member

@cstamas cstamas Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And one more important point: if you DO provide checksums, basic connector will let them pass (and deploy in opaque manner) unless configured to use same checksum algorithm. Think ASF source bundle deploys, we use a plugin to create SHA512 for them, (while Resolver is using 'standard' checksum config of MD5 and SHA1). IF Resolver would be configured to use SHA512 as well (mvn3: -Daether.checksums.algorithms=... and mvn4: aether.layout.maven2.checksumAlgorithms), it would recalculate and replace checksum with its own on deploy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, important is the "kind" of checksum:

/**
* Enum denoting origin of checksum.
*
* @since 1.8.0
*/
enum ChecksumKind {
/**
* Remote external kind of checksum are retrieved from remote doing extra transport round-trip (usually by
* getting "file.jar.sha1" for corresponding "file.jar" file). This kind of checksum is part of layout, and
* was from beginning the "official" (and one and only) checksum used by resolver. If no external checksum
* present, {@link #onNoMoreChecksums()} method is invoked that (by default) fails retrieval.
*/
REMOTE_EXTERNAL,
/**
* Included checksums may be received from remote repository during the retrieval of the main file, for example
* from response headers in case of HTTP transport. They may be set with
* {@link org.eclipse.aether.spi.connector.transport.GetTask#setChecksum(String, String)}. If no included
* checksum present, {@link #REMOTE_EXTERNAL} is tried for.
*/
REMOTE_INCLUDED,
/**
* Provided checksums may be provided by {@link org.eclipse.aether.spi.checksums.ProvidedChecksumsSource}
* components, ahead of artifact retrieval. If no provided checksum present, {@link #REMOTE_INCLUDED} is
* tried for.
*/
PROVIDED
}

@kwin
Copy link
Member Author

kwin commented Sep 16, 2025

The "Maven way" of wanted topic "deploy API using PUT by default for HTTP" is true IF following conditions are true:

  • last connector in pipeline (mvn3 does not have it, but similar thing happens effectively, while mvn4 has dedicated API for this for programmatic construction) is basic connector
  • transport being used is some of HTTP implementations (apache, jdk or jetty) -- usually transport selection happens based 0n RemoteRepository#getProtocol() (but as always, there are exceptions)

In that case, one can say that "deploy" call maps to HTTP PUT method for each artifact and metadata.

What exactly do you want me to change/add to the doc?

@cstamas
Copy link
Member

cstamas commented Sep 16, 2025

Maybe just emphasize that "basic connector + HTTP transport" is the "most common way users are using Maven" (given Central is HTTP)? But, that is exactly NOT the typical how they deploy 😄

Unsure, what we want really to document here... as today, NOTHING aside of MRMs (that provide "internal" or "private" repositories, and usually proxies as well) support the "basic Maven deploy" (HTTP PUT artifact to remote repo) use case.

@kwin
Copy link
Member Author

kwin commented Sep 16, 2025

Unsure, what we want really to document here.

The way deploy is implemented by standard resolver services, obviously all those standard services can be overidden/extended in which case the picture may change.

as today, NOTHING aside of MRMs (that provide "internal" or "private" repositories, and usually proxies as well) support the "basic Maven deploy" (HTTP PUT artifact to remote repo) use case.

That is impossible to understand without this piece of information.

@cstamas
Copy link
Member

cstamas commented Sep 16, 2025

Just for ref, the Slack discussion as well:

So, I don't know can we go with it so simple, as for example, new mvn4 feature is this (visible with -X):

[DEBUG] Final pipeline: offline( rrf( basic( apache-snapshots-b6ad1b6b4141cf7b4e128785f79cbc45945d1ec4 (https://repository.apache.org/content/groups/snapshots, default, snapshots) ) ) )

Maven 4 now "pipeline" connectors, and this is final assembled pipeline in resolver 2:

offline( rrf( basic( target-usually remote repo ) ) )

Roles:

  • offline, if repo offline, "shortcuts" and refuse request
  • rrf, based (and if present) RRF rules, bounce/refuse requests
  • basic, is our "basic" transport, handles transport (Transport) and checksums (corruption protection)

Transport is implementing actual transport like HTTP, FTP, S3 etc. Also, we plan to add new connectors in pipeline, like sigcheck().

What this doco describe is true ONLY if basic connector is used (it implements the well known "roundtrip" maven repo, which focuses on immediate availability), but one could implement other connectors, like for example P2 is (gets stuff from P2 repo), or OBR and those formats are wildly different (btw, the connector/transport separation happened quite late, around maven 3.3.? As before connector+transport was one). For example, Njord is another connector as well (not transport, it in fact reuses file transport from resolver). Mimir is another connector, that implements read-through cache around basic.

Resolver is layered on purpose, and at the same time due this is not quite trivial to explain how it works.

Also, important distinction about "abstraction levels": connectors deals with Artifacts, while transport only about URIs. Transport is blind for "which artifact is this URI for"-like questions.

@cstamas
Copy link
Member

cstamas commented Sep 19, 2025

@kwin is this good to go into 2.0.12? If so, pls merge

@kwin
Copy link
Member Author

kwin commented Sep 19, 2025

Good as a starting point, I would say. Can be extended later on.

@kwin kwin merged commit 10079fa into apache:master Sep 19, 2025
8 checks passed
@kwin kwin deleted the feature/doc-deployment branch September 19, 2025 14:52
@github-actions
Copy link

@kwin Please assign appropriate label to PR according to the type of change.

@github-actions
Copy link

@kwin The PR can't be associated to a milestone, because there are multiple open milestones. Please add the text "branch: master" to the description to the milestone where this PR belongs to.

@kwin kwin added the documentation Improvements or additions to documentation label Sep 19, 2025
@kwin kwin added this to the 2.0.12 milestone Sep 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Document deploy API using PUT by default for HTTP transporters

2 participants