web-dev-qa-db-fra.com

Dans Java 8, comment puis-je obtenir mon nom d'hôte sans le coder en dur dans mon environnement?

Nous venons de passer à Java 8 sur Amazon Linux. Nous utilisons Spring 4.3.8.RELEASE. Auparavant, nous pouvions obtenir le nom d'hôte de notre machine en configurant des beans dans notre fichier de contexte d'application comme alors ...

<bean id="localhostInetAddress" class="Java.net.InetAddress" factory-method="getLocalHost" />
<bean id="hostname" factory-bean="localhostInetAddress" factory-method="getHostName" />

Mais avec Java 8, le bean "hostname" contient maintenant la chaîne

localhost

Avant Java 8, il contenait la valeur "hostname" exécutée sur la ligne de commande, qui est

[myuser@machine1 ~]$ hostname
machine1.mydomain.org

Comment puis-je reconfigurer notre bean pour qu'il obtienne le nom d'hôte que la ligne de commande répertorie? Je ne veux rien coder en dur n'importe où.

22
Dave

Il y a une question similaire dans les bogues OpenJDK

Les appels les plus récents respectent les fichiers de configuration localhosts /etc/nsswitch.conf. Dans le cas de cette machine, ce fichier indique à ces appels de rechercher dans les fichiers avant de référencer d'autres services de nommage.

Étant donné que le fichier/etc/hosts contient un mappage explicite pour cette combinaison nom d'hôte/IP, c'est ce qui est renvoyé.

Dans les anciens JDK, gethostbyname ignorait en fait les paramètres des machines locales et était immédiatement délégué au service de nommage.

Vous pouvez toujours utiliser la classe Runtime pour cela:

Process hostname = Runtime.getRuntime().exec("hostname");

BufferedReader stdInput = new BufferedReader(new
            InputStreamReader(hostname.getInputStream()));
String s;
while ((s = stdInput.readLine()) != null) {
        System.out.println(s);
}

Mais ce n'est pas aussi recommandé que possible voir

1
Daniel Taub

De InetAddress Java 8 n'obtient pas le nom d'hôte :

Un bug similaire a été déclenché dans JDK.

Ce que je comprends, c'est qu'ils ont changé le processus de résolution par défaut.

Ils honorent la configuration dans /etc/nsswitch.conf où les hôtes sont configurés pour/etc/hosts, ce qui lui donne la priorité principale pour la résolution de noms.

Habituellement,/etc/hosts a un enregistrement pour 127.0.0.1 localhost qui fournit le nom de l'hôte localhost

4
mikep

InetAddress dans Java 8 avait un bug concernant la résolution du nom d'hôte. Le bogue a été signalé dans la version 8u20 et a été corrigé depuis. Veuillez vérifier que vous n'êtes pas sur sinon, utiliser InetAddress.getLocalHost().getHostName() vous donnera le nom d'hôte.

Je suggère également de configurer un nom d'hôte statique sur l'instance AWS.

  1. Mettre à jour/etc/hosts
  2. Mettre à jour/etc/hostname
  3. Exécutez hostname pour vérifier le nom d'hôte
  4. Redémarrez et vérifiez le nom d'hôte persistant

Cela devrait vous permettre de lire le nom d'hôte du fichier si nécessaire.

De plus, si la commande hostname donne le résultat correct, utilisez alors méthode exec dans la classe Runtime pour exécuter la commande et lisez InputStream pour obtenir la réponse.

PS: vous pouvez utiliser InetAddress.getLocalHost().isLoopbackAddress() pour vérifier si l'adresse est une adresse LoopbackAddress, puis utiliser une méthode de secours.

2
Arpit Sharma

Je peux mieux définir une propriété dans votre fichier .properties pour un nom d'hôte comme.

hostname=myserver.mydomain.com

Et utilisez-le dans votre application. Cette façon n'est pas codée. Il évite également la dépendance à la configuration du système d'exploitation qui peut être modifiée sans attention.

2
Mehmet Sunkur

Je crois que Java appelle toujours la gethostname() native, mais je ne peux pas dire pourquoi cela échoue.

Pour Linux, vous pouvez essayer cette alternative:

String hostname = new String(Files.readAllBytes(Paths.get("/proc/sys/kernel/hostname")), StandardCharsets.US_ASCII);
2
Marcos Zolnowski

Alternativement, vous pouvez exécuter la commande hostname linux en utilisant Java Runtime, le code devrait être quelque chose comme ci-dessous:

String cmdResult="";
Runtime r = Runtime.getRuntime();
Process p = r.exec("hostname");
BufferedReader in = new BufferedReader(new
InputStreamReader(p.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
                cmdResult += inputLine;
      }
in.close();
2
Rahul

Depuis que mon commentaire s'est perdu dans le flux, veuillez essayer

<bean id="hostname" class="com.amazonaws.util.EC2MetadataUtils" factory-method="getLocalHostName()">

Jetez un œil à la documentation d'Amazon si le résultat ne correspond pas à vos besoins.

2
Hannes

Vous avez vraiment trois options de complexité et de valeur d'information différentes:

  1. Exécutez en fait la commande hostname en utilisant Runtime . Il est assez portable et devrait fonctionner à peu près partout. (Peut-être pas sur les mainframes d'IBM)
  2. Saisissez toutes les interfaces réseau disponibles et obtenez leurs noms d'hôte. https://docs.Oracle.com/javase/tutorial/networking/nifs/listing.html
  3. Définissez un environnement ou une propriété système comme valeur de nom d'hôte .
    Comme Java -Dmy.hostname = hostname ...

La partie triste est que ce n'est pas si simple dans Spring XML.

Toutes les autres options sont connues pour donner divers degrés de précision. Comme 127.0.0.1 se résoudra probablement en localhost ou localhost.localdomain .

2
Aleksandr Panzin

Vous pouvez essayer InetAddress.getCanonicalHostName()

Le JavaDocs pour getCanonicalHostName () dit

Obtient le nom de domaine complet pour cette adresse IP. Méthode du meilleur effort, ce qui signifie que nous ne pourrons peut-être pas renvoyer le FQDN en fonction de la configuration du système sous-jacent.

2
LukeN