How to configure host name resolution to use a universal host name resolver in Java
Tags: java, programming, networking, dns
Published: 2022-10-28 21:59:00

In the JDK 8 the [java.net.InetAddress][1] resolves host names using the local machine's default host name resolver by default:

> Host name-to-IP address resolution is accomplished through the use of a combination of local machine configuration information and network naming services such as the Domain Name System (DNS) and Network Information Service(NIS). The particular naming services(s) being used is **by default the local machine configured one**. For any host name, its corresponding IP address is returned. <sup>[[source]][1]</sup>

In the JDK 19 the [java.net.InetAddress][2] works the same way but there is also the option to use a custom configuration:

> The built-in InetAddress resolver implementation does host name-to-IP address resolution and vice versa through the use of a combination of local machine configuration information and network naming services such as the Domain Name System (DNS) and the Lightweight Directory Access Protocol (LDAP). The particular naming services that the built-in resolver uses **by default depends on the configuration of the local machine**. InetAddress has a service provider mechanism for InetAddress resolvers that allows a custom InetAddress resolver to be used instead of the built-in implementation. <sup>[[source]][3]</sup>

So how can we configure this behavior without modifying the local machine's default host name resolver in a universal way that works for Java 8 and later?

In this situation [**Burningwave Tools**](https://burningwave.github.io/tools/) comes to our aid by providing us with the `HostResolutionRequestInterceptor` that allows us:
* to use a custom resolver instead the default one
* to prepend a custom resolver to the default one
* to postpone a custom resolver to the default one

To include Burningwave Tools in our project we need to add the following dependency to our _pom.xml_: 

{% gist https://gist.github.com/Roberto-Gentili/e7eeaa80443d27985be8563d3e0fb561.js %}

And to install the HostResolutionRequestInterceptor component we must proceed as follows:

{% gist https://gist.github.com/JJBRT/e828f3bb0b004cd2f01e26887781499b %}

Burningwave Tools provides also a DNS server connection based host resolver:

{% gist https://gist.github.com/JJBRT/7067fe83fed9c31d1817b13cba11d5c0.js %}

But you can also define a new custom resolver by implementing the HostResolver interface that [create DNS packet requests][4], send them to the servers through the [java.net.DatagramSocket][5] and [parse the responses][6]:

{% gist https://gist.github.com/JJBRT/55a206a9e3b630b4e8c3807c76fa6956.js %}

If we add the [**Jackson framework**](https://mvnrepository.com/artifact/com.fasterxml.jackson.core) to our project we can add the configuration via yaml file support with a few lines of code by using the [`PathHelper`](https://burningwave.github.io/core/#Resolving-collecting-or-retrieving-paths) component:

{%gist https://gist.github.com/JJBRT/cb24302ce5b64ad061f012e547295767.js %}

{%gist https://gist.github.com/JJBRT/f925b6c84dabb6656e1d33fdda1223c8.js %}

From [**here**](https://github.com/JJBRT/advanced-java-tutorials) you can download/clone the [**tutorial shared on GitHub**](https://github.com/JJBRT/advanced-java-tutorials/tree/master/customize-hostname-resolution).

  [1]: https://docs.oracle.com/javase/8/docs/api/java/net/InetAddress.html

  [2]:
https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/net/InetAddress.html

  [3]: https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/net/InetAddress.html#host-name-resolution

  [4]:
https://levelup.gitconnected.com/dns-request-and-response-in-java-acbd51ad3467

  [5]:
https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/net/DatagramSocket.html

  [6]:
https://levelup.gitconnected.com/dns-response-in-java-a6298e3cc7d9