web-dev-qa-db-ja.com

Java 8では、自分の環境でホスト名をハードコーディングせずにホスト名を取得するにはどうすればよいですか?

Java= Amazon Linuxで8にアップグレードしました。Spring4.3.8.RELEASEを使用しています。以前は、アプリケーションコンテキストファイルに次のようなBeanを設定することで、マシンのホスト名を取得できました。そう ...

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

ただし、Java 8の場合、Beanの「ホスト名」には文字列が含まれるようになります。

localhost

Java 8の前は、コマンドラインで実行される "hostname"値が含まれていました。

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

コマンドラインがリストするホスト名を取得するようにBeanを再構成するにはどうすればよいですか?どこにもハードコーディングしたくありません。

22
Dave

OpenJDKバグ にも同様の質問があります

新しい呼び出しでは、localhosts /etc/nsswitch.conf構成ファイルが考慮されます。このマシンの場合、そのファイルは、他のネーミングサービスを参照する前にファイルを検索するようにこれらの呼び出しに指示します。

/ etc/hostsファイルには、このホスト名とIPの組み合わせの明示的なマッピングが含まれているため、これが返されます。

以前のJDKでは、gethostbynameは実際にはローカルマシンの設定を無視し、すぐにネームサービスに委任していました。

いつでも Runtime クラスを使用できます。

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

しかし、できる限りお勧めしません see

1
Daniel Taub

From InetAddress Java 8がホスト名を取得していない

JDKで同様のバグが発生しました。

私が理解しているのは、彼らがデフォルトの解決プロセスを変更したということです。

それらは、ホストが/ etc/hostsに対して構成されている/etc/nsswitch.confの構成を尊重し、名前解決の主な優先順位を与えます。

通常、/ etc/hostsには、ホストlocalhostの名前を提供する127.0.0.1 localhostのレコードがあります

4
mikep

Java 8のInetAddressには、ホスト名の解決に関して バグ がありました。このバグはバージョン8u20で報告されており、それ以降修正されています。オンになっていないことを確認してくださいこのバージョンでない場合は、InetAddress.getLocalHost().getHostName()を使用してホスト名を取得します。

また、AWSインスタンスに 静的ホスト名 を設定することをお勧めします。

  1. / etc/hostsを更新する
  2. / etc/hostnameを更新する
  3. hostnameを実行してホスト名を確認します
  4. 再起動して永続化されたホスト名を確認します

これにより、必要に応じてファイルからホスト名を読み取ることができます。

また、hostnameコマンドが正しい結果を提供している場合は、 ランタイムクラスのexecメソッド を使用してコマンドを実行し、InputStreamを読み取って応答を取得します。

PS:InetAddress.getLocalHost().isLoopbackAddress()を使用して、アドレスがLoopbackAddressかどうかを確認してから、フォールバックメソッドを使用できます。

2
Arpit Sharma

ホスト名のように.propertiesファイルでプロパティを定義した方がいいかもしれません。

hostname=myserver.mydomain.com

そして、あなたのアプリケーションでそれを使用してください。この方法はハーコード化されていません。また、注意せずに変更できるオペレーティングシステム構成への依存を回避します。

2
Mehmet Sunkur

Javaは依然としてネイティブgethostname()を呼び出しますが、これが失敗する理由はわかりませんでした。

Linuxの場合、次の代替策を試すことができます。

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

または、Javaランタイムを使用して、hostname linuxコマンドを実行できます。コードは以下のようになります。

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

私のコメントがストリームで失われたので、お試しください

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

結果がニーズに合わない場合は、 Amazonのドキュメント をご覧ください。

2
Hannes

実際には、複雑さと情報の価値が異なる3つのオプションがあります。

  1. Runtime を使用してhostnameコマンドを実際に実行します。それはかなりポータブルであり、ほとんどどこでも動作するはずです。 (たぶんIBMのメインフレームにはない)
  2. 利用可能なすべてのネットワークインターフェイスを取得し、それらのホスト名を取得します。 https://docs.Oracle.com/javase/tutorial/networking/nifs/listing.html
  3. hostnameの値として環境またはシステムプロパティを設定します。
    同様Java -Dmy.hostname = hostname ...

残念なことに、Spring XMLではそれほど単純ではありません。

他のすべてのオプションは、さまざまな程度の精度を提供することが知られています。同様に127.0.0.1localhostまたはlocalhost.localdomain

2

あなたはInetAddress.getCanonicalHostName()を試すことができます

GetCanonicalHostName()のJavaDocsは言う

このIPアドレスの完全修飾ドメイン名を取得します。ベストエフォート方式。つまり、基になるシステム構成によっては、FQDNを返せない場合があります。

2
LukeN