Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MNG-6869] New flag to verify Maven installation status #995

Open
wants to merge 44 commits into
base: master
Choose a base branch
from

Conversation

mthmulders
Copy link
Contributor

This pull request adds a few basic checks that users can run to see if they've installed Maven correctly. This includes:

  1. A check if the local Maven repository is usable.
  2. A check if Maven can connect to remote repositories configured in settings.xml.
  3. A check if Maven can resolve a pre-existing artifact (to be precise, org.apache.maven:apache-maven:3.8.6).

These checks honour settings.xml profile activation through <activeProfiles>. The artifact resolution check honours any configured mirrors.

The connection check is quite rudimentary, and only functions at the HTTP connection level. Since there is no guarantee that a repository will contain a particular artifact, there's not much more we can do.

The artifact resolution check is a bit more thorough: it checks if there is any way in which Maven can resolve itself. It does so by temporarily using a "dummy" local repository. This is necessary to prevent a "false positive", where the artifact may have existed before.

We have not added unit tests or integration tests (yet). At some level, they may be useful, but we expect a full integration test to be a significant amount of work that would not provide a lot of value. We're curious to hear your opinions about that trade-off.


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

  • Make sure there is a JIRA issue filed
    for the change (usually before you start working on it). Trivial changes like typos do not
    require a JIRA issue. Your pull request should address just this issue, without
    pulling in other changes.
    --> MNG-6869
  • Each commit in the pull request should have a meaningful subject line and body.
  • Format the pull request title like [MNG-XXX] SUMMARY,
    where you replace MNG-XXX and SUMMARY with the appropriate JIRA issue.
  • Also format the first line of the commit message like [MNG-XXX] SUMMARY.
    Best practice is to use the JIRA issue title in both the pull request title and in the first line of the commit message.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Run mvn clean verify to make sure basic checks pass. A more thorough check will
    be performed on your pull request automatically.
  • You have run the Core IT successfully.

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.

@rmannibucau
Copy link
Contributor

Isnt it something a plugin would be a better location? Can need some basic downloads but would enable to do more checks on the project, better configure the dummy artifact - 3.8.6 or maven cant be hardcoded in case of central "mirroring", it can be forbidden intentionally.
It would also enable to maje checks grow, in particular with coming multilocal repo feature for ex.

return issues;
}

private List<String> verifyArtifactResolution(final MavenExecutionRequest mavenExecutionRequest) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is 1 step too much. Is this the only way to verify if a remote repository is accessible? If you need to use an explicit file instead of a directory, is it possible to use http HEAD ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

[...] 1 step too much [...]

Just to verify: are you referring to the fact that this code actually downloads a file (e.g., it could've been an HTTP HEAD request), or to the fact that the --status verifies if artifact resolution works?

In the case of the former: is a remote repository required to support an HTTP HEAD request? Could we rely on the fact that if HTTP HEAD is OK, HTTP GET will be OK, too?

Copy link
Contributor

Choose a reason for hiding this comment

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

It depends on what you define as "artifact resolution works". I'm not interested if the implementation is correct. I wish there's a way to only confirm that the connection works. It is about returning questions on StackOverflow that say Maven can't download things, but it is just that it cannot reach a repository. Possible rootcauses are missing proxies (or misconfigured) and misconfigured mirrors. Maybe @michael-o or @cstamas can think of a low-level reliable way to conform this.

Copy link
Contributor

Choose a reason for hiding this comment

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

From my experience this is not testing a random artifact which works but more enabling the aether logs which help, ultimately logging the request to be able to replay it with curl to do the check. Rest is random tests which can easily be proven false positive/negative due to proxies (correct) configuration.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The goal of this code is not to explain what is wrong and how the user should fix it. I agree with @rmannibucau that the Aether logs are more suitable for that. What this code wants to do is tell the user they have a problem, without even building a project.

Ideally, in the case of the StackOverflow questions that @rfscholte refers to, we could say "please share the output of mvn --status". Their output might look like this for example:

[INFO] Local repository setup check completed
[INFO] Connection check for repository 'corporate-repo' at 'https://pkgs.dev.azure.com/big-corporate/project/_packaging/whatever-repository/maven/v1' completed
Downloading from corporate-repo: https://pkgs.dev.azure.com/big-corporate/project/_packaging/whatever-repository/maven/v1/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6.pom
Downloading from misconfigured-mirror: https://non-existing.example.com/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6.pom
[INFO] Artifact resolution check completed
[INFO]
[ERROR] The following issues where found
[ERROR] 1.  Connection to misconfigured-mirror [https://non-existing.example.com/maven2/] not possible. Cause: non-existing.example.com: nodename nor servname provided, or not known
[ERROR] 2.  Could not find artifact org.apache.maven:apache-maven:pom:3.8.6 in corporate-repo (https://pkgs.dev.azure.com/big-corporate/project/_packaging/whatever-repository/maven/v1)
[ERROR] 3.  Could not transfer artifact org.apache.maven:apache-maven:pom:3.8.6 from/to misconfigured-mirror (https://non-existing.example.com/maven2/): non-existing.example.com: nodename nor servname provided, or not known

Even though this doesn't tell the user the solution, it points them in a few directions where they could look. It's a lot more compact than the complete Aether logs - which the user could still inspect, in case this message doesn't point them in the right direction already.

@mthmulders
Copy link
Contributor Author

Isnt it something a plugin would be a better location?

The current approach does not need any additional download. I think that's a good thing, as we can now use it to also point the user at issues in their configuration that would prevent artifact resolution. If we moved this to a plugin, we'd need artifact resolution to actually work...

Can need some basic downloads but would enable to do more checks on the project, better configure the dummy artifact - 3.8.6 or maven cant be hardcoded in case of central "mirroring", it can be forbidden intentionally.

I'm open to suggestions for another publicly available artifact. But in order to "prove" that artifact resolution works, we need something that is publicly available - I think something that at the very least is hosted by Central, and maybe by mirrors.

It would also enable to maje checks grow, in particular with coming multilocal repo feature for ex.

More thorough checks could reside in a plugin, but as pointed out before, we can't rely on resolution to work until we've checked that it works. So agreed, additional checks could live in a plugin, but I'm convinced that we'll need a few basic checks (among them artifact resolution and local repository setup) to live in Core.

@rmannibucau
Copy link
Contributor

I'm open to suggestions for another publicly available artifact. But in order to "prove" that artifact resolution works, we need something that is publicly available - I think something that at the very least is hosted by Central, and maybe by mirrors.

Point is none can be hardcoded, cause we dont know companies mirrors.
This is why it fits a plugin better IMO (wouldnt be great to have that in maven imo).

If you dont like the plugin, what about doing a mvn-install-checker project or extension which can grow and be downloaded at need.
Thing is this code requires config and ultimately shouldnt be a command but more explicit error messages when it fails IMHO.
Current flavor looks like not scaling well in time/hard to maintain in a relevant manner and is already biased due to profiles so a checker or plugin looks iso without the pitfall to impact core directly when you ll need to check proxy certs, proxy protocol, proxy passwords, sftp cert for deployment, properties typos in settings etc....(this is where this command/plugin/helper will lead if adopted).

@michael-o
Copy link
Member

Why not move it into a module within Maven Core which could be no-op of this default code. It could be easily exchanged?!

@rmannibucau
Copy link
Contributor

@michael-o or just enhance the CLI with a small SPI to enable to add custom command with extensions so this does not need a noop at all and is purely optional and in a dedicated module which can get a real configuration and enhancements later?

@mthmulders
Copy link
Contributor Author

Personally, I don't see much value in moving the code to a new module. If I understand correctly, we'd be moving this code to a different module inside the same Git repository, only to introduce some complexity in maven-embedder to load that exact same code. Also, this PR doesn't pull in new dependencies to maven-embedder, which we could have avoided by moving the code elsewhere, so I really fail to see the benefits of such a refactoring.

@mthmulders mthmulders force-pushed the mng-6869-new-flag-to-verify-maven-status branch from 45ba62e to 853819c Compare February 23, 2023 13:40
@rmannibucau
Copy link
Contributor

so I really fail to see the benefits of such a refactoring

  1. not deliver it by default
  2. not add specific options by default
  3. not make it grow to actually validate the installation completely and properly (if it becomes a feature the impl must be way more complex)

@mthmulders
Copy link
Contributor Author

mthmulders commented Feb 23, 2023

  1. not deliver it by default

That would completely defy the utility and value of this feature. I do want a clean Maven installation to be able to do a few basic checks. That is exactly the idea as laid out in MNG-6869, if you ask me.

Anything that requires a separate download (a plugin, or a helper script, or extension, or ....) and we do not ship with Apache Maven itself is completely opposite to the original idea, and would therefore be a -1 from me.

  1. not add specific options by default

I'm sorry, I don't understand what you mean here.

  1. not make it grow to actually validate the installation completely and properly (if it becomes a feature the impl must be way more complex)

If it were to become much bigger, we could always move it out later. As long as we can ship it with Apache Maven by default (see point 1).

Edit: I am aware of ${maven.home}/lib/ext/, but as far as I can see, this is only used for 3rd-party libraries - not for stuff that we maintain ourselves.

@@ -30,11 +31,11 @@
* A wrapper class around a maven resolver artifact.
*/
public class DefaultArtifactCoordinate implements ArtifactCoordinate {
private final @Nonnull AbstractSession session;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this change be removed from this PR ? It's completely unrelated.
Also, if we do change that, other classes such as DefaultArtifact and maybe others use the same mechanism and should be changed at the same time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure! I've just pushed a commit to undo this part.

@michael-o michael-o removed their request for review March 8, 2023 22:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants