Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/ApiRemovalProcess.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ See [Eclipse Project Deprecation Policy](Eclipse_API_Central_Deprecation_Policy.

For new API planned removals use:

* For Java code use the @Deprecated annotation (see below for an example) and optional additional Javadoc.
* For Java code use the @Deprecated annotation (see below for an example) and optional additional Javadoc.
An extra entry in the removal document from [removal document](https://help.eclipse.org/latest/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fporting%2Fremovals.html) is not necessary anymore
* If appropriate the @noextend @noreference and @noinstantiate Javadoc annotation should be added to code

Expand All @@ -15,15 +15,15 @@ Javadoc generates a detailed [list of forRemoval](https://help.eclipse.org/lates

Example of a deprecation comment:

```
```java
* XXX
* @noreference
* @noextend
* @noimplement
* @deprecated This XXX (class/method/field) will be removed in a future release. Use XXX instead.
*/
@Deprecated(forRemoval = true, since = "2025-06")
```
```
* The PMC may decide to back out of an API removal
* In general, removing a deprecated API does NOT cause the increase of the major version segment.

Expand Down
7 changes: 4 additions & 3 deletions docs/Coding_Conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ Coding Conventions

Oracle has established coding standards that are generally considered reasonable, as evidenced by their widespread adoption by other Java-based development efforts. One of the goals is to make the Eclipse Platform blend in with the Java platform. This goal is furthered by our following suit.

[Oracle's Code Conventions for the Java Programming Language](https://www.oracle.com/java/technologies/javase/codeconventions-contents.html) covers filenames, file organization, indentation, comments, declarations, statements, white space, naming conventions, and programming practices.
All code written for the Eclipse Platform should follow these conventions except as noted below.
[Oracle's Code Conventions for the Java Programming Language](https://www.oracle.com/java/technologies/javase/codeconventions-contents.html) covers filenames, file organization, indentation, comments, declarations, statements, white space, naming conventions, and programming practices.
All code written for the Eclipse Platform should follow these conventions except as noted below.
We deviate only in places where our needs differ from Oracle's; when we do deviate, we explain why. (The section numbers shown below are Oracle's.)

* Section 3.1.1 Beginning Comments
Expand All @@ -21,10 +21,11 @@ The Eclipse project has more specific naming conventions. See Eclipse Project [N

Modifiers should be ordered as specified in the JLS and summarized in [AST#newModifiers(int)](http://help.eclipse.org/neon/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/AST.html#newModifiers-int-):

```java
public protected private
abstract default static final
synchronized native strictfp transient volatile
```

For Javadoc conventions, see Oracle's [How to Write Doc Comments for the Javadoc Tool](https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html) and [Eclipse/API_Central](API_Central.md).

Expand Down
13 changes: 7 additions & 6 deletions docs/Eclipse_API_Central_Deprecation_Policy.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
Eclipse/API Central/Deprecation Policy
======================================

This page contains Eclipse Project guidelines on API deprecation.
This page contains Eclipse Project guidelines on API deprecation.
This page is maintained by the [Eclipse/PMC](https://eclipse.dev/eclipse/team-leaders.php).


What is Deprecation?
====================

API deprecation is used to inform API clients that a particular API element is no longer recommended for use.
API deprecation is used to inform API clients that a particular API element is no longer recommended for use.
The deprecation comment should describe the reason for the deprecation, and directions for how to replace their usage with the new recommended way of doing things.
Deprecation does not necessary implies that the API will be deleted in a future release unless it is explicitely marked for deletion.

Expand All @@ -20,7 +20,7 @@ Process to deprecate an API
Identifying Deprecated API
==========================

This section describes how clients can identify what API is deprecated.
This section describes how clients can identify what API is deprecated.
To identify API from non-API, see [Provisional API Guidelines](Provisional_API_Guidelines.md)

Java API
Expand All @@ -31,16 +31,17 @@ Java API is deprecated through use of the @Deprecate annotation.
If it is planned to be removed in the future set the forRemoval = true property.
In this case, the since tag should include the release in which is was marked for deletion.

```java
@Deprecated(forRemoval = true, since="2024-12")
```


Older code used @deprecated javadoc tag on types, methods, and fields.
Older code used @deprecated javadoc tag on types, methods, and fields.
The javadoc paragraph following the @deprecated tag defines the rationale for the deprecation and instructions on moving to equivalent new API.

Extension Points
----------------

Elements and attributes in extension points are deprecated by setting the "Deprecated" property to true in the PDE extension point schema editor.
Elements and attributes in extension points are deprecated by setting the "Deprecated" property to true in the PDE extension point schema editor.
The entire extension point can be deprecated by deprecating the "extension" element, which is the top level element at the root of any contribution to the extension point.

![Schema-deprecation.png](images/Schema-deprecation.png)
Expand Down
22 changes: 16 additions & 6 deletions docs/Evolving-Java-based-APIs-3.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Other notes
Data Compatibility
------------------

The Component implementation may need to store and retrieve its internal data from a file. For example, Microsoft Word stores a document in a file. When one of these files may live from release to release, clients would break if the format or interpretation of that data changed in an incompatible way.
The Component implementation may need to store and retrieve its internal data from a file. For example, Microsoft Word stores a document in a file. When one of these files may live from release to release, clients would break if the format or interpretation of that data changed in an incompatible way.
**Data compatibility** is an additional issue for components with persistent data.

The standard technique is to tag all stored data with its format version number. The format version number is increased when the format is changed from one release to the next. The Component implementation contains readers for the current format version and for all past versions, but usually only the writer for the current format version (unless for some reason there is an ongoing need to write older versions).
Expand All @@ -34,9 +34,11 @@ Even simpler than Deprecate and Forward, the Component API and implementation ca

Here is a simple technique for adding an argument to a method that is intended to be overridden by subclasses. For example the `Viewer.inputChanged(Object input)` method should get an additional argument `Object oldInput`. Adding the argument results in pre-existing clients overridding the wrong method. The workaround is to call the old method as the default implementation of the new method:

```java
public void inputChanged(Object input, Object oldInput) {
inputChanged(input);
}
```

Pre-existing clients which override the old method continue to work; and all calls to the old method continue to work. New or upgraded clients will override the new method; and all calls to the new method will work, even if they happen to invoke an old implementation.

Expand All @@ -48,37 +50,45 @@ Since Java 8, this technique also works for interface methods (new method is a d

The first release of an API callback-style interface didn't work as well as hoped. For example, the first release contained:

```java
public interface IProgressMonitor {
void start();
void stop();
}

```

You now wish you had something like:

```java
public interface IProgressMonitor {
void start(int total);
void worked(int units);
void stop();
}

```

But it's too late to change `IProgressMonitor` to be that API. So you mark `IProgressMonitor` as deprecated and introduce the new and improved one under the name `IProgressMonitor2` (a name everyone recognizes as the second attempt):

```java
public interface IProgressMonitor2 extends IProgressMonitor {
void start(int total);
void worked(int units);
void stop();
}

```

By declaring the new interface to extend the old one, any object of type `IProgressMonitor2` can be passed to a method expecting an old `IProgressMonitor`. Don't forget to mention `IProgressMonitor2` in the API of `IProgressMonitor`, even if you don't deprecate it, e.g.:

```java
/**
* [...]
* @see IProgressMonitor2
*/
public interface IProgressMonitor {
[...]
}

```

### COM Style

The "COM style" is to not implement interfaces directly but to ask for an interface by using `getAdapter(someInterfaceID)`. This allows adding new interfaces in the implementation without breaking existing classes.
Expand Down Expand Up @@ -168,5 +178,5 @@ On the other hand, clients should avoid all `Class.getDeclared_XXX_` methods as
Versioning
----------

It should be easy for API clients to know whether a new version of your components broke APIs or not.
It should be easy for API clients to know whether a new version of your components broke APIs or not.
Eclipse projects implement semantic versioning according to the [Version Numbering](VersionNumbering.md) specification.
34 changes: 25 additions & 9 deletions docs/Evolving-Java-based-APIs.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Document is currently split in 3 parts:
* [Part 2: Achieving API Binary Compatibility](Evolving-Java-based-APIs-2.md)
* [Part 3: Other Notes](Evolving-Java-based-APIs-3.md)

This document is about how to evolve Java-based APIs while maintaining compatibility with existing client code.
Without loss of generality, we'll assume that there is a generic **Component** with a **Component API**, with one party providing the Component and controlling its API.
This document is about how to evolve Java-based APIs while maintaining compatibility with existing client code.
Without loss of generality, we'll assume that there is a generic **Component** with a **Component API**, with one party providing the Component and controlling its API.
The other party, or parties, write **Client** code that use the Component's services through its API. This is a very typical arrangement.


Expand Down Expand Up @@ -43,7 +43,7 @@ Changing an API in a way that is incompatible with existing Clients would mean t

As the Component API evolves, all pre-existing Clients are expected to continue to work, both in principle and in practice.

Suppose a Client was written to a given release of the Component and abided by the contracts spelled out in the Component API specification.
Suppose a Client was written to a given release of the Component and abided by the contracts spelled out in the Component API specification.
The first requirement is that when the Component API evolves to follow-on releases, all pre-existing Client must still be legal according to the contracts spelled out in the revised Component API specification, without having to change the Clients source code. This is what is meant by continuing to work in principle.

> **API Contract Compatibility:** _API changes must not invalidate formerly legal Client code._
Expand Down Expand Up @@ -79,11 +79,11 @@ Note that in some cases, the contractual roles are reversed. The party responsib

When contemplating changing an existing API contract, the key questions to ask are:

* What roles does the API contract involve?
* What roles does the API contract involve?
For a method contract, there is the caller and the implementor. In the case of frameworks, there is also an additional contract between superclass and subclass regarding default behavior, extending, and overriding.
* Which role or roles will each party play?
* Which role or roles will each party play?
For many Component API methods, the Component plays the role of exclusive implementor and the Client plays the role of caller. In the case of Component callbacks, the Component plays the caller role and the Client plays the implementor role. In some cases, the Client might play more than one role.
* Is a role played exclusively by the Component?
* Is a role played exclusively by the Component?
Component API changes coincide with Component releases, making it feasible to change Component code to accommodate the changed APIs.
* For roles played by Clients, would the contemplated API change render invalid a hypothetical Client making legal usage of the existing API?

Expand All @@ -95,24 +95,30 @@ Standard method contracts have two roles: caller and implementor. Method postcon

Consider the following API method specification:

```java
/** Returns the list of children of this widget.
* @return a non-empty list of widgets
*/
Widget[] getChildren();
```

The contemplated API change is to allow the empty list of widgets to be returned as well, as captured by this revised specification:

```java
/** Returns the list of children of this widget.
* @return a list of widgets
*/
Widget[] getChildren();
```

Would this change break compatibility with existing Clients? It depends on the role played by the Client.

Looking at the caller role, this change would break a hypothetical pre-existing caller that legitimately counts on the result being non-empty. The relevant snippet from this hypothetical caller might read:

```java
Widget[] children = widget.getChildren();
Widget firstChild = children[0];
```

Under the revised contract, this code would be seen to be in error because it assumes that the result of invoking `getChildren` is non-empty; under the previous contract, this assumption was just fine. This API change weakens a postcondition for the caller, and is not contract compatible for the caller role. The contemplated change would break Clients playing the caller role.

Expand All @@ -128,25 +134,31 @@ Method preconditions are those things that a caller must arrange to be true befo

Consider the following API method specification:

```java
/** Removes the given widgets from this widget's list of children.
* @param widgets a non-empty list of widgets
*/
void remove(Widget[] widgets);

```

The contemplated API change is to allow empty lists of widgets to be passed in as well:

```java
/** Removes the given widgets from this widget's list of children.
* @param widgets a list of widgets
*/
void remove(Widget[] widgets);
```

Would this change break compatibility with existing Clients? Again, it hinges on the role played by the Client.

Looking at the caller role, this change would not break hypothetical pre-existing callers since they pass in non-empty lists. However, this change would break a hypothetical pre-existing implementations that legitimately assumed that the argument is not empty.

The relevant snippet from this hypothetical implementor might read:

```java
Widget firstChild = widgets[0];
```

Under the revised contract, this code would be seen to be in error because it assumes that the argument is non-empty; under the previous contract, this assumption was just fine. This API change weakens a method precondition, and is not contract compatible for the implementor role. The contemplated change would break Clients that implement this method.

Expand All @@ -156,15 +168,19 @@ Fields can be analyzed as having two roles: a getter and a setter. The Java lang

Consider the following API field specification:

```java
/** This widget's list of children, or <code>null</code>.
*/
Widget[] children;

```

The contemplated API change is to get rid of the possibility of the `null` value:

```java
/** This widget's list of children.
*/
Widget[] children;
```

Would this change break compatibility with existing Clients?

Expand All @@ -182,7 +198,7 @@ However, if the method is added to a class which Clients may subclass, then the

### General Rules for Contract Compatibility

Whether a particular Component API change breaks or maintains contract compatibility with hypothetical pre-existing Clients hinges on which role, or roles, the Client plays in the API contract(s) being changed. The following table summarizes the pattern seen in the above examples:
Whether a particular Component API change breaks or maintains contract compatibility with hypothetical pre-existing Clients hinges on which role, or roles, the Client plays in the API contract(s) being changed. The following table summarizes the pattern seen in the above examples:

| | | | |
| --- | --- | --- | --- |
Expand Down
Loading
Loading