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

Once guava-jre requires Java *9*, investigate merging the 2 "flavors" into a multi-release jar #5621

Closed
cpovirk opened this issue Jun 22, 2021 · 5 comments
Labels
P4 package=general type=other Miscellaneous activities not covered by other type= labels

Comments

@cpovirk
Copy link
Member

cpovirk commented Jun 22, 2021

Someday in the distant future, guava-jre will require Java 9.

(My assumption has usually been that we will skip requiring 9 and wait until we have enough reason to require some even higher version. If so, we can wait for that. But the issue I'm now filing will give us at least a small motivation to pull the trigger on Java 9 rather than wait. Then again, our hand is often forced by the people who depend on us, who may likewise by inclined to wait for a version higher than 9....)

When that happens, we could consider trying to eliminate the split between guava-android and guava-jre by putting both into a single multi-release jar. This would be workable only if:

  • Android tools reliably look at only the classes in the "root" section of the jar.
  • Non-Android tools reliably look at the classes under META-INF/versions/9.
  • Users can deal with the doubled jar size.
  • The spec for multi-release jars is evolved to eliminate the requirement that "Every version of the library should offer the same API." (For all I know, this may have happened already. But I suspect not.)
  • Probably various other things happen. But I'm already feeling that this is a pipe dream :)

[edit: I have had some trouble with multi-release jars, as discussed in jspecify/jspecify#245. If we're lucky, it will turn out that part of the problem is that I was doing something wrong. But it does sound like there may be legitimate tool limitations at this point. Maybe those will be fixed before we even investigate multi-release jars for Guava.]

@cpovirk cpovirk added type=other Miscellaneous activities not covered by other type= labels package=general P4 labels Jun 22, 2021
@shreelakshmijoshi
Copy link

Hi @cpovirk !
I am a new open source contributor and would like to know about this issue, could you help me understand the issue by providing some extra references ?

@cpovirk
Copy link
Member Author

cpovirk commented May 10, 2022

I'm going to close this, since the requirement that "Every version of the library should offer the same API" still exists—and is essentially "enforced," intentionally or not, by at least some tools. If something changes, we can reopen this.

@cpovirk
Copy link
Member Author

cpovirk commented May 23, 2024

If we get far enough with #6567, then the guava-jre and guava-android APIs someday might match after all. That might make this a possibility—again, subject to the caveats in my original post. [edit: But it also means that there's relatively little to be gained by undoing the split, since picking the wrong flavor has fewer ill effects (though not zero).]

One significant concern would be that we'd be committing to keep the APIs in sync again—or to re-split guava-jre and guava-android in the future. A re-split would likely end up more disruptive than just keeping the split all along :( I don't know how likely it is that we'd want to re-split, since I don't know what the future holds for library and language desugaring.

Another thing we'd have to think about, though, is whether the Gradle Module Metadata could be made to understand that the 2 flavors of Guava have been collapsed down to 1.

My guess is that we still won't do this. But I wanted to leave the notes while they were on my mind.

@cpovirk
Copy link
Member Author

cpovirk commented May 28, 2024

(I keep thinking "Oh, but what if we kept the APIs exactly the same but put @DoNotCall+@Deprecated on any that people shouldn't use from Android?" But then I keep remembering that that doesn't work because new javac versions will look at the guava-jre APIs even when targeting guava-android (barring --release 9, which is the wrong thing to do when targeting Android). We could in principle still attempt something roughly along those lines, but it would have to be a custom Error Prone checker (which helps only Error Prone users) that somehow determines whether we're targeting Android or not. Or we could maybe just add the APIs and hope for the best. That approach might work best if the APIs were separated out into distinct classes, like if we offered a Records or MoreGatherers class. Really, such separate classes might be something we could consider even if Guava keeps targeting Java 8. But I wouldn't be surprised if that turned out to confuse some build tools.)

@cpovirk
Copy link
Member Author

cpovirk commented Sep 30, 2024

(I also periodically think things like "If we had a multi-release jar, then we could refer to Record from the Java 14+ version." [edit: And here I'm speaking only about in implementations, not in API, since API has to match across versions.] However, while I am not totally sure which version Android would use at runtime, I'm confident that it won't use the Java 14+ version in exactly the circumstances that we want: It will pick (I assume) one or the other, without a way to know which version of Android the app will be run under. That means either that it will lack Record support when we might want it (even before we take into account that arbitrary versions might want it because of desugaring!) or it will attempt to run the Record-support code when it doesn't work. As a result, we'd end up needing to guard the checks no matter what. Maybe this will stick with me now that I've written google/gson#2744 (comment).)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P4 package=general type=other Miscellaneous activities not covered by other type= labels
Projects
None yet
Development

No branches or pull requests

2 participants