Java/Socket, InetAddressにおけるDNS名前解決の仕組みと networkaddress.cache.ttl ではSocket, InetAddressによるDNS名前解決を追ったが、最終的に取得できるのはIPアドレスのみだった。
DNSのレコード単位で問い合わせを行ったり、DNSサーバを指定したい場合は、JNDIのDNSサービスプロバイダを利用できる。
この記事では、JNDIのDNSサービスプロバイダを使ったDNSサーバ問い合わせ処理のサンプルコードを紹介する。
サンプルコードの実行環境 : Win7 64bit + Oracle JDK 1.8.0.31
JNDIで使えるDNSサービスプロバイダの実装(Javaソース):
参考資料:
JndiDnsTest1.java: "google.com" を取得
import java.util.Properties; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; public class JndiDnsTest1 { public static void main(String[] args) throws Exception { // see: http://www.ibm.com/developerworks/jp/websphere/library/was/was_jndi/1.html Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory"); DirContext ictx = new InitialDirContext(env); Attributes attrs = ictx.getAttributes("google.com"); NamingEnumeration<?> allAttr = attrs.getAll(); while (allAttr.hasMore()) { Attribute attr = (Attribute) allAttr.next(); System.out.println("Attribute: " + attr.getID()); NamingEnumeration<?> values = attr.getAll(); while (values.hasMore()) System.out.println("Value: " + values.next()); } } }
実行結果:
Attribute: A Value: 216.58.220.174 Attribute: NS Value: ns3.google.com. Value: ns2.google.com. Value: ns4.google.com. Value: ns1.google.com. Attribute: MX Value: 30 alt2.aspmx.l.google.com. Value: 40 alt3.aspmx.l.google.com. Value: 20 alt1.aspmx.l.google.com. Value: 10 aspmx.l.google.com. Value: 50 alt4.aspmx.l.google.com.
→ getAttributes()の引数を "www.google.com" にしてみる:
Attributes attrs = ictx.getAttributes("www.google.com");
実行結果:
Attribute: A Value: 173.194.38.208 Value: 173.194.38.210 Value: 173.194.38.211 Value: 173.194.38.212 Value: 173.194.38.209
→ AレコードとMXレコードだけに絞ってみる。
Attributes attrs = ictx.getAttributes("google.com", new String[] { "MX", "A" });
※やってみたが、取れたり取れなかったりしたので、スキップ。
JndiDnsTest2.java: DNSサーバのアドレスは、ご利用のプロバイダのアドレスなどに書き換えて試して下さい。
package jdk8scratch; import java.util.Properties; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; public class JndiDnsTest2 { public static void main(String[] args) throws Exception { // see: http://www.ibm.com/developerworks/jp/websphere/library/was/was_jndi/1.html Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory"); env.put(Context.PROVIDER_URL, "dns://xxx.yyy.zzz.www"); DirContext ictx = new InitialDirContext(env); Attributes attrs = ictx.getAttributes("google.com"); NamingEnumeration<?> allAttr = attrs.getAll(); while (allAttr.hasMore()) { Attribute attr = (Attribute) allAttr.next(); System.out.println("Attribute: " + attr.getID()); NamingEnumeration<?> values = attr.getAll(); while (values.hasMore()) System.out.println("Value: " + values.next()); } } }
実行結果:
Attribute: AAAA Value: 2404:6800:4004:807::1002 Attribute: A Value: 173.194.126.165 Value: 173.194.126.164 Value: 173.194.126.169 Value: 173.194.126.168 Value: 173.194.126.162 Value: 173.194.126.160 Value: 173.194.126.163 Value: 173.194.126.166 Value: 173.194.126.161 Value: 173.194.126.167 Value: 173.194.126.174 Attribute: NS Value: ns3.google.com. Value: ns1.google.com. Value: ns2.google.com. Value: ns4.google.com. Attribute: MX Value: 30 alt2.aspmx.l.google.com. Value: 50 alt4.aspmx.l.google.com. Value: 40 alt3.aspmx.l.google.com. Value: 20 alt1.aspmx.l.google.com. Value: 10 aspmx.l.google.com.
→ NSとAAAAレコードだけに絞ってみる。
Attributes attrs = ictx.getAttributes("google.com", new String[] { "NS", "AAAA" });
実行結果:
Attribute: AAAA Value: 2404:6800:4004:812::200e Attribute: NS Value: ns4.google.com. Value: ns1.google.com. Value: ns3.google.com. Value: ns2.google.com.
2015-02-07時点:
JDK7,8の日本語/英語ドキュメント:
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.example.jndi.dns.DnsContextFactory"); ^^^^^^^^^^^
JDK6の日本語/英語ドキュメント:
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory"); ^^^^^^^
正解:"com.sun.jndi.dns.DnsContextFactory"の方。JDK8で "com.example"にしたら以下の例外発生:
Caused by: java.lang.ClassNotFoundException: com.example.jndi.dns.DnsContextFactory
コメント