[英]In Java 8, how do I get my hostname without hard-coding it in my environment?
We just upgraded to Java 8 on Amazon Linux. 我们刚刚在Amazon Linux上升级到Java 8。 We are using Spring 4.3.8.RELEASE.
我们正在使用Spring 4.3.8.RELEASE。 It used to be that we could get our machine hostname by setting up beans in our application context file like so ...
过去我们可以通过在应用程序上下文文件中设置bean来获取我们的机器主机名,就像这样...
<bean id="localhostInetAddress" class="java.net.InetAddress" factory-method="getLocalHost" />
<bean id="hostname" factory-bean="localhostInetAddress" factory-method="getHostName" />
But with Java 8, the bean "hostname" now contains the string 但是对于Java 8,bean“hostname”现在包含字符串
localhost
Before Java 8, it used to contain the "hostname" value as run on the command line, which is 在Java 8之前,它曾用于包含在命令行上运行的“hostname”值,即
[myuser@machine1 ~]$ hostname
machine1.mydomain.org
How can I reconfigure our bean so that it gets the hostname that the command line lists out? 如何重新配置我们的bean以便它获取命令行列出的主机名? I don't want to hard-code anything anywhere.
我不想在任何地方硬编码。
From InetAddress java 8 is not getting the hostname : 从InetAddress java 8获取主机名 :
There was similar bug fired in JDK.
在JDK中发生了类似的错误。
What I understand is that they changed default resolution process.
据我所知,他们改变了默认解析过程。
They honor configuration in /etc/nsswitch.conf where hosts are configured for /etc/hosts that gives it main priority for name resolution.
他们尊重/etc/nsswitch.conf中的配置,其中为/ etc / hosts配置了主机,为其提供了名称解析的主要优先级。
Usually /etc/hosts has record for 127.0.0.1 localhost that provide name for host localhost
通常/ etc / hosts具有为主机localhost提供名称的127.0.0.1 localhost的记录
You could try InetAddress.getCanonicalHostName()
你可以尝试
InetAddress.getCanonicalHostName()
The JavaDocs for getCanonicalHostName() says getCanonicalHostName()的JavaDocs说
Gets the fully qualified domain name for this IP address.
获取此IP地址的完全限定域名。 Best effort method, meaning we may not be able to return the FQDN depending on the underlying system configuration.
尽力而为方法,这意味着我们可能无法返回FQDN,具体取决于底层系统配置。
You really have three options of differing complexity and information value: 您确实有三种不同复杂性和信息价值的选择:
hostname
... hostname
... Sad part is that it's not that straightforward in Spring XML. 可悲的是,它在Spring XML中并不那么简单。
All other options are known to give varying degrees of accuracy. 众所周知,所有其他选项都具有不同程度的准确性。 Like 127.0.0.1 will likely resolve to localhost or localhost.localdomain .
像127.0.0.1可能会解析为localhost或localhost.localdomain 。
Alternatively, you can run the hostname linux command using Java Runtime, code should be something like below: 或者,您可以使用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();
I believe Java still calls the native gethostname()
, but couldn't say why this fails. 我相信Java仍然会调用本机
gethostname()
,但不能说为什么会失败。
For Linux, you could try this alternative: 对于Linux,您可以尝试这种替代方案:
String hostname = new String(Files.readAllBytes(Paths.get("/proc/sys/kernel/hostname")), StandardCharsets.US_ASCII);
Since my comment got lost in the stream, please try 由于我的评论在流中丢失了,请尝试
<bean id="hostname" class="com.amazonaws.util.EC2MetadataUtils" factory-method="getLocalHostName()">
Have a look at Amazon's documemtation if the result does not suits your needs. 如果结果不符合您的需求,请查看亚马逊的文档 。
I can be better to define a property in your .properties file for hostname like. 我可以更好地在.properties文件中为hostname定义一个属性。
hostname=myserver.mydomain.com
And use it in your application. 并在您的应用程序中使用它。 This way is not harcoded.
这种方式没有被编码。 It also avoid dependency to operating system config which can be changed without attention.
它还避免了对操作系统配置的依赖,操作系统配置可以在不注意的情
InetAddress in Java 8 had a bug regarding the resolution of hostname. Java 8中的InetAddress有关于主机名解析的错误 。 The bug was reported in version 8u20 and has been fixed since then.
该错误在版本8u20中报告,并且从那时起已经修复。 Please check that you are not on this version.
请检查您是否使用此版本。 If not, then using
InetAddress.getLocalHost().getHostName()
will give you the hostname. 如果没有,那么使用
InetAddress.getLocalHost().getHostName()
将为您提供主机名。
Also I suggest, setting up a static hostname on the AWS instance. 我还建议在AWS实例上设置静态主机名 。
hostname
to check the hostname hostname
以检查主机名 This should allow you to read the hostname from the file if required. 这应该允许您在需要时从文件中读取主机名。
Also, if hostname
command is giving the correct result, then use exec method in Runtime class to execute the command and the read the InputStream to get the response. 此外,如果
hostname
命令给出正确的结果,则在Runtime类中使用exec方法执行命令并读取InputStream以获取响应。
PS: You can use InetAddress.getLocalHost().isLoopbackAddress()
to check whether the address is a LoopbackAddress and then use a fallback method. PS:您可以使用
InetAddress.getLocalHost().isLoopbackAddress()
来检查地址是否为LoopbackAddress,然后使用回退方法。
There are a similar question in the OpenJDK bugs OpenJDK中有一个类似的问题
The newer calls respect the localhosts /etc/nsswitch.conf configuration files.
较新的调用遵循localhosts /etc/nsswitch.conf配置文件。 In the case of this machine that file tells these calls to look in files before referencing other naming services.
在这台机器的情况下,该文件告诉这些调用在引用其他命名服务之前查看文件。
Since the /etc/hosts file contains an explicit mapping for this hostname / IP combination, that is what is returned.
由于/ etc / hosts文件包含此主机名/ IP组合的显式映射,因此返回的内容。
In the older JDK's the gethostbyname actually ignored the local machines settings and immediately delegated to the naming service.
在较旧的JDK中,gethostbyname实际上忽略了本地计算机设置并立即委托给命名服务。
You can always use the Runtime
class for that : 您始终可以使用
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.