【问题标题】:java.net.UnknownHostException: java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)java.net.UnknownHostException:java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(本机方法)
【发布时间】:2021-08-10 10:14:03
【问题描述】:

我有这个有效的代码(有一个警告)。

import java.io.*;
import java.util.ArrayList;
import java.util.List;

import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicNameValuePair;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.json.JSONArray;
import org.json.JSONObject;

import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

/**
*/
public class PorkbunDynDNSClient
{
    static String endpoint = "";
    static String apikey = "";
    static String secretapikey = "";

    private static String getLocalIPv6Address() throws IOException
    {
        InetAddress inetAddress = null;
        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
    outer:
        while (networkInterfaces.hasMoreElements())
        {
            Enumeration<InetAddress> inetAds = networkInterfaces.nextElement().getInetAddresses();
            while (inetAds.hasMoreElements())
            {
                inetAddress = inetAds.nextElement();
                //Check if it‘s ipv6 address and reserved address
                if (inetAddress instanceof Inet6Address && !isReservedAddr(inetAddress))
                {
                    break outer;
                }
            }
        }

        String ipAddr = inetAddress.getHostAddress();
        // Filter network card No
        int index = ipAddr.indexOf("%");
        if (index > 0) {
            ipAddr = ipAddr.substring(0, index);
        }

        return ipAddr;
    }

    /**
     * Check if it‘s "local address" or "link local address" or
     * "loopbackaddress"
     *
     * @param ip address
     *
     * @return result
     */
    private static boolean isReservedAddr(InetAddress inetAddr)
    {
        if (inetAddr.isAnyLocalAddress() || inetAddr.isLinkLocalAddress() || inetAddr.isLoopbackAddress())
        {
            return true;
        }

        return false;
    }

    public static void main(String[] args)
    {
        if (args.length < 3)
        {
            System.out.println("Required arguments are domain, subdomain, record type\nExample 1: yourdomain.com \"www\" A\nExample 2: yourdomain.com \"\" A");
            return;
        }

        String domainName = args[0].toLowerCase();
        String subDomain = args[1].toLowerCase();
        String recordType = args[2].toUpperCase();

        String hostName = domainName;
        if(subDomain.length() > 0)
            hostName = subDomain+"."+domainName;

        // read config file
        try
        {
            File config = new File("./config.json");
            FileInputStream fis = new FileInputStream(config);
            byte[] data = new byte[(int) config.length()];
            fis.read(data);
            fis.close();
            String configStr = new String(data, "UTF-8");

            JSONObject configObj = new JSONObject(configStr);

            endpoint = configObj.get("endpoint").toString();
            apikey = configObj.get("apikey").toString();
            secretapikey = configObj.get("secretapikey").toString();

            System.out.println("API endpoint: "+endpoint);
            System.out.println("apikey: "+apikey);
            System.out.println("secretapikey: "+secretapikey);
        }
        catch(Exception e)
        {
            e.printStackTrace();
            System.exit(0);
        }

        String realIp = "";

        // ping API to get current IP
        if(recordType.equals("AAAA"))
        {
            try
            {
                realIp = getLocalIPv6Address().toLowerCase();
                System.out.println("Detected current IPv6 as "+realIp+".");
            }
            catch(Exception e) 
            {
                e.printStackTrace();
                System.out.println("Could not get IPv6 from local computer.");
                System.exit(0);
            }
        } else {
            JSONObject pingResult = ping();
            if(!pingResult.get("status").toString().equals("SUCCESS"))
            {
                System.out.println("Could not get ping result from API.");
                System.out.println(pingResult);
                System.exit(0);
            }
            System.out.println(pingResult);
            realIp = pingResult.get("yourIp").toString().toLowerCase();
            System.out.println("Detected current IPv4 as "+realIp+".");
        }

        // get current records
        JSONObject retrieveResult = retrieve(domainName);
        if(!retrieveResult.get("status").toString().equals("SUCCESS"))
        {
            System.out.println("Could not get records from API.");
            System.out.println(retrieveResult);
            System.exit(0);
        }
        System.out.println(retrieveResult);
        JSONArray records = (JSONArray)retrieveResult.get("records");
        for(int i = 0; i < records.length(); i++)
        {
            JSONObject record = (JSONObject)records.get(i);
            String currentId = record.get("id").toString().toLowerCase();
            String currentName = record.get("name").toString().toLowerCase();
            String currentType = record.get("type").toString().toUpperCase();
            String currentContent = record.get("content").toString().toLowerCase();

            if(currentName.equals(hostName) && currentType.equals(recordType))
            {
                System.out.println(currentType+" record for "+currentName+" is currently "+currentContent+".");
                if(!currentContent.equals(realIp))
                {
                    System.out.println("Modifying current DNS record due to IP address mismatch.");

                    // edit record
                    JSONObject editResult = edit(domainName, currentId, subDomain, currentType, realIp, "300", "0");
                    if(!editResult.get("status").toString().equals("SUCCESS"))
                    {
                        System.out.println("Could not edit record via API.");
                        System.out.println(editResult);
                        System.exit(0);
                    }
                    System.out.println(editResult);
                }
            }
        }
    }

    static JSONObject edit(String domain, String id, String name, String type, String content, String ttl, String prio)
    {
        JSONObject data = new JSONObject();
        data.put("name", name);
        data.put("type", type);
        data.put("content", content);
        data.put("ttl", ttl);
        data.put("prio", prio);
        String commandEndpoint = endpoint+"/dns/edit/"+domain+"/"+id;
        JSONObject result = sendCommand(commandEndpoint, data);

        return(result);
    }

    static JSONObject retrieve(String domain)
    {
        JSONObject data = new JSONObject();
        String commandEndpoint = endpoint+"/dns/retrieve/"+domain;
        JSONObject result = sendCommand(commandEndpoint, data);

        return(result);
    }

    static JSONObject ping()
    {
        JSONObject data = new JSONObject();
        String commandEndpoint = endpoint+"/ping";
        JSONObject result = sendCommand(commandEndpoint, data);

        return(result);
    }

    static JSONObject sendCommand(String url, JSONObject data)
    {
        JSONObject result = null;

        data.put("secretapikey", secretapikey);
        data.put("apikey", apikey);

        try (final CloseableHttpClient httpclient = HttpClients.createDefault())
        {
                    final HttpPost httpPost = new HttpPost(url);

                StringEntity entity = new StringEntity(data.toString());
            httpPost.setEntity(entity);

                    try (final CloseableHttpResponse response = httpclient.execute(httpPost)) 
            {
                        System.out.println(response.getCode() + " " + response.getReasonPhrase());
                        final HttpEntity entity2 = response.getEntity();
                String responseString = EntityUtils.toString(entity2, "UTF-8");
                result = new JSONObject(responseString);

                        EntityUtils.consume(entity2);
                    }
            catch(Exception e) 
            {
                e.printStackTrace();
                return(null);
            }
        }
        catch(Exception e) 
        {
            e.printStackTrace();
            return(null);
        }

        return(result);
    }
}

此代码来自porkbun-dynamic-dns-java,当我登录时它在我的 Linux 上运行良好。

但是当我让这个脚本在启动时运行时,我得到了这个错误:

API endpoint: https://porkbun.com/api/json/v3
apikey: xxxxx
secretapikey: xxxxx
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
java.net.UnknownHostException: porkbun.com: Falha temporária na resolução de nome
    at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
    at java.base/java.net.InetAddress$PlatformNameService.lookupAllHostAddr(InetAddress.java:932)
    at java.base/java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1517)
    at java.base/java.net.InetAddress$NameServiceAddresses.get(InetAddress.java:851)
    at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1507)
    at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1366)
    at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1300)
    at org.apache.hc.client5.http.SystemDefaultDnsResolver.resolve(SystemDefaultDnsResolver.java:43)
    at org.apache.hc.client5.http.impl.io.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:118)
    at org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:409)
    at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.connectEndpoint(InternalExecRuntime.java:164)
    at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.connectEndpoint(InternalExecRuntime.java:174)
    at org.apache.hc.client5.http.impl.classic.ConnectExec.execute(ConnectExec.java:135)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
    at org.apache.hc.client5.http.impl.classic.ProtocolExec.execute(ProtocolExec.java:172)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
    at org.apache.hc.client5.http.impl.classic.HttpRequestRetryExec.execute(HttpRequestRetryExec.java:93)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
    at org.apache.hc.client5.http.impl.classic.ContentCompressionExec.execute(ContentCompressionExec.java:128)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
    at org.apache.hc.client5.http.impl.classic.RedirectExec.execute(RedirectExec.java:116)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:178)
    at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:75)
    at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:89)
    at PorkbunDynDNSClient.sendCommand(PorkbunDynDNSClient.java:239)
    at PorkbunDynDNSClient.ping(PorkbunDynDNSClient.java:220)
    at PorkbunDynDNSClient.main(PorkbunDynDNSClient.java:142)
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.json.JSONObject.get(String)" because "<local6>" is null
    at PorkbunDynDNSClient.main(PorkbunDynDNSClient.java:143)
API endpoint: https://porkbun.com/api/json/v3
apikey: xxxxx
secretapikey: xxxxx
Detected current IPv6 as 1xx.xxx.xxx.xxx.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
java.net.UnknownHostException: porkbun.com: Falha temporária na resolução de nome
    at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
    at java.base/java.net.InetAddress$PlatformNameService.lookupAllHostAddr(InetAddress.java:932)
    at java.base/java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1517)
    at java.base/java.net.InetAddress$NameServiceAddresses.get(InetAddress.java:851)
    at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1507)
    at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1366)
    at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1300)
    at org.apache.hc.client5.http.SystemDefaultDnsResolver.resolve(SystemDefaultDnsResolver.java:43)
    at org.apache.hc.client5.http.impl.io.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:118)
    at org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:409)
    at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.connectEndpoint(InternalExecRuntime.java:164)
    at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.connectEndpoint(InternalExecRuntime.java:174)
    at org.apache.hc.client5.http.impl.classic.ConnectExec.execute(ConnectExec.java:135)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
    at org.apache.hc.client5.http.impl.classic.ProtocolExec.execute(ProtocolExec.java:172)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
    at org.apache.hc.client5.http.impl.classic.HttpRequestRetryExec.execute(HttpRequestRetryExec.java:93)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
    at org.apache.hc.client5.http.impl.classic.ContentCompressionExec.execute(ContentCompressionExec.java:128)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
    at org.apache.hc.client5.http.impl.classic.RedirectExec.execute(RedirectExec.java:116)
    at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
    at org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:178)
    at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:75)
    at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:89)
    at PorkbunDynDNSClient.sendCommand(PorkbunDynDNSClient.java:239)
    at PorkbunDynDNSClient.retrieve(PorkbunDynDNSClient.java:211)
    at PorkbunDynDNSClient.main(PorkbunDynDNSClient.java:155)
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.json.JSONObject.get(String)" because "<local6>" is null
    at PorkbunDynDNSClient.main(PorkbunDynDNSClient.java:156)

我假设这是因为在启动时我仍然没有发布的 IPv6 地址。
我无法修复此错误。
有人可以帮忙吗?

【问题讨论】:

    标签: java linux dns ipv6


    【解决方案1】:

    我使用 systemd 功能完成了这项工作。
    我创建了一个/etc/systemd/system/ddns-AAAA.service,内容如下:

    [Unit]
    Description=DDNS AAAA record for domain.tld at Porkbun
    Wants=network.target
    After=network-online.target
    
    [Service]
    Type=oneshot
    User=joe
    ExecStart=/usr/local/bin/ddns-AAAA
    RemainAfterExit=yes
    Restart=on-failure
    RestartSec=10s
    StartLimitInterval=1min
    
    [Install]
    WantedBy=multi-user.target default.target
    Alias=ddns-AAAA.service
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-30
      • 2013-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多