【发布时间】:2016-05-03 03:14:18
【问题描述】:
我正在尝试使用 clojure 中的 DNSJava 库。我尝试以下方法:
dmarced.dns> (def results (.run (Lookup. "google.com" Type/TXT)))
#'dmarced.dns/results
dmarced.dns> (def r (get results 0))
#'dmarced.dns/r
dmarced.dns> r
#object[org.xbill.DNS.TXTRecord 0x687a3556 "google.com.\t\t3599\tIN\tTXT\t\"v=spf1 include:_spf.google.com ~all\""]
dmarced.dns> (class r)
org.xbill.DNS.TXTRecord
dmarced.dns> (instance? TXTRecord r)
true
太棒了!我从docs 知道我应该可以使用 .getStrings 来获取记录的内容。
dmarced.dns> (.getStrings r)
Reflection warning, *cider-repl dmarced*:150:13 - reference to field getStrings can't be resolved.
IllegalArgumentException Can't call public method of non-public class: public java.util.List org.xbill.DNS.TXTBase.getStrings() clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:88)
Ok quick google 告诉我这可以通过类型提示来解决:
dmarced.dns> (.getStrings ^TXTRecord r)
Reflection warning, *cider-repl dmarced*:153:13 - call to method getStrings on org.xbill.DNS.TXTRecord can't be resolved (argument types: ).
IllegalArgumentException Can't call public method of non-public class: public java.util.List org.xbill.DNS.TXTBase.getStrings() clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:88)
嗯。在我进一步搜索谷歌,并阅读interop 上的完整页面,但我没有任何运气。
查看TXTRecord 的源代码,我发现它扩展了TXTBase,这是一个实现getStrings 的抽象类。由于 TXTRecord 扩展了它,我应该可以通过它访问 getStrings(我什至编写了一个 Java 程序来验证它。
有人知道我如何通过 Clojure 访问它吗?
编辑工作的java程序
import org.xbill.DNS.*;
class Main {
public static void main(String [] args) throws TextParseException {
Lookup l = new Lookup("google.com", Type.TXT);
Record [] rs = l.run();
for(int i = 0; i < rs.length; i++) {
TXTRecord tr = (TXTRecord)rs[i];
for(int j = 0; j < tr.getStrings().size(); j ++) {
System.out.println(tr.getStrings().get(j));
}
}
}
}
【问题讨论】:
-
好吧,
TXTBase没有声明为public。所以我不知道为什么你可以访问在org.xbill.dns包之外的那个类上声明的任何方法。这正是异常消息所暗示的内容——“不能在 non-public 类上调用公共方法”(添加了重点)。请您添加有效的 Java 程序,以便我们与 Clojure 版本进行比较,好吗? -
已添加。两者都使用 dnsjava 2.1.7 off maven。如果需要,我可以提供 gradle 和 project.clj 文件。
标签: clojure clojure-java-interop