我们刚刚在Amazon Linux上升级到Java 8。我们正在使用Spring 4.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“hostname”现在包含字符串
localhost
在Java 8之前,它曾用于包含在命令行上运行的“hostname”值,即
[myuser@machine1 ~]$ hostname
machine1.mydomain.org
如何重新配置我们的bean,以便它获取命令行列出的主机名?我不想在任何地方硬编码。
答案 0 :(得分:4)
来自InetAddress java 8 is not getting the hostname:
在JDK中发生了类似的错误。
据我所知,他们改变了默认解决方案。
他们尊重/etc/nsswitch.conf中的配置,其中为/ etc / hosts配置了主机,为其提供了名称解析的主要优先级。
通常/ etc / hosts有127.0.0.1 localhost的记录,它提供了host localhost的名称
答案 1 :(得分:2)
您可以尝试InetAddress.getCanonicalHostName()
getCanonicalHostName()的JavaDocs说
获取此IP地址的完全限定域名。尽力而为方法,这意味着我们可能无法返回FQDN,具体取决于底层系统配置。
答案 2 :(得分:2)
您确实有三种不同复杂性和信息价值的选项:
hostname
... 可悲的是,它在Spring XML中并不那么简单。
众所周知,所有其他选项都具有不同程度的准确性。 与 127.0.0.1 一样,可能会解析为 localhost 或 localhost.localdomain 。
答案 3 :(得分:2)
或者,您可以使用Java Runtime运行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();
答案 4 :(得分:2)
我相信Java仍然会调用原生gethostname()
,但无法说明为什么会失败。
对于Linux,您可以尝试以下方法:
String hostname = new String(Files.readAllBytes(Paths.get("/proc/sys/kernel/hostname")), StandardCharsets.US_ASCII);
答案 5 :(得分:2)
由于我的评论在流中丢失了,请尝试
<bean id="hostname" class="com.amazonaws.util.EC2MetadataUtils" factory-method="getLocalHostName()">
如果结果不符合您的需求,请查看Amazon's documemtation。
答案 6 :(得分:2)
我可以更好地在.properties文件中为hostname定义一个属性,如。
hostname=myserver.mydomain.com
并在您的应用程序中使用它。这种方式没有被编码。它还避免了对操作系统配置的依赖,操作系统配置可以在没有注意的情况下进行更改
答案 7 :(得分:2)
Java 8中的InetAddress有关于主机名解析的bug。该错误在版本8u20中报告,并且从那时起已经修复。请检查您是否使用此版本。如果没有,那么使用InetAddress.getLocalHost().getHostName()
将为您提供主机名。
我还建议在AWS实例上设置static hostname。
hostname
以检查主机名如果需要,这应该允许您从文件中读取主机名。
此外,如果hostname
命令给出正确的结果,则使用exec method in Runtime class执行命令并读取InputStream以获得响应。
PS:您可以使用InetAddress.getLocalHost().isLoopbackAddress()
检查地址是否为LoopbackAddress,然后使用回退方法。
答案 8 :(得分:0)
较新的调用遵循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
那样推荐