-
Notifications
You must be signed in to change notification settings - Fork 23
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
Introduce annotations to further restrict API usage #9
Comments
I like this idea. I can imagine some build tool plugins that would validate these restrictions. Not sure though whether it should be the same plugin as the one proposed in here or a new one. |
|
Most of these are somehow similiar to Even though you're right and it is similiar, I wouldn't say that this is breaking DRY rule. |
I would say they are literally exactly the same thing. |
That's not correct. The If you feel that the documentation for the status does not adequately explain, then please raise an issue to address that. Cheers |
@sbrannen I wouldn't agree. These are 2 different perspectives - Also:
isn't exactly true. If I expose an interface as public API and provide a public APIfor obtaining the implementation (which is internal), that implementation class is not a subject for Example: Spring Data repositories; let's forget for a moment that they are built in runtime and assume that they are "real" (not synthethic) classes. These implementations are purely |
From the JavaDoc of @NoReference:
In the Eclipse API's you will find classes that are public but not all of its methods are intended to be called by client code. E..g constructors or dispose()-methods are invoked by the framework so they must be public, but this doesn't mean clients are allowed to call them, so they a annotated with |
Yes. I only argued that |
Why would they be internal, if clients need to use them? /**
* Must not be used by any external code. Might be removed without prior
* notice.
*/
INTERNAL, If those classes would have constructors, I'd understand to make those INTERNAL, but the class itself most definitely isn't. |
Huh... I think that the word "used" is the source of misunderstanding here. From my perspective such repo implementations (as well as e.g. SOAP service implementations, etc) are purely internal and are not exposed in any way to client, as he'd use interface and wouldn't care what is that implementation. Removing of these classes would be seemless, as their replacement would be provided by API owners. In this interpretation On the other hand, I understand that this can be interpreted as "class that is only used only in internal works of the library". In this interpretation And to answer your question:
Because client is not using them explicitly, but rather via their interface. From his perspective they don't matter, but they are still provided to him. |
Maybe the class has to be public due to technical reasons, but the API owner wants to make sure that nobody uses the implementation directly.
To me this obviously means to refer to something by name. Let's take the following sample interface and implementation. public interface Animal {
void move();
}
@API(status = INTERNAL)
public class Cat implements Animal {
// omitted for readability
} Clients should not reference But given the following factory method: public Animal create() {
return new Cat();
} Clients should be allowed to use that one to obtain an You can replace |
I totally agree and I would have provided almost identical example. I agree that |
Why not? Your source code is not referring to it, is it? |
The other problem is, we can only statically check source code to obey those rules. I don't believe anybody want's to enforce them at runtime using an agent or something. |
I guess it boils down to whether a reference is a reference by name in source code or a reference to an object at runtime. |
OK, so this is yet another cause for misunderstanding - does "to reference" used as above mean "reference by name in source code" or "reference in runtime". |
OK, now we're on the same page. All this time I was defending this annotation as non-breaking DRY, because I understood "referencing" as "referencing in runtime". Would we understand that as "reference by name", I agree that these two (annotation and API status) are totally equivalent. I would definitely find usage for this annotation, though and still think that this kind of contract can simplify a lot of things. |
It mentions classes, interfaces, annotations, enums, methods and fields all of which are constructs that you refer to by name. At runtime you have references to objects, which are not mentioned. Makes me believe we're talking about referencing by name. |
Yeah, I just looked into Eclipse javadocs and I've read:
So it probably means referencing by name. Now, we don't have to exactly copy Eclipse approach. Would you say that such annotation with "reference in runtime" semantics would be useful? |
It would be hard to keep track of when implementing something and even hard to enforce with tools. |
Does it make sense to add those Annotations (except |
My take on those:
|
|
Quoting myself:
Where I stated:
The good ones do. Just saying... |
Here's my real-world use case: I have a library whose methods return interfaces that the calling code is expected to reference by name, but should never implement in their own class or extend in their own interface. The implementation classes in my library are package protected. (Note that some of my interfaces even include default methods, so users might be even more inclined to misunderstand their purpose.)
|
Given that this has not seen much traction, how about splitting this into several issues? Alternatively, if @ChristianSchwarz is still interested, he could create a PR that includes the first few annotations where there was at least rough consensus. I imagine that having something concrete to look at and review could help with the discussion. |
Overview
For Frameworks and libraries it is quite common to provide interfaces and classes. But not all interfaces are intended to be implemented by clients, or classes may not be intended to be instantiated. If you write plugins for Eclipse you can use the Eclipse API Annotations to express such restrictions (and the IDE supports them by generating violation errors).
It would be nice to have a
common-lib/apiguardian
that provides these so they may become standard.Example
Copied directly from Eclipse API Annotations:
The text was updated successfully, but these errors were encountered: