2012-07-25 40 views
7

java.net.InetAddress resuelve nombres de host usando predeterminado host-de resolución de nombres de la máquina local de forma predeterminada:¿Cómo configurar la resolución del nombre de host para usar un servidor DNS personalizado en Java?

nombre de host-a-IP se lleva a cabo la resolución de direcciones mediante el uso de una combinación de información de configuración de máquina local y la red de servicios de nombres tales como el Sistema de nombres de dominio (DNS) y el Servicio de información de red (NIS). Los servicios de nombres particulares que se utilizan son por defecto la máquina local configurada es. Para cualquier nombre de host, se devuelve su dirección IP correspondiente. [source]

¿Cómo podemos configurar este comportamiento sin modificar resolver el nombre de host predeterminado de la máquina local?

Por ejemplo, hay alguna forma de configurar java.net.InetAddress tal que resuelve los nombres de host a través de OpenDNS (208.67.222.222, 208.67.220.220) o Google Public DNS (2001: 4860: 4860 :: 8888, 2001: 4860: 4860: : 8844)?

¿O es la única solución para crear explícitamente solicitudes de paquete DNS, enviarlas a los servidores a través de java.net.DatagramSocket o java.net.Socket, y analizar las respuestas?

Respuesta

8

Java 9 eliminó esta capacidad. Tendrá que usar una biblioteca de cliente DNS de terceros.

Si está utilizando Java 8 años o más que puede hacer:

Puede establecer la propiedad del sistema sun.net.spi.nameservice.nameservers según lo documentado por this site.

+1

Según lo documentado en el mismo sitio: "Es posible que estas propiedades no se admitan en versiones futuras". ¿Hay alguna otra manera de lograr eso? – bernatp

+2

No. No si quiere usar 'java.net.InetAddress'. Si está bien utilizando un mecanismo diferente, puede utilizar una biblioteca DNS de terceros (por ejemplo, [dnsjava] (http://www.dnsjava.org/)). La única razón real por la que las propiedades podrían cambiar es si Oracle revisa la implementación de 'java.net' en alguna versión futura de Java. Si esto sucede, es probable que proporcionen una nueva solución a este problema en ese momento también. – Pace

+0

Se reacondicionó 'java.net' en Java 9, por lo que las clases' sun.net' necesarias para lograr esto ya no existen. – ndm13

1

Aquí está el código que he escrito en el disco de código un nombre foo sistema DNS resolución en Java para que los casos de prueba pasen. Su ventaja es agregar su (s) entrie (s) específico (s) a la resolución DNS predeterminada del tiempo de ejecución de Java.

Recomiendo para no ejecutarlo en la producción. Se utiliza el acceso reflexivo forzado y las clases de implementación no pública de Java en tiempo de ejecución.

private static final String FOO_IP = "10.10.8.111"; 

/** Fake "foo" DNS resolution */ 
@SuppressWarnings("restriction") 
public static class MyHostNameService implements sun.net.spi.nameservice.NameService { 
    @Override 
    public InetAddress[] lookupAllHostAddr(String paramString) throws UnknownHostException { 
     if ("foo".equals(paramString) || "foo.domain.tld".equals(paramString)) { 
      final byte[] arrayOfByte = sun.net.util.IPAddressUtil.textToNumericFormatV4(FOO_IP); 
      final InetAddress address = InetAddress.getByAddress(paramString, arrayOfByte); 
      return new InetAddress[] { address }; 
     } else { 
      throw new UnknownHostException(); 
     } 
    } 
    @Override 
    public String getHostByAddr(byte[] paramArrayOfByte) throws UnknownHostException { 
     throw new UnknownHostException(); 
    } 
} 

static { 
    // Force to load fake hostname resolution for tests to pass 
    try { 
     List<sun.net.spi.nameservice.NameService> nameServices = 
      (List<sun.net.spi.nameservice.NameService>) 
      org.apache.commons.lang3.reflect.FieldUtils.readStaticField(InetAddress.class, "nameServices", true); 
     nameServices.add(new MyHostNameService()); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } 
} 

Espero que esto ayude, pero de nuevo, ¡a utilizar con cuidado!

Cuestiones relacionadas