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

Version 2.x Maven Central Identification #3170

Closed
benjchristensen opened this issue Aug 21, 2015 · 33 comments
Closed

Version 2.x Maven Central Identification #3170

benjchristensen opened this issue Aug 21, 2015 · 33 comments
Labels
Milestone

Comments

@benjchristensen
Copy link
Member

The intent of 2.x is to live side-by-side with 1.x. The package name (io.reactivex vs rx) is insufficient though, as the Maven Central artifactId needs to also be different otherwise both can't be imported. So instead of rxjava should it just be rxjava2 like this?

compile 'io.reactivex:rxjava2:2.x.y'
compile 'io.reactivex:rxjava:1.x.y'
@benjchristensen benjchristensen added this to the 2.0 milestone Aug 21, 2015
@benjchristensen
Copy link
Member Author

@rspieldenner Rob, I can't figure out what I need to change in the Gradle properties to change the name from rxjava to rxjava2 other than changing "project.name" which also changes everything else.

If I change project.name I end up with this:

/io/reactivex/rxjava2/2.0.0-DP1-SNAPSHOT/rxjava2-2.0.0-DP1-SNAPSHOT.jar

Is that what it should be? Or can it be this somehow with just 'rxjava' in the filename?

/io/reactivex/rxjava2/2.0.0-DP1-SNAPSHOT/rxjava-2.0.0-DP1-SNAPSHOT.jar

@benjchristensen
Copy link
Member Author

Seems that the artifactId is most commonly or always also the prefix for the filename. That suggests something like rxjava2 as above. Changing the complete name would also have the side-benefit of allowing two separate projects with different names in an IDE at the same time: rxjava and rxjava2.

However, I winder about the name rxjava2. If we need to make a 3.x but want to retain the same package names we would be stuck with the artifactId rxjava2 with version 3.x.

Is there a better name to represent this next version of rxjava?

io.reactivex – rxjava2 – rxjava2-2.0.0.jar
io.reactivex – rxjava2 – rxjava2-3.0.0.jar

io.reactivex – rxjava – rxjava-2.0.0.jar (I really wish this could work)

@rspieldenner
Copy link
Contributor

Why wouldn't this "io.reactivex – rxjava – rxjava-2.0.0.jar" work?

On Thu, Aug 20, 2015 at 9:33 PM, Ben Christensen notifications@github.com
wrote:

Seems that the artifactId is most commonly or always also the prefix for
the filename. That suggests something like rxjava2 as above. Changing the
complete name would also have the side-benefit of allowing two separate
projects with different names in an IDE at the same time: rxjava and
rxjava2.

However, I winder about the name rxjava2. If we need to make a 3.x but
want to retain the same package names we would be stuck with the artifactId
rxjava2 with version 3.x.

Is there a better name to represent this next version of rxjava?

io.reactivex – rxjava2 – rxjava2-2.0.0.jar
io.reactivex – rxjava2 – rxjava2-3.0.0.jar

io.reactivex – rxjava – rxjava-2.0.0.jar (I really wish this could work)


Reply to this email directly or view it on GitHub
#3170 (comment).

@akarnokd
Copy link
Member

A separate project makes things much easier; no need to switch back-and-forth between two branches. We could call it rsjava but I can see the confusion due to the one letter change. Having just rxjava-2.0.0 is also attractive. How about copying the current 1.x to a new project RxJava1 and have the 2.0 start in a cleared out RxJava project?

A separate project has also the benefit of not being intermixed with issues and PRs targeting the two versions.

@rspieldenner
Copy link
Contributor

I think changing the group and artifact name are some of the worst things
you can do. When you do that the 2 versions would no longer participate in
conflict resolution. So a gradle/maven/sbt etc. resolve could pull in 2
different versions of rxjava if you do anything besides moving to
io.reactivex:rxjava:2.x.x

On Fri, Aug 21, 2015 at 1:27 AM, David Karnok notifications@github.com
wrote:

A separate project makes things much easier; no need to switch
back-and-forth between two branches. We could call it rsjava but I can
see the confusion due to the one letter change. Having just rxjava-2.0.0
is also attractive. How about copying the current 1.x to a new project
RxJava1 and have the 2.0 start in a cleared out RxJava project?


Reply to this email directly or view it on GitHub
#3170 (comment).

@JakeWharton
Copy link
Contributor

That's the point of the change. They are able to operate next to each other.

On Fri, Aug 21, 2015, 10:04 AM Rob Spieldenner notifications@github.com
wrote:

I think changing the group and artifact name are some of the worst things
you can do. When you do that the 2 versions would no longer participate in
conflict resolution. So a gradle/maven/sbt etc. resolve could pull in 2
different versions of rxjava if you do anything besides moving to
io.reactivex:rxjava:2.x.x

On Fri, Aug 21, 2015 at 1:27 AM, David Karnok notifications@github.com
wrote:

A separate project makes things much easier; no need to switch
back-and-forth between two branches. We could call it rsjava but I can
see the confusion due to the one letter change. Having just rxjava-2.0.0
is also attractive. How about copying the current 1.x to a new project
RxJava1 and have the 2.0 start in a cleared out RxJava project?


Reply to this email directly or view it on GitHub
<#3170 (comment)
.


Reply to this email directly or view it on GitHub
#3170 (comment).

@benjchristensen
Copy link
Member Author

could pull in 2 different versions of rxjava

@rspieldenner As @JakeWharton said, that's the point. Otherwise as soon as v2 comes out it will break every application and basically be unusable without herculean efforts to upgrade everything from v1 to v2 - and that could only be possible if and once v2 accounts for every piece of functionality v1 had (not necessary a good thing to force upon v2).

RxJava is not a library that hides well, as it is intended to be exposed in the public APIs, and be used for composing libraries and systems together. Thus, a breaking change would mean coordinating all systems and libraries to all upgrade at the same time.

For example, at Netflix we would need to upgrade Hystrix for the entire company at the same time. Not going to happen. I consider this an even harder upgrade than Guava (which typically take many months of effort to upgrade) since Guava generally is not part of our public APIs, just internal implementation details.

An application could have the following dependencies:

io.reactivex:rxjava:rxjava-1.0.14
io.reactivex:rxjava:rxjava2-2.0.0

They would then use different types like this:

rx.Observable (from rxjava-1)
io.reactivex.Observable (from rxjava-2) (or whatever we call the package and class names)

@benjchristensen
Copy link
Member Author

@akarnokd I'm not a fan of splitting the projects. We split the community, lose the collaboration between 1.x and 2.x issues (which will be very common), will end up cross-posting things a lot, and would complicate the branding. The branding includes the Github URL, contributors, forks and stars. Those statistics (as superficial as it sounds) are meaningful. They represent the community around the project. Community, branding and marketing are honestly a massive part of a project like this. The code itself honestly is the easiest part.

@jkschneider
Copy link

@benjchristensen There is one alternative since you are also changing source package names which is to retain the same Maven coordinate but also provide a shim library that bridges 2.x functionality to the old package names. Effectively, anybody needing both 2.x and 1.x to coexist would just add an additional dependency on the shim. This is a little more in-your-face and encourages upgrades. Think of the SLF4J Log4J shim as a not-entirely-similar case.

@benjchristensen
Copy link
Member Author

@jkschneider can you give me an example of how that would work? That sounds intriguing.

@benjchristensen
Copy link
Member Author

I think I may understand. Is it as follows?

We could double publish RxJava v1 like this:

  • io.reactivex:rxjava:1.x.y
  • io.reactivex:rxjava1:1.x.y (or whatever name we want like rxjava-v1 or rxjava_1, etc)

Then we publish v2 as:

  • io.reactivex:rxjava:2.x.y

So if someone gets upgraded to v2 and it breaks their world, and they need both to live together, they would have dependencies like:

  • io.reactivex:rxjava1:1.x.y
  • io.reactivex:rxjava:2.x.y

So, instead of us changing artifactIds for new versions, we actually add one for the old version?

@jkschneider
Copy link

@benjchristensen That's right -- the main benefit is a natural bias toward upgrading, especially for first order dependents. Depending on how easy it is to bridge new concepts to old, it may also provide an easy way for you to deliver bugfixes to older uses of the API without working on two distinct core branches of rxjava itself.

Perhaps call it something like io.reactivex:rxjava-compat:2.x.y and have the compat library's version track the version of rxjava itself. After all, the compat shim and rxjava will be feature coupled.

@zsxwing
Copy link
Member

zsxwing commented Aug 22, 2015

@jkschneider I think it's possible that someone uses both a library A that depends on io.reactivex:rxjava:1.x.y, and a library B that depends on io.reactivex:rxjava:2.x.y. Then the user needs to fix the dependency tree manually, since maven/gradle only selects one version of io.reactivex:rxjava.

@simonbasle
Copy link
Contributor

@jkschneider @benjchristensen @zsxwing that could indeed be the case for instance if said user depends on the Couchbase SDK (which in turn depends on RxJava).

@jkschneider
Copy link

@simonbasle @zsxwing while conflict resolution would evict io.reactivex:rxjava:1.x.y, adding the shim would make any dependency that requires rxjava 1.x happy, just not with the exact same binary it had before.

@zsxwing
Copy link
Member

zsxwing commented Aug 25, 2015

@simonbasle @zsxwing while conflict resolution would evict io.reactivex:rxjava:1.x.y, adding the shim would make any dependency that requires rxjava 1.x happy, just not with the exact same binary it had before.

I see. However, my concern is that the user has to fix it manually (excluding incompatible dependency and adding new dependency). Sometimes, the dependency tree is very complicated and it's hard for the user to figure out how to fix it. E.g., I remember that I spent several hours on understanding the SLF4J Log4J shim things when I encountered the conflicts at the first time :(

@jkschneider
Copy link

@zsxwing That is a legitimate concern and the principle tradeoff.

@benjchristensen
Copy link
Member Author

Talked with @rspieldenner about this today to get some guidance. We can make RxJava v1 double-publish artifacts for us to solve this.

The way it would work is:

RxJava v2 only
compile 'io.reactivex:rxjava:2.x.y'
RxJava v1 only
compile 'io.reactivex:rxjava:1.x.y'
RxJava v1 and v2 together

If someone needs both, v2 would override v1 and transitive dependencies would break. They would then manually opt-in to having 'rxjava_v1' included and they'll end up with both jars.

compile 'io.reactivex:rxjava_v1:1.x.y'
compile 'io.reactivex:rxjava:2.x.y'
RxJava v2 and v3 together

Eventually (hopefully never or at least many years from now) if we need to do the same for v2/v3 we could add an artifact for v2 (and yet another set of package names for 3.x):

compile 'io.reactivex:rxjava_v2:2.x.y'
compile 'io.reactivex:rxjava:3.x.y'

The change from v1 to v2 is too significant for a thin shim. Virtually every single class in the entire project is going to be touched in the move from v1 to v2. Thus, we really do want to just provide all v1 byte code untouched with a different artifact so both can live side-by-side. We also intend on v1 living for a long time (at least while Android doesn't support Java 8), though hope that server-side projects will upgrade over a 12-18 month period from v1 to v2 so that most server environments would only need to be importing v2.

So, unless there is dispute with what is stated above, it's time to debate the artifactId.

I suggest rxjava_v1.

@simonbasle
Copy link
Contributor

👍 for this solution (great one)
👍 for the name rxjava_v1 (don't have a strong opinion on any other name anyway)

@zsxwing
Copy link
Member

zsxwing commented Aug 28, 2015

@benjchristensen 👍 for your proposal. This is just a tradeoff. Thanks for explaining why you made this choice.

@JakeWharton
Copy link
Contributor

As RxJava 2 has yet to be released, I would like to propose io.reactivex.rxjava2:rxjava as the Maven coordinates for the 2.0 major version release. The details on both group ID naming and artifact ID naming are encapsulated in my blog post.

Multiple comments from this issue are addressed in the post:

The package name (io.reactivex vs rx) is insufficient though, as the Maven Central artifactId needs to also be different otherwise both can't be imported.

Covered in the post.

Is there a better name to represent this next version of rxjava?

Covered in the post. Group ID changes is the simple way to break this apart.

They would then manually opt-in to having 'rxjava_v1' included and they'll end up with both jars.

and

Eventually (hopefully never or at least many years from now) if we need to do the same for v2/v3 we could add an artifact for v2 (and yet another set of package names for 3.x):

This solution plays to the always-upgrading nature of consumers and some libraries. While it represents a non-zero effort on consumer's part, the naive remain blissfully unaware and allow natural progression of these APIs to take place.

@benjchristensen
Copy link
Member Author

Jake, thanks for the followup on this. I'm good with accepting the artifact name you propose.

@akarnokd
Copy link
Member

👍 to be able to import them the same time.

@akarnokd
Copy link
Member

Jake's suggestion for io.reactivex.rxjava2:rxjava sounds reasonable for me. It also allows upgrading the neighboring libraries and have all of 2.x under the same groupId pattern (io.reactivex.rxjava2:rxjava-math).

Unfortunately, I'm not sure where this new group ID could be applied (hidden inside the nebula plugin?).

@artem-zinnatullin
Copy link
Contributor

@akarnokd yeah, looks like it's in nebula rxjava plugin, but you can override it inside RxJava's build.gradle, add group = 'io.reactivex.rxjava2'. When I run ./gradlew publishToMavenLocal it publishes it to overridden group.

@artem-zinnatullin
Copy link
Contributor

👍 for Jake's proposal about groupId change to io.reactivex.rxjava2.

@JakeWharton
Copy link
Contributor

Might be a good time to shed some nebula? RxAndroid got rid of all of them
and never looked back.

On Fri, Jun 17, 2016, 8:56 AM Artem Zinnatullin notifications@github.com
wrote:

👍 for Jake's proposal about groupId change to io.reactivex.rxjava2.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#3170 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AAEEEaOIeM0VW9cpfnKQF2mXdqCAMUCMks5qMpmTgaJpZM4FvoU-
.

@akarnokd
Copy link
Member

Sounds good, @JakeWharton . Was there something in RxAndroid regarding nebula that had to be replaced (such as travis-maven publish on release builds)?

@JakeWharton
Copy link
Contributor

Yes. The challenging part was retaining the part which does the release
builds. @dlew helped set it up, and while it's not pretty it doesn't feel
any less brittle than Nebula already was.

On Fri, Jun 17, 2016 at 11:39 AM David Karnok notifications@github.com
wrote:

Sounds good, @JakeWharton https://github.com/JakeWharton . Was there
something in RxAndroid regarding nebula that had to be replaced (such as
travis-maven publish on release builds)?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#3170 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AAEEEfz-uqq4aHQDfm0F_21qmHAN_Bq7ks5qMr-YgaJpZM4FvoU-
.

@akarnokd
Copy link
Member

Great. Not sure if we can actually test it before RC1 (release RC0 as is at the time of testing?).

@stevegury
Copy link
Member

👍 for the groupId change.
@akarnokd I can try to find someone from our tools team to help with the migration out of Nebula.

@akarnokd
Copy link
Member

@stevegury any help in this regard is appreciated, thanks!

@akarnokd
Copy link
Member

Changing the group ID while still using Nebula does work for the snapshot release: https://oss.jfrog.org/artifactory/libs-snapshot/io/reactivex/rxjava2/rxjava/

The discussion about removing the plugin continues in #4032.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants