Interoperability with Ivy and Maven dependency resolvers #262
Comments
I had the same thought the other day, I think that'd be really handy indeed. Would you be willing to test this for me? |
So Maven repo docs fail to mention these:
|
The biggest problem would be that Ceylon modules don't have a group/artifact split. We can emulate one, by splitting on the last |
That's already what happens in the <?xml version="1.0" ?>
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ceylon.interop</groupId>
<artifactId>java</artifactId>
<version>1.2.2</version>
<name>ceylon.interop.java</name>
<dependencies>
<dependency>
<groupId>ceylon</groupId>
<artifactId>collection</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>
</project> |
Alternatively, we could add an annotation in mvn("ceylon", "interop.java")
module ceylon.interop.java 1.0.0 {
...
} |
Why can't the group and artifact be identical: the module name? |
That's a slippery slope right there -- adding Maven specific annotations to language module... Maybe have a And additionally, this would be used for mvn pom generation. Lacking An example: group("ceylon.sdk")
module ceylon.time 1.2.2 { ...} Would generate following POM file: <?xml version="1.0" ?>
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ceylon.sdk</groupId>
<artifactId>ceylon.time</artifactId>
<name>ceylon.time</name>
<version>1.2.2</version>
<dependencies>
...
</dependencies>
</project> |
Usually the groupid refers to the project. See http://central.sonatype.org/pages/choosing-your-coordinates.html
I think a better default would be:
This might be the best default, because then the artifact would have already the right name for resolution. |
Yes. I will try to create some kind of integration test for this. |
@vietj: what do you think we should do about group/artifact? |
Note that if we change the group/artifact mapping in Herd, we will also want to change it in the generated |
I think Herd should simply extract the |
That is indeed another option. Except that:
|
So it should be a mix of both, as we do when generating OSGI metadata in manifest: reuse information specified in the internal POM, and add any additional information that can be provided by Herd. |
Looks like a good compromise.
Technically, poms can also contain such data, so we could fill it from |
I can, that's why I said that it's a bit richer if I generate the |
Supports Does not support javadoc yet but I'm pretty sure the Java tools would not be able to make sense of ceylondoc anyway. |
Yeah, I think so too, which is why I asked @vietj about his opinion. |
having an annotation to specify a group id : can raise a problem if you want to deduce de GAV from the Ceylon module name because you don't have the information |
having a scheme with multiple group ids can make a problem later if you want to put the same deps on maven central because usually you owns a single group id |
at the same time, maven does not manage cyclic dependencies, so I don't see how you would publish ceylon cyclic dependencies in a maven repo. |
ATM @vietj has parts of the distrib published at http://mvnrepository.com/artifact/org.ceylon-lang under the Using |
Another option is to use a common groupId for every Ceylon module: |
why not use the same coordinates that already are in maven central? |
Tricky... seems like the only way to avoid trouble is to add a |
instead of a |
Yeah, a decision will severely affect Java-Ceylon-interaction in the long run. For what purpose is the pom.xml in the CAR generated by Ceylon in the first place? Maybe the best way to deal with it, is to not generate the pom.xml automatically and to ditch the Maven interoperability in Herd that I proposed here. All projects that want to be available in Maven would have to add an additional publishing process to their build that generates a pom file and uploads their CAR as JAR to Maven. To make this work you would have to publish Ceylon core stuff also to Maven. edit: Ah forget it. Then Ceylon projects that use Herd as repository would suffer, because when they use a Java library from Maven that uses a Ceylon library from Maven (which is also used directly by the project with Herd coordinate) CMR would not get that. |
Just for the record, the artifact id is as important as the group id. Both cannot be safely deduced from the Ceylon module name. They are simply two different things. The Ivy Maven interop works so well because Ivy has organization and module name as coordinates which is similar to Mavens coordinates (but also not the same). See http://ant.apache.org/ivy/history/latest-milestone/ivyfile.html / http://ant.apache.org/ivy/history/latest-milestone/ivyfile/info.html This got complicated very quickly :/ Should we add another issue that deals with Maven / Ceylon artifact coordinate interoperability in another project issue tracker? |
I think what everyone is forgetting here is that the person writing and compiling the module is not the person who wants to depend on the module using mvn. Therefore a system which depends on the module author (optionally) annotating the module at compile time is unlikely to work well in practice. |
Perhaps this has already been discussed in a previous comment, but we're talking about serving a Maven repo from Herd, so why not configure the group id/artifact id in Herd directly? This can be during the project claim, or during the project upload, with default values extracted from the module name. pros:
cons:
|
I don't know why not. I see two situations:
We should definitely not support some weird situation where a user of the module decides to publish it on Maven Central! |
@bjansen hmmm not a bad idea at all! Although honestly I don't like much the fact that 2 (or N, for each time the author decides to change the coordinates in the Herd) different versions of all CARs would exist. That would make checking CRCs a lot harder ("I have 2 sha1s here, one of them should probably check out") |
Do we really need two versions? We can rename the CAR to JAR and not modify the pom.xml inside, Maven will not use anyway (it will use the sibling pom). And I suppose the maven layout will reside in a completely different folder, right? |
Of course this does not solve the problem of uploading things to Maven central, because Maven coordinates won't be known locally. We could add a "publish to maven central" button in Herd, though. |
I think, that to have 2 different pom for one car is pretty mess. 2016-03-09 14:40 GMT+01:00 Bastien Jansen notifications@github.com:
|
Can someone please answer this?
|
If that's true then okay. It might be weird to see that Ceylon's metamodel would return different names than the one you asked for but we could probably live with that. |
As far as I know because that's what many (all?) Maven artifacts do too, so I guess it's used somewhere. But I think @FroMage will know better |
Right, that's exactly what I was getting at in my last comment. Stef has already decided to generate a pom using Herd itself (rather than just extracting it from the car). So it doesn't seem unreasonable to have Herd handle this stuff as well. |
That's possible, but it does not make it easier for people to upload to Maven Central without Herd in the equation. |
It's not really clear to me how and when and why the "upload to Maven Central" requirement snuck into this particular issue. Originally we were talking about letting Herd act as a mvn repo. |
Maybe it helps to list use cases and possible problems:
Currently, I can add the Herd repository as Maven repository in Gradle. This works fine for now.
Currently, I can add both, a Maven repository and the Herd repository, to my Gradle project. This works fine for now.
Currently, I can add both, a Maven repository and the Herd repository, to my Gradle project. But the There are similar use cases for Ceylon developers where different names should result in multiple downloads and imports of the same library (even if Maven fake mode of Herd is ditched, at least when eclipse-archived/ceylon#5968 is solved). One can always resolve these issues manually, but it makes Ceylon Herd look like an offender. The only solution to this is to somehow link dependencies on Maven Central with dependencies on Herd (when they are uploaded to both). When maintaining this link is manual work, many people will not do it, which in turn results in ugly problems mentioned in 3). One solution would be to allow Herd to push my library to Maven Central or another popular Maven repository. This way the link will be automatically maintained by Herd. This seems also to be what JCenter makes possible for its users:
BTW similar issues might occur when working on NPM interoperability, but I am not sure... |
Now, there's been so much discussion here hat I might just have skimmed over some relevant bits. If so, excuse me if I rehash something that has already been decided. About my suggestion for setting Maven Then we should have some way of overriding these defaults. First on the command line and then for perpetuating the chosen setting in a configuration file somewhere ( The defaultsThe most sensible default behavior I can come up with is to have group id and artifact id to be same as module id. I know that this runs counter to how Ceylon modules have been published to maven so far, but if this is configurable later, I still think that this is the most sensible default. Command lineOne should be able to configure maven ceylon compile --maven-groupId=ceylon-lang The above command should produce set of modules whose ceylon compile --maven-groupid=ceylon-lang --maven-artifactid=interop-java ceylon.interop-java would produce ceylon module with maven coordinates 'ceylon-lang:interop-java:1.2.2' Trying to call the latter command line with multiple modules (either explicitly on command line, or implicitly when calling without module name in a project with multiple modules) should be considered an error. As an additional consideration, we could add support for some simplified regular expression syntax for deriving groupId and artifactId from the module name. Something along these lines: ceylon compile --maven-groupid=ceylon-lang --maven-artifactId="ceylon.(**)|$1|r/./-" That would take everything after "ceylon." in the module name and use it as Maven artifactId ...
Project configurationWhatever we allow on command line we should be able to configure in I guess the simplest configuration might be like this:
|
this seems to be a great debate, however I haven't see anything about cyclic dependencies. how are cyclic module dependencies going to be exposed by Herd to Maven ? |
I guess we have several layers of maven/ivy interop issues under discussion here ... maybe we should split those discussions off to their own separate issues? |
This enhancement would allow to create a flat classpath of Ceylon CARs for Java projects using Maven, Ivy or Gradle. This is possible by offering appropriate repository "facades" through the Herd repository server.
Maven repository structure
Maven expects the following layout (see Maven Repository Layout - Final) for primary artifacts:
/$groupId[0]/../${groupId[n]/$artifactId/$version/$artifactId-$version.$extension
and for secondary artifacts:
/$groupId[0]/../$groupId[n]/$artifactId/$version/$artifactId-$version-$classifier.$extension
Ivy repository structure
Ivy is more flexible and allows to specify custom patterns for artifact resolution (see Ivy Documentation - Main Concepts). The default patten that is used by Gradle is the following (see Gradle DSL Reference - IvyArtifactRepository):
Artifacts:
$baseUri/[organisation]/[module]/[revision]/[type]s/[artifact](.[ext])
Ivy module descriptors:
$baseUri/[organisation]/[module]/[revision]/[type]s/[artifact](.[ext])
Meta information
To resolve transitive dependencies both repository types require meta information. Maven uses
pom.xml
s. Ivy usesivy.xml
s, but can also processpom.xml
s. Those files must be accessible via HTTP requests.Meta information augmentation
When the repository server responds to a "foreign" meta data request for a Ceylon module, it should automatically add all implicit dependencies of the Ceylon language to the response. For interoperability these Ceylon language modules should be published to the Herd repository so that Java projects that depend on a Ceylon library do not have to provide them by themselves.
Artifact aliases
For interoperability it would be very useful when CAR files are also available under the same name but with JAR file extension when accessed through a facade.
Many IDEs automatically link source and javadoc JARs to the downloaded artifacts by searching in the module cache for files like
$artifactId-$version-$classifier-sources.$extension
(IDE dependent see NetBeans DependencyNode). Ceylon source artifacts should be made available in a way that this resolution works out of the box. This means that the artifacts are made available under another name than they are normally accessible in Herd.The text was updated successfully, but these errors were encountered: