Java Development Tools

Here are descriptions of some of the more interesting or significant changes made to the Java development tools (JDT) for the 4.31 release of Eclipse. They are grouped into:

See also the Eclipse Platform What's New document for changes in the Platform.

We also recommend to read the Tips and Tricks.

Java Editor

New Make Static Refactoring

A new refactoring called 'Make Static' has been added to Eclipse's Java Development Tools (JDT), which converts instance methods into static methods, when possible. This refactoring adds an extra parameter to the method declarations to handle references to instance fields, methods, or classes in the original method. Existing calls to the method are altered accordingly, and if the extra parameter is necessary, the refactoring passes 'this' or the specific instance originally used to access the method.

To apply this refactoring, the following conditions must be met:

  • The method is not a constructor.
  • The method does not override a method from the parent type nor is overridden in any child types.
  • The type in which the method is declared is not a local type, an anonymous type, or an annotation.

The refactoring can be executed by selecting a method invocation, except in cases where a super method invocation is selected.

Make Static Refactoring Example Before

Make Static Refactoring Example After

Java Compiler

Analysis of Resource Leaks Improved with Annotations The compiler's capability to detect when resources (implementation of AutoCloseable) are not properly closed has been enhanced.

Previously, flow analysis for resource leaks was focused on resources that are created and closed within the same method. It could not deal well with resources that are shared between different methods, perhaps even different objects.

The compiler now interprets an annotation @Owning to understand data flows of resources by way of the following concepts:

A source of resources
Here a resource will come into the focus of the current method, along with a responsibility to close it.
A sink for resources
Here a resource will be consumed, either by closing, or by delegation to other code which then will be responsible

Resource allocation is the primordial source, and a call to AutoCloseable.close() is the final sink. When allocation and closing do not happen within the same method, then annotation @Owning should be used to create connections through which responsibility for a resource can be transferred from one method to another. The inverse annotation @NotOwning, on the other hand, signals that no such connection is made; the original holder of the resource is still responsible for sending it to a suitable sink.

code properly annotated for resource leak analysis

It's in method produce() where a new resource is allocated. The return statement in that method is governed by the @Owning annotation on the method. This implies that returning this value is a sink from the point of view of produce(). By this method produce() is considered safe. But looking from the outside this sink is in fact the source by which the resource arrives in method test().

After method test() receives the resource, the responsibility to close is fulfilled by passing it down into consume(). In method consume() it's the annotation on parameter in that creates the connection: test() has done its part and now consume() is responsible. Protecting the resource with a try-with-resources statement is the preferred way to fulfill the responsibility, its implicit close() call is the ultimate sink. Thus the given combination of method calls indeed creates a provably safe data flow from initial source to final sink, because both calls are governed by @Owning.

The body of produce() also shows another detail: just like test() it passes the resource as a parameter to another method, here: skipHeader(). The parameter of skipHeader(), however, is annotated as @NotOwning by which the method rejects any responsibility. Indeed there's no close call to be found here, but that's OK under the @NotOwning annotation - this parameter is not a source. As a result, still after the call to skipHeader() it is produce() who is responsible. For that reason saying return in; is indeed necessary for produce() to demonstrate obedience to the contract.

Additional rules exist for fields holding a resource and for methods other than close() that perform mandatory clean-up. Details on those can be found in the documentation of org.eclipse.jdt.annotation.Owning.

To enable this feature select Java Compiler > Errors/Warnings > Enable annotation based resource analysis in the project preferences:

compiler properties dialog

Java Formatter

Switch Statements/Expressions: Align Arrows on Column Switch statements and expressions with arrows can now be aligned so that all arrows are placed at the same position in line. Open the formatter profile editor and find the new option under Indentation > Align items in columns > Arrows in switch statements/expressions.

Formatter options and code preview