-
-
Notifications
You must be signed in to change notification settings - Fork 114
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
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
Support Maven groupId relocation #801
Comments
This seems like a great feature. I've looked at this before and am not sure which tools and repos currently support it, I've never seen it in the wild. I assume Maven does support it though? |
I would assume so. Since Clojure CLI does its own resolution it may need patching though. Don't know about leiningen or other aether based tools. I'll try to do some testing. |
https://clojure.atlassian.net/browse/TDEPS-8 this is a planned feature for tdeps. |
I didn't know relocation was a maven feature, thanks for bringing it up! Given that not all build tools support relocation and the effort involved, I don't think we should be moving projects fully on Clojars. I do think relocation can be useful as a hint for tooling that supports it. Given a project
Then any tooling that doesn't support relocation can still use I think the real value of relocation here is for tooling that detects stale dependencies like antq or lein-ancient. They could be updated to follow relocations to find the new name. We could also pull the relocation info from the pom on Clojars, and link to the new name on the jar and search results pages. How does that sound? |
That's a reported gap, not a planned feature. :) This is a rarely used feature of Maven. If it becomes more common, then I would need to move its importance up for support. I do have a good idea of where and how to support this. In any case, will follow here. |
One real danger here is ending up with two copies of the same library on the classpath, under different names. That's one of those "I've lost 3 days here and can't explain why the program works 50% of the time" problems. Maybe com.foo/bar could depend on a version of foo/bar that has nothing in it? But that's reliant on TDEPS behaviour of picking the highest version, Lein/Mvn works differently so it wouldn't work for that case. If you change the namespace in the artifact move, then this isn't a problem. |
I'd suggest tools.deps follow Clojars' lead. If Clojars supports relocation, it'll likely become relatively common among Clojure libraries even if it remains rarely used in the larger Java ecosystem. |
Thanks @tobias for the proposal.
I agree with that, I don't think it's Clojars' job to actually "move" projects, as a maintainer I only want the possibility to point an artifact to a new name, after I deployed it to that new name. The minimum that is needed from Clojars' side for this to work is being able to deploy a pom without the jar. I understand that probably sounds much easier than it really is, I'm assuming both Clojars internals and UI assume there is always a jar to work with. I also see the point of keeping certain checks in place, like only supporting pom-only deploys if there is a relocation, and the relocation seems valid. But maybe this would be a comparatively small change. The next level would be some UI indicating the artifact has moved, this is how Maven does it: (example) Finally you could consider some smarts to help developers, like being able to indicate via the UI that an artifact will be deployed to a different groupId going forward, and have Clojars generate the relocation pom upon deploy. Maybe nice to have but something that could just as well be dealt with by deployment tooling.
This does seem to be what for instance hibernate-validator is doing. They continue to deploy all artifacts twice, but also including a relocation stanza. Others like Pushing it twice does mean maximal compatibility, but at what cost? As the hibernate docs point out this can cause issues.
I can see it happen quite easily that through transitive dependencies you end up with two artifacts on the classpath with conflicting version. This is what @SevereOverfl0w also pointed out. I think in this case I would prefer for my tools to fail with an error message, than to continue with a possibly inconsistent classpath. Relocation seems to work fine in Leiningen, but it confuses My preferred outcome would be for Clojars to gain at least the minimal support of allowing pushing a relocation pom, and tools.deps to learn to deal with that. I think we can also allocate some @GaiwanTeam time to help make those things happen, provided someone can provide some initial pointers and be available for questions. |
Thanks @plexus for digging in to this a bit more and testing with
This should be a straightforward change - I think this requirement is based on assumptions from the early days of Clojars. Regarding having the same classes/namespaces in the dependency tree: I had not considered that, and agree that that could be a real problem, especially with transitive dependencies. But I think I have an idea that could avoid that:
Concerns about this approach:
I think the concrete work here is:
How does that sound? Any concerns with that approach? As outlined, it's not a lot of work, and I should be able to do it fairly quickly. |
I did a bit more testing by just inserting some dummy poms/jars in
Base case
Leiningen: works as expected. tools.deps: Adding an empty jarCreated an empty jar (i.e. a zip file with nothing in it), and put that in leiningen: ignores the empty jar, only puts tools.deps: will start now, but only with Adding the dependencyIn the Here is gets interesting: the behavior is exactly the same as with the previous case. Both lein and tools.deps ignore the dependencies when there is a relocation stanza. Which is not what I expected, I assumed since tools.deps ignores the relocation stanza it would just follow the dependencies, but it seems that's not the case, so adding both is not a solution for Clojure CLI compat. Maybe @puredanger has an idea of why it's like that, even though tools.deps doesn't honor the relocation stanza, it seems to still shadow the dependencies. ConclusionI like the idea of adding the dependency on top of the relocation for maximal compatibility, although at least for the most common tools it doesn't seem to make a difference. The rest of the plan all sounds good. The final pom: <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>com.foo</groupId>
<artifactId>bar</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<distributionManagement>
<relocation>
<groupId>com.foo</groupId>
</relocation>
</distributionManagement>
</project> |
I guess I outlined this in a slack thread yesterday but didn't put it here, but this is what I would expect. Note that tools.deps does not look at the pom, it uses the Maven APIs. There are two calls into Maven:
|
Just letting you know that I'm also interested in this feature. A group relocation of one of my libs caused several issues because of two versions of the same lib on the classpath. |
I'm currently looking into this after chatting with @plexus separately. We've concluded that we'll start with updating deploy validation on clojars so we can upload poms w/o jars and at least have tools like I've played around with clojars-web and I can say that simply omitting However, that's probably easing the validation too much. We need stricter validation. As @tobias has suggested above:
Sounds like a good idea. Also, would it make sense to:
I'm happy to open a PR easing the validation for having a jar so long as the above requirements (some or all) are met. Does this make sense? |
Given the tooling issues with relocations based on @plexus' research, what if the recommended approach was to not use a relocation stanza, but instead:
That won't prevent We could also support a format for the description field that could be parsed to point to the new name (example: Do folks see issues with that approach? @kamilwaheed I think your work is a great start!
I think this is enough, I don't think we need to replace it with any other validation. Having a pom-only release is perfectly fine in other maven-based systems, and they are useful beyond this case (for example, for umbrella projects like https://clojars.org/ring/ring or https://clojars.org/org.immutant/immutant, where the project itself provides no code, just dependencies). I think we have the jar requirement just for historical reasons from Clojars' early days, and I'm fine with getting rid of it. |
I'm looking at some more examples, while many indeed use a pom-only approach, I'm also seeing several that upload a pom + a jar, with the jar only containing the Reading the maven relocation docs again I did come across this part, which I think I did not fully appreciate before:
So indeed they do recommend overwriting old poms, which makes me queasy, I'm not sure at all that Clojars should allow this. The best I can imagine is a limited feature where you can mark a library within clojars as being relocated, and clojars will generate the minimal relocation pom if a pom for an older version is requested. But that does seem a lot more complex. And old poms could still be cached locally. If we can't do something like that to ensure that for every version there's a relocation stanza, then I think there's not a lot of benefit to using relocation over @tobias's proposal of uploading single-dependency libraries at the old coords that pull in the new version. And that would mean existing tooling doesn't need adjusting. Ideally I'd like tooling like Antq or Depot to also switch over to the new group-id when upgrading dependencies, but as long as we keep releasing both old and new names (with one being an "empty" jar + dependency to the new one), then it shouldn't cause many issues that they don't. It would be good if we could come up with a way in the pom to still signal the relocation, in case tools do want to handle the rename. It also would be good if we could have Clojars show a big warning box on the old version pointing to the new one. It's not going to be a perfect solution, there will be user confusion and errors during the transition, but I think this does give us something we can start doing that is an improvement over what we're currently doing. In that case I think next steps would be
Or we pursue full relocation handling
|
If we did have Clojars rewrite POMs, we would have to do it for all versions at the time the relocation was specified, since artifacts served via the repo don't pass through the Clojars app; they are served via Fastly & S3. And you are correct - we have to worry about local caches, as well as the Fastly cache (which we can purge) and any mirrors (which we can't force to update). We also can't rewrite POMs for any GPG-signed releases.
I wish we had other alternatives (for example, I wish POMs supported arbitrary properties that we could use for this). But, as you say, (ab)using the description field for this now doesn't prevent a better solution in the future. We could parse the description field then note the relocation:
If we come up with a standard for the description field, Antq or Depot could follow that. We could package up relocation detection into a small lib for them to use. Or they could call the Clojars API to get that information.
Agreed, I'd like to see this implemented regardless.
I don't think we'll ever be able to implement full relocation support, since we can't rewrite older signed POMs, and I would prefer to keep Clojars immutable. That means we would only have partial relocation support for new versions, which doesn't solve the issue with classpath collisions. My personal recommendation would be for folks to not rename/relocate existing libraries, but I realize that I don't maintain any real libraries any longer, so don't feel the pain of having two group names. |
Correct me if I'm wrong here, but based on my testing (
This appears to me as a minor improvement over showing description as plain text that contains the relocation notification from the author. Do we then also enforce presence of the relocated coordinates in dependencies and match them again the relocation notification in description? |
If you look at the Maven docs for relocation they recommend physically moving all old artifacts to their new group-id, and then putting poms with relaction stanzas where the old artifacts used to be. Once that has happened you are expected to continue deploying a pom with the old group-id along with every new release, which contains a relocation stanza pointing to the new group-id. This last part deploy tools can handle, but the original move would be handled manually by a server admin. This is the only way that you will get correct resolution. If Maven pulls the pom for
We are trying to make the best of a situation we were forced into. Turns out that, in conclusion, "the best" is more or less what we already have, since there is no feasible technical solution that will not cause more issues for users. So yes, given that insight we will likely continue to release older projects under the |
I've also run into this problem. I've released some existing libraries under the new artifact group system, using a verified domain name, without considering how this affected the classpath and existing dependencies. I'm not certain what the best solution is to this, now that I have released libraries under the new group IDs. I can add a dependency from Is there any ideal solution to this, or is this an issue that's not meaningfully resolvable now that I've made the mistake of changing the group ID? |
I've also had this problem and regretted moving a lib (borkdude/sci -> org.babashka/sci) since this caused issues with both old and new versions on the classpath. I managed to track down most old usages via https://grep.app and made PRs for those, but it would definitely be nice to have this handled by clojars. Thanks! |
I tested out using Maven's hard dependency to see if this could be a possible solution, as one would imagine this would allow Unfortunately Maven's dependency resolution logic is completely insane and this doesn't work -- and even if it did, tools.deps uses a different (albeit saner) dependency resolution algorithm entirely that ignores the hard dependency syntax. It may be worth adding to the FAQ that moving artifact groups is generally a bad idea for packages hosted on Clojars. We have no mechanism that can handle this in a way that doesn't produce issues and no real way of resolving it after the package has been deployed. I'd feel like this was just me being dumb, but as plexus and borkdude also fell for this trap, it may not be as obvious as it seems in hindsight. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
With the new groupId policy we have started using
com.lambdaisland
instead oflambdaisland
. This is necessary for new artifacts, but we have also started doing this for existing libraries, to keep things consistent for our own internal tooling, and for our users going forward.Seems Maven actually has a feature to assist with such a scenario known as relocation. For instance, they give the example of
ant:ant
moving toorg.apache.ant:ant
. This involves serving up a pom.xml for the old artifact name that looks like this:I've tried uploading this with
But this results in a "no jar was uploaded" error (which is correct, I don't want to upload a jar)
Any thoughts on this would be appreciated as I'm also no Maven expert.
The text was updated successfully, but these errors were encountered: