Skip to content

cs fetch caches a POM with no artifact, and fails to download on subsequent runs with different repositories #2377

@chrisjrn

Description

@chrisjrn

The maven package javax.media:jai_core:1.1.3 exists in an incomplete state on repo1.maven.org/maven2, which is one of Coursier's default repositories.

To satisfy dependencies from org.osgeo, the package is hosted at https://repo.osgeo.org/repository/release. The JAR is available from there.

We've discovered that you can get Coursier into a state where it will permanently fail to download this artifact.

Symptoms

There are three separate problematic behaviours that Coursier is exhibiting here:

  1. If repo1.maven.org comes before repo.osgeo.org in Coursier's resolve order, Coursier will download the POM at repo1.maven.org, rather than trying the other configured repository to see if it possible to resolve there
  2. If --no-default is not specified, repo1.maven.org is always tested before user-supplied repositories, which leads to unexpected behaviour for an inexperienced user (re-ordering the repositories list will not do anything until --no-default is supplied, which will break other resolves)
  3. Coursier eagerly caches the first POM it finds for a given coordinate, regardless of whether a JAR can be fetched next to that POM, and regardless of which repositories are configured on subsequent runs. Consequently, once javax.media:jai_core:1.1.3 is attempted to be fetched from repo1.maven.org, subsequent Coursier runs will always fail to fetch the JAR, regardless of what repositories are fetched. The current work-around for this is to blow away the entire Coursier cache, which is undesirable

Expected behaviours

  1. Coursier should try all configured repositories until an artifact is downloaded. Downloading just the POM for that artifact is not sufficient to show success.
  2. Coursier should check user-supplied repositories before the default repositories
  3. Coursier should not cache this POM because it does not supply a usable artifact, and causes Coursier to actively get in the way of fixing these symptoms
  4. (BONUS) Coursier should cache each artifact according to the repository it was found at, so that if the repositories list ever changes (to get a different packaging of an artifact maybe?) it will download it more eagerly.

How to reproduce

  1. Work in a tmpdir: mkdir /tmp/coursier && cd /tmp/coursier

Delete the coursier download cache, to start with clean state. E.g., on MacOS: rm -rf ~/Library/Caches/Coursier/v1/.

Fetch the broken artifact from the bad repository:

$ cs fetch -r=https://repo1.maven.org/maven2 --no-default --json-output-file=coursier_report.json javax.media:jai_core:1.1.3

$ cat coursier_report.json | jq -M .dependencies[0].file
null

Try and refetch with the good repository:

$ rm -f coursier_report.json  # Just to be sure that isn't confusing us somehow
$ cs fetch -r=https://repo.osgeo.org/repository/release -r=https://repo1.maven.org/maven2 --no-default --json-output-file=coursier_report.json javax.media:jai_core:1.1.3

$ cat coursier_report.json | jq -M .dependencies[0].file
null

Delete the coursier cache again, as above.

Refetch with the good repository, as above:

$ rm -f coursier_report.json 
$ cs fetch -r=https://repo.osgeo.org/repository/release -r=https://repo1.maven.org/maven2 --no-default --json-output-file=coursier_report.json javax.media:jai_core:1.1.3

$ cat coursier_report.json | jq -M .dependencies[0].file
"/Users/benjyw/Library/Caches/Coursier/v1/https/repo.osgeo.org/repository/release/javax/media/jai_core/1.1.3/jai_core-1.1.3.jar"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions