Menu

#51 Type conversion error in version 2.1.7, in org.xbill.DNS.SetResponse.getNS(SetResponse.java:184)

None
closed
nobody
None
5
2019-05-18
2015-07-02
No

Exception in thread "main" java.lang.ClassCastException: java.util.ArrayList cannot be cast to org.xbill.DNS.RRset at org.xbill.DNS.SetResponse.getNS(SetResponse.java:184)

This happens after trying to extract NS records after a query with a deferral result. Example code to reproduce the problem:

    String name = "com.";
    String lookupHost = "h.root-servers.net.";

    Resolver resolver = new SimpleResolver(lookupHost);
    resolver.setTimeout(5);

    Lookup lookup = new Lookup(name, Type.NS);

    Cache cache = new Cache();
    lookup.setCache(cache);
    lookup.setResolver(resolver);
    lookup.setCredibility(Credibility.NONAUTH_AUTHORITY);

    Record[] records = lookup.run();

    SetResponse sr = cache.lookupRecords(new Name(name), Type.NS, Credibility.ANY);
    RRset nsSet = sr.getNS(); // <-- EXCEPTION HERE

    Iterator it = nsSet.rrs();
    while (it.hasNext())
        System.out.println(it.next().toString());

Discussion

  • Brian Wellington

    There are a number of problems with this code.

    The main problem here is that you didn't verify that the response was a referral before calling getNS(). sr.isDelegation() returns false, while sr.isSuccessful() returns true, and getNS() is only supposed to be used when isDelegation() is true.

    Also, you're passing Credibility.ANY, which means that any data in the cache is sufficient. The cache contains the NS records added by the referral response, so those are considered good enough, and returned as a successful answer.

    If the code is changed to pass Credibility.NORMAL, it should work, although it doesn't. As for why that's the case, I expect that the cache is incorrectly using credibility levels somewhere, and that's causing the referral to be treated as a more authoritative answer than it is. This might be fixable, but fixing it without breaking anything else is likely impossible.

    I'd recommend changing your code to check the type of response before calling getNS(); calling answers() should give you the NS records in this case.

     
  • Ingo

    Ingo - 2019-05-18
    • status: open --> closed
    • Group: -->
     
  • Ingo

    Ingo - 2019-05-18

    If you still think this is an issue/use case, please create a pull request on dnsjava's new home at Github: https://github.com/dnsjava/dnsjava