В Java 8, как мне получить свое имя хоста без жесткого кодирования в моей среде?
Мы только что перешли на Java 8 на Amazon Linux. Мы используем Spring 4.3.8.RELEASE. Раньше считалось, что мы можем получить наше машинное имя, настроив beans в нашем файле контекста приложения так...
<bean id="localhostInetAddress" class="java.net.InetAddress" factory-method="getLocalHost" />
<bean id="hostname" factory-bean="localhostInetAddress" factory-method="getHostName" />
Но с Java 8 бит "hostname" теперь содержит строку
localhost
До Java 8 оно содержало значение "имя хоста", которое запускалось в командной строке, что
[[email protected] ~]$ hostname
machine1.mydomain.org
Как я могу переконфигурировать наш компонент, чтобы он получил имя хоста, которое выводится в командной строке? Я не хочу ничего жестко кодировать.
Ответы
Ответ 1
Подобный вопрос возникает в ошибках 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);
}
Но это не так рекомендуется, как вы можете видеть
Ответ 2
Из InetAddress java 8 не получает имя хоста:
В JDK произошла аналогичная ошибка.
Я понимаю, что они изменили процесс разрешения по умолчанию.
Они соблюдают конфигурацию в /etc/nsswitch.conf, где хосты настроены для /etc/hosts, что дает ему основной приоритет для разрешения имен.
Обычно /etc/hosts имеет запись для 127.0.0.1 localhost, которые предоставляют имя для хоста localhost
Ответ 3
Вы можете попробовать InetAddress.getCanonicalHostName()
JavaDocs для getCanonicalHostName() говорит
Получает полное доменное имя для этого IP-адреса. Метод наилучших усилий, то есть мы не сможем вернуть полное доменное имя в зависимости от базовой конфигурации системы.
Ответ 4
У вас действительно есть три варианта различной сложности и информационной ценности:
- На самом деле запустите команду hostname с помощью Runtime. Он довольно портативный и должен работать практически везде. (Возможно, не на мэйнфреймах IBM)
- Возьмите все доступные сетевые интерфейсы и получите их имена хостов. https://docs.oracle.com/javase/tutorial/networking/nifs/listing.html
- Задайте свойство среды или системы как значение имени хоста.
Как java -Dmy.hostname = hostname
...
Печальная часть заключается в том, что это не так просто в Spring XML.
Известно, что все другие варианты дают разную степень точности. Подобно 127.0.0.1, скорее всего, будет разрешено localhost или localhost.localdomain.
Ответ 5
Кроме того, вы можете запустить команду linux linux с использованием Java Runtime, код должен выглядеть примерно так:
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();
Ответ 6
Я считаю, что Java по-прежнему вызывает родное gethostname()
, но не может сказать, почему это не удается.
Для Linux вы можете попробовать эту альтернативу:
String hostname = new String(Files.readAllBytes(Paths.get("/proc/sys/kernel/hostname")), StandardCharsets.US_ASCII);
Ответ 7
Поскольку мой комментарий потерялся в потоке, попробуйте
<bean id="hostname" class="com.amazonaws.util.EC2MetadataUtils" factory-method="getLocalHostName()">
Посмотрите на документацию Amazon, если результат не соответствует вашим потребностям.
Ответ 8
Я могу лучше определить свойство в вашем файле.properties для имени хоста.
hostname=myserver.mydomain.com
И используйте его в своем приложении. Этот путь не кодируется. Это также позволяет избежать зависимости от конфигурации операционной системы, которая может быть изменена без внимания.
Ответ 9
InetAddress в Java 8 имел ошибку в отношении разрешения имени хоста. Об ошибке сообщалось в версии 8u20 и с тех пор исправлено. Убедитесь, что вы не используете эту версию. Если нет, то с помощью InetAddress.getLocalHost().getHostName()
предоставит вам имя хоста.
Также я предлагаю настроить статическое имя хоста на экземпляре AWS.
- Обновить /etc/hosts
- Обновить /etc/hostname
- Запустить
hostname
чтобы проверить имя хоста - Перезагрузите и проверьте сохраненное имя хоста
Это должно позволить вам прочитать имя хоста из файла, если это необходимо.
Кроме того, если команда hostname
дает правильный результат, используйте метод exec в классе Runtime для выполнения команды и прочитайте InputStream, чтобы получить ответ.
PS: Вы можете использовать InetAddress.getLocalHost().isLoopbackAddress()
чтобы проверить, является ли адрес LoopbackAddress, а затем использовать метод резервного копирования.