JDK-8274558 : Implementation of JEP 418: Internet-Address Resolution SPI
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.net
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 18
  • Submitted: 2021-09-30
  • Updated: 2021-10-26
  • Resolved: 2021-10-26
Related Reports
CSR :  
Description
Summary
-------

Add new Service Provider Interface (SPI) to allow customization of `InetAddress` API methods implementing host name and address resolution requests.

Problem
-------

`InetAddress` API methods delegate to built-in resolver to perform an Internet-Address (IP) resolution operations. The built-in resolver is responsible for forwarding the resolution requests to Operating System (O/S) resolver. Currently, there is no mechanism available to replace it with a custom resolver implementation. 
The built-in resolver is problematic for Virtual Threads (project Loom) as it will block in the kernel, which limits the number of  concurrent requests that can be sent in parallel. Providing an SPI would allow applications that need massive parallelism to replace the built-in implementation with a more scalable implementation.

Solution
--------

Introduce a new Java standard service provider interface that allows installing a custom resolver implementation as the built-in resolver replacement. More information is available in [JEP-418](https://bugs.openjdk.java.net/browse/JDK-8263693)


Specification
-------------

The list of `InetAddress` API methods that will use a custom resolver, if one installed:

 - IP address (forward) lookup methods: `InetAddress.getAllByName` and
   `InetAddress.getByName`
 - Host name (reverse) lookup methods:
   `InetAddress.getCanonicalHostName` and `InetAddress.getHostName`
  
  
Summary of new SPI classes added to 'java.net.spi' package:

 - `InetAddressResolverProvider` - a new abstract class defining a service provider, and is, essentially, a factory for `InetAddressResolver` resolvers.
 - `InetAddressResolverProvider.Configuration` - a new sealed interface describing the platform's built-in configuration for resolution operations.
 - `InetAddressResolver` - an interface that defines methods for the forward and reverse lookup operations.
 - `InetAddressResolver.LookupPolicy` - a final class whose instances describe the characteristics of a forward lookup operation.

List of API documentation changes that can be found in attached `specdiff.zip` archive:

 - Document new SPI classes added to `java.net.spi` package.
 - Changes to `java.net.InetAddress`:  Extend class-level documentation to describe how new SPI works; update javadocs for existing API methods  to use `resolver` term.
 - Add new `inetAddressResolverProvider` permission  to a table with the standard target names in `RuntimePermission` class-level javadoc

Attached `webrev.zip` also contains a change to `src/java.base/share/classes/java/net/doc-files/net-properties.html` file as well as to the `src/java.base/share/classes/module-info.java` file alongside to other implementation changes.
(changes to these two files are unfortunately not tracked by the specdiff)

Comments
Moving to Approved. I did not see any obvious edits needed to be made to Inet4Address or Inet6Address as part of this work.
26-10-2021

During the PR review multiple changes to `InetAddressResolverProvider`, `InetAddressResolver`, and `InetAddress` classes have been applied. Most of the changes are in class-level javadoc sections describing how new service provider is discovered, set and used by `InetAddress` API. specdiff and webrev archives with these changes are attached: `specdiff-4.zip` `webrev-4.zip`
26-10-2021

The changes to `java.net.spi.InetAddressResolver`, `java.net.spi.InetAddressResolverProvider` and `java.net.InetAddress` javadocs have been made to address [code review][1] comments. The updated specdiff and webrev archives with these changes incorporated are attached: specdiff-3.zip and webrev-3.zip [1]: https://github.com/openjdk/jdk/pull/5822
22-10-2021

Thanks for your comments, Joe. Please, find updates and replies below: > Please check for proper @since tags on the new API elements. Added `"@since 18"` tags to the new API classes > Please add explicit discussion of empty/not found conditions in > InetAddressResolver, presumably empty streams are returned. `InetAddressResolver.lookupByName` documentation specifies that `UnkownHostException` should be thrown if no IP addresses for the specified host name could be found. > Should InetAddressResolver.LookupPolicy be an enum? Motivations behind making `LookupPolicy` as a final class instead of *enum* are the following: - In the future, there could be possible extensions made to the resolution mechanism that requires an addition of a new bit flag that will be supplied to a resolver alongside to addresses type and order flags. - Addresses type and order constants defined in `LookupPolicy` class are used in the built-in resolver native implementation to query an O/S resolver. > I assume InetAddressResolverProvider is an abstract class rather than an interface to allow for permissions checks. Correct, `InetAddressResolverProvider` is mentioned as an abstract class above. `InetAddressResolver` is an interface. I'm attaching new versions of *specdiff-1.zip* and *webrev-1.zip* with latest changes.
20-10-2021

During [code review][1] for JEP 418 the following changes to `java.net.spi.InetAddressResolver` interface have been applied: - `InetAddressResolver.lookupAddresses` was renamed to `InetAddressResolver.lookupByName` - `InetAddressResolver.lookupHostName` was renamed to `InetAddressResolver.lookupByAddress` specdiff and webrev archives with these changes are attached: `specdiff-2.zip` and `webrev-2.zip` [1]: https://github.com/openjdk/jdk/pull/5822
20-10-2021

[~dfuchs] [~aefimov] Thanks much for clarifying the need for Configuration interface.
14-10-2021

During prototyping work, it was established that custom `InetAddressResolver` providers might need: - the reference to a built-in resolver - a way to acquire a `localhost name` from O/S. You're correct that `InetAddressResolverProvider.Configuration` interface API might evolve. In this case, other methods may be added to the `Configuration` interface. That is why we pass the `Configuration` instance to `InetAddressResolverProvider.get` instead of two parameters: built-in resolver reference and a supplier of a `localhost name`. Worth noting here that `local hostname` can change with time: the value seen during provider instantiation might differ from the value observed when a lookup operation is performed. `Configuration.localhostname` returns up-to-date name.
13-10-2021

InetAddressResolverProvider.Configuration as sealed interface, supplying the built-in resolver. Just thinking, modifying the method signature to avoid this sealed interface? public abstract InetAddressResolver get(InetAddressResolver builtInResolver); OR the scope of this Configuration is going to evolve ?
13-10-2021

The `Configuration` class also allows to query for the local host name, which is a dynamic information. It is not clear that there is a use case for custom code to provide its own implementation of the `Configuration` interface. Allowing it would also pause an interesting naming challenge as `Configuration::builtinResolver` might no longer return the built-in resolver. Therefore we settled on defining a sealed interface, which also gives us the possibility of unsealing it in the future if we ever find a use case that requires it. It also caters for future evolution if we have the need to pass more configuration items.
13-10-2021

Moving to Provisional. Please check for proper @since tags on the new API elements. Please add explicit discussion of empty/not found conditions in InetAddressResolver, presumably empty streams are returned. Should InetAddressResolver.LookupPolicy be an enum? I assume InetAddressResolverProvider is an abstract class rather than an interface to allow for permissions checks.
11-10-2021