Open cburroughs opened 7 years ago
Having been on the implementing side for years, I would assume that anything that is public has an assumption of stability from an API contract standpoint. However, if you are incrementing minor versions, there is an expectation that the behavior may subtly change. With major version changes, the expectation is that some portion of the API will change, but not like 80%. One should be able to catch major version incompatibilities via compilation errors.
I would assume that anything that is public has an assumption of stability from an API contract standpoint
As a consumer of libraries that is my expectation as well. If the class is public then I can use it. I'll even extend java.lang.String
if I want to!
But as library developer, I would not want people to depend on com.joyent.manta.util.ConcurrentWeakIdentityHashMap
or com.joyent.manta.client.multipart.EncryptionState
.
https://docs.google.com/spreadsheets/d/1lly891zfckkYJfV6nfbBvC2flFsUu9Nya2bqF7F07zw/edit#
I went class by class and took a stab at what this might look like. I think my largest take away was just how broad the api surface area is.
(I think I now lean slightly towards having an @Internal
and letting public classes just be public like anyone would assume by default.)
Is the primary issue here that there are classes which should be package-private but need to be public to work across package boundaries?
An annotation for such classes might be valuable but I'd be hesitant to add annotations to every class that reaffirming that the class is public (and doing so indefinitely for every new class) without a clear benefit.
Is the primary issue here that there are classes which should be package-private but need to be public to work across package boundaries?
Yes I think that's a good way to put it. I at least have the habit of typing public
by default, so it is also possible that some of those "Internal" classes could be package-private.
From the CHANGELOG "this project aims to adhere to Semantic Versioning". However, that leaves open the questions of what exactly the public api is. Is it all classes that happened to be
public
? All classes exposed viaMantaClient
? Everything a "reasonable user" would use? We will also sometimes haphazardly have documentation that say a whole module (ie benchmarks) is not a stable public contract.This has come up with reviews where we have reasonable through how each class is exposed. That easy to mess up and unfun to repeat on each review. As this library is used more it becomes harder to make the kind of sweeping changes we did in
3.0.0
, so we need to create space for organic growth.In
java-http-signature
we have deprecated a significant number of methods, but not yet had a release that removed them.java-manta
is significantly larger with (as of this writing) 131 non-test classes in the primary module.Some related approaches:
@Beta
)Proposal:
@Public
annotation to the classes that form the public consumed API of the application. For example,MantaClient
and exceptions. I am unsure of the merits of also having an@Internal
annotation, and thus mandating that every class have an annotation. I think I lean slightly towards having both so it is harder for developers to make a mistake.@Beta
it (or something like that).@VisibleForTesting
or similar.NOTE:
@Stable
will likely be an (internal?) jdk9 annotation, so that might not be the best word choice.