I'm attempting to use the DNSJava library from clojure. I attempt the following:
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
Great! I know from the docs that I should be able to use .getStrings to get the content of the record.
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 tells me this can be solved via type hints:
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)
Huh. At I've search Google further, and read the full page on interop, but I'm not having any luck.
Looking at the source for TXTRecord I see that it extends TXTBase which is an abstract class where getStrings is implemented. Since TXTRecord extends it, I should have access to getStrings through that (and I went so far as to write a Java program to verify it.
Does anyone know how I can access this via Clojure?
EDIT Working java program
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));
}
}
}
}
TXTBaseis not declared aspublic. So I don't know why you'd have access to any methods declared on that class outside theorg.xbill.dnspackage. And that's exactly what the exception message hints at -- "Can't call public method on non-public class" (emphasis added). Could you add the Java program that works so we can compare with the Clojure version, please? - Nathan Davis