JDK-8192780 : Consider restoring DNS SPI
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 9,10
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • Submitted: 2017-11-30
  • Updated: 2021-11-12
  • Resolved: 2021-11-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
In this change

changeset:   14108:d11ad4b19348   
user:        msheppar
date:        2016-04-11 03:00 +0100
8134577: Eliminate or standardize a replacement for sun.net.spi.nameservice.NameServiceDescriptor
Reviewed-by: chegar, alanb

an internal API was removed.  This causes hardships for us at Google.  We eventually decided to restore the functionality locally in our jdk9, roughly as in this patch:


This API was a natural thing to use as a general purpose DNS proxy mechanism.  Should we instead be creating a "real" DNS server outside the JDK?  

The jdk.net.hosts.file replacement seems inadequate - a general proxy cannot be replaced by a simple file.
Comment from submitter of JDK-8201428: ------------------------------------------------------------ Within our product (BiglyBT) we have been making use of the DNS SPI for various reasons (proxing of certain DNS requests; triggering of the installation of software to handle various proxied domains). We need to be able to intercept DNS resolution requests and then either handle them ourselves or forward them to the default provider. From Java 9 we have been using reflection to access java.net.InetAddressImpl for delegation but this is obviously not optimal and also generates an 'illegal reflective access' warning with threats about future prohibition. A feature we also want to implement, but are wary of doing so given the current support, is use of services such as DNS-over-HTTPS provided by Cloudflare (https://developers.cloudflare.com/ via a DNS proxy. We are very interested in having a standard way of achieving our aims here!

The original motivation for this feature was Solaris environments configured to use NIS rather than DNS. That scenario hasn't been interesting for many years. For a brief time, Sun's Java Web Start used the DNS provider to workaround timeout and configuration issues in specific Windows environments. That scenario has also not been interesting for many years. So it would be interesting to see if there is a real need here. As Martin's notes, it is a bit odd to have an application configured to use only DNS then the system is configured differently (maybe hosts file + DNS). If it were to be restored then its initialization and interaction with other classes would need to be re-examined as it has historically been involved in messy recursive initialization and startup issues. Minimally it could not be used until initPhase2 has completed. As regards whether it needs to be a standard interface then maybe not, it could be exported to the jdk.naming.dns module with the DNS implementation and loaded via ServiceLoader (maybe java.naming too if it is interesting to have an LDAP implementation). That would avoid adding a documented interface. It also comes down to whether there are interesting scenarios where the application needs to be configured differently to the system.

My webrev was not a serious proposal, but a "user experience report" that shows that it is possible to restore this API in jdk9 - at Google we are currently running with a local patch close to this. it's totally acceptable for us to have the API elsewhere (e.g. java.net instead of sun.net). We will try to understand our internal users' needs better. (Modifying DNS behavior should arguably not be done inside a language library since then such facilities have to be built into every language's library. it should be done at the OS level)

Chris, thanks for filing the bug! And don't worry, the reason the customer couldn't use the native implementation was not because it is not sufficient. It was rather because he did run in a rather weird environment with restrictions on which native functions he was able to call so he resorted to a "Java-only" solution DNS resolution.

I filed JDK-8192780 to track the issue with DNSContext. Further discussion relating to that specific issue should probably happen there. Volker, the reason your customer reached for the unsupported name service interface was because: "the customer couldn't use the default, native resolution for some other reasons". Would it be possible to find out from your customer what that reason is, so we can further understand why OS configuration is not sufficient?

We had a customer who used InetAddress to resolve some hosts and he got the problems I mentioned before because the query of the three record types "A", "AAAA", "CNAME" was squashed into one "ANY" request (the customer couldn't use the default, native resolution for some other reasons). With jdk8 he could simply switch to an alternative, open source Name Service provider. With jdk9 this will not be possible any more because InetAddress uses either the default, native implementation or the jdk.net.hosts.file replacement. So we think it might be good if InetAddress' usage of name services could be made configurable again. Interdependently from that, the JNDI DNS provider could be made configurable to not squash multiple requests into one request of type "ANY" .

The JNDI DNS provider assumes support for "*" qtypes and maybe that needs to be re-examined. Best to create a bug in the java.naming subcomponent to re-examine that.

Volker, as already stated, the suggested patch does not constitute an acceptable proposal. What specifically are your requirements? You seem to be more interested in enabling the JNDI DNS provider, or is that just an observation of a bug in said provider's implementation.

Alan, Martin, we run into similar problems as well with some clients so we are highly interested in a solution as proposed by Martin. One other issue you should be aware of when implementing the proposed solution is that many modern DNS servers (e.g. CloudFare) reject DNS requests of type "ANY". The old, jdk8 implementation (which used com.sun.jndi.dns.DNSContext) tried to squash queries for several DNS types into a single ANY query (e.g. a lookup which queries "A", "AAAA" and "CNAME" were mapped to a single "ANY" query). This is still done in the latest version of DNSContext in jdk 9 and 10: /* * Returns the most restrictive resource record class and type * that may be used to query for records matching cts. * See classAndTypeMatch() for matching rules. */ private static CT getClassAndTypeToQuery(CT[] cts) { int rrclass; int rrtype; if (cts == null) { // Query all records. rrclass = ANY; rrtype = ANY; } else if (cts.length == 0) { // No records are requested, but we need to ask for something. rrclass = ResourceRecord.CLASS_INTERNET; rrtype = ANY; } else { rrclass = cts[0].rrclass; rrtype = cts[0].rrtype; for (int i = 1; i < cts.length; i++) { if (rrclass != cts[i].rrclass) { rrclass = ANY; } if (rrtype != cts[i].rrtype) { rrtype = ANY; } } } return new CT(rrclass, rrtype); DNSNameService.lookupAllHostAddr() wants to query the three record types "A", "AAAA", "CNAME", but in the end this results into a query of "ANY" which fails for some DNS servers. Notice that the OS-implementations do single requests. It would be great if during your changes you could at least make this behavior configurable by a property if not the default.

Accepting for now, pending further discussion and clarification.

Martin, your patch is not acceptable as is. As Alan said, the java.base module cannot export the sun.net.spi.nameservice package, but I can see why this may be a reasonable first attempt since calling code can continue to execute without change. What specifically are your requirements? And what specifically is inadequate about the jdk.net.hosts file mechanism ( we know there are limitations in its implementation, and these can be fixed ).

The legacy name service SPI was never a supported interface. It was very problematic and was involved in many recursive initialization issues at first usage. Testing has been the main usage in recent years so the jdk.net.hosts.file replacement has been working well. Note that java.base cannot export sun.net.* packages so if there is effect to introduce a SPI then it would need to be a standard API.

Google engineers are willing to do the implementation engineering once a resolution is agreed upon. One possibility is to move the spi from sun.net to java.net.