#navi_header|Java| [[1346]] ではSocket, InetAddressによるDNS名前解決を追ったが、最終的に取得できるのはIPアドレスのみだった。 DNSのレコード単位で問い合わせを行ったり、DNSサーバを指定したい場合は、JNDIのDNSサービスプロバイダを利用できる。 この記事では、JNDIのDNSサービスプロバイダを使ったDNSサーバ問い合わせ処理のサンプルコードを紹介する。 ---- サンプルコードの実行環境 : Win7 64bit + Oracle JDK 1.8.0.31 JNDIで使えるDNSサービスプロバイダの実装(Javaソース): - https://github.com/openjdk-mirror/jdk7u-jdk/tree/master/src/share/classes/com/sun/jndi/dns 参考資料: - JNDIインタフェース関連APIおよび開発者ガイド -- JDK8 : https://docs.oracle.com/javase/jp/8/technotes/guides/jndi/index.html - JNDI/DNSサービス・プロバイダ -- JDK8 : https://docs.oracle.com/javase/jp/8/technotes/guides/jndi/jndi-dns.html -- JDK7 : https://docs.oracle.com/javase/jp/7/technotes/guides/jndi/jndi-dns.html -- JDK6 : https://docs.oracle.com/javase/jp/6/technotes/guides/jndi/jndi-dns.html - (英語版) -- http://docs.oracle.com/javase/8/docs/technotes/guides/jndi/jndi-dns.html -- http://docs.oracle.com/javase/7/docs/technotes/guides/jndi/jndi-dns.html -- http://docs.oracle.com/javase/6/docs/technotes/guides/jndi/jndi-dns.html - 今さら人に訊けない JNDI: 第 1 回 「JNDI ってなんだっけ?」 -- http://www.ibm.com/developerworks/jp/websphere/library/was/was_jndi/1.html ---- * サンプルコード ** JndiDnsTest1.java : OSのDNSサーバ設定を使用する。 JndiDnsTest1.java: "google.com" を取得 #code|java|> 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()); } } } ||< 実行結果: #pre||> 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"); 実行結果: #pre||> 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サーバを指定 JndiDnsTest2.java: DNSサーバのアドレスは、ご利用のプロバイダのアドレスなどに書き換えて試して下さい。 #code|java|> 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()); } } } ||< 実行結果: #pre||> 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" }); 実行結果: #pre||> 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. ||< * Context.INITIAL_CONTEXT_FACTORY に指定する値は "com.sun.jndi.dns.DnsContextFactory" と "com.example.jndi.dns.DnsContextFactory" のどちらが正? 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 #navi_footer|Java|