2012-07-25 13 views
7

java.net.InetAddress risolve i nomi host utilizzando predefinito host-name resolver del computer locale per impostazione predefinita:Come configurare la risoluzione del nome host per utilizzare un server DNS personalizzato in Java?

host name-to-IP risoluzione degli indirizzi si realizza attraverso l'uso di una combinazione di informazioni di configurazione macchina locale e rete di servizi di denominazione, come il Domain Name System (DNS) e Network Information Service (NIS). Il particolare servizio di denominazione utilizzato è per impostazione predefinita, il computer locale ha configurato uno. Per qualsiasi nome host, viene restituito l'indirizzo IP corrispondente. [source]

Come possiamo configurare questo comportamento senza modificare resolver hostname di default del computer locale?

Ad esempio, è comunque necessario configurare java.net.InetAddress in modo che risolva i nomi host tramite OpenDNS (208.67.222.222, 208.67.220.220) o Google Public DNS (2001: 4860: 4860 :: 8888, 2001: 4860: 4860: : 8844)?

Oppure è l'unica soluzione per creare esplicitamente richieste di pacchetti DNS, inviarle ai server tramite java.net.DatagramSocket o java.net.Socket e analizzare le risposte?

risposta

8

Java 9 ha rimosso questa funzionalità. Sarà necessario utilizzare una libreria client DNS di terze parti.

Se si utilizza Java 8 o più anziani si può fare:

È possibile impostare la proprietà di sistema sun.net.spi.nameservice.nameservers come documentato da this site.

+1

Come documentato nello stesso sito: "Queste proprietà potrebbero non essere supportate nelle versioni future." C'è un altro modo per riuscirci? – bernatp

+2

No. Non se si desidera utilizzare 'java.net.InetAddress'. Se stai usando un meccanismo diverso, potresti ovviamente utilizzare una libreria DNS di terze parti (ad es. [Dnsjava] (http://www.dnsjava.org/)). L'unica vera ragione per cui le proprietà potrebbero cambiare è se Oracle revisiona l'implementazione 'java.net' in qualche versione futura di Java. Se ciò accade, probabilmente forniranno una nuova soluzione a questo problema anche in quel momento. – Pace

+0

Hanno revisionato 'java.net' in Java 9, quindi le classi' sun.net' necessarie per rimuoverlo non esistono più. – ndm13

1

Ecco il codice che ho scritto a livello di codice un nome di sistema foo DNS risoluzione in Java per passare i casi di test. La sua caratteristica è quella di aggiungere le tue specifiche entrate alla risoluzione DNS di runtime Java predefinita.

Si consiglia di di non eseguirlo in produzione. Sono utilizzate le classi di implementazione non pubbliche con accesso forzato e Java Runtime!

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(); 
    } 
} 

Spero che questo aiuti, ma ancora, per essere utilizzato con cura!

Problemi correlati