[UPGRADES] Drop uk.nominet:dnsjnio

DNSJava from 3.5 onward allows already asynchronous request execution,
thus this external dependency, incompatible with DNSJava 3.5, can be dropped.
diff --git a/assemble/pom.xml b/assemble/pom.xml
index 45caa92..55f736a 100644
--- a/assemble/pom.xml
+++ b/assemble/pom.xml
@@ -43,10 +43,6 @@
             <artifactId>dnsjava</artifactId>
         </dependency>
         <dependency>
-            <groupId>uk.nominet</groupId>
-            <artifactId>dnsjnio</artifactId>
-        </dependency>
-        <dependency>
             <groupId>net.java.dev</groupId>
             <artifactId>jvyaml</artifactId>
         </dependency>
diff --git a/pom.xml b/pom.xml
index 95799a9..c1770e2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,11 +88,6 @@
                 <version>3.5.1</version>
             </dependency>
             <dependency>
-                <groupId>uk.nominet</groupId>
-                <artifactId>dnsjnio</artifactId>
-                <version>1.0.3</version>
-            </dependency>
-            <dependency>
                 <groupId>junit</groupId>
                 <artifactId>junit</artifactId>
                 <version>4.13.2</version>
diff --git a/resolver/pom.xml b/resolver/pom.xml
index 2138ecb..d78ec89 100644
--- a/resolver/pom.xml
+++ b/resolver/pom.xml
@@ -46,10 +46,6 @@
             <artifactId>dnsjava</artifactId>
         </dependency>
         <dependency>
-            <groupId>uk.nominet</groupId>
-            <artifactId>dnsjnio</artifactId>
-        </dependency>
-        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>
diff --git a/resolver/src/main/java/org/apache/james/jspf/core/DNSService.java b/resolver/src/main/java/org/apache/james/jspf/core/DNSService.java
index fb86a20..82935d7 100644
--- a/resolver/src/main/java/org/apache/james/jspf/core/DNSService.java
+++ b/resolver/src/main/java/org/apache/james/jspf/core/DNSService.java
@@ -22,6 +22,8 @@
 import org.apache.james.jspf.core.exceptions.TimeoutException;
 
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
 
 /**
  * Interface which should be used to access all necassary DNS-Records
@@ -38,6 +40,8 @@
      */
     public List<String> getRecords(DNSRequest request) throws TimeoutException;
 
+    CompletionStage<List<String>> getRecordsAsync(DNSRequest request);
+
     /**
      * Try to get all domain names for the running host
      * 
diff --git a/resolver/src/main/java/org/apache/james/jspf/executor/AsynchronousSPFExecutor.java b/resolver/src/main/java/org/apache/james/jspf/executor/AsynchronousSPFExecutor.java
new file mode 100644
index 0000000..ac8836d
--- /dev/null
+++ b/resolver/src/main/java/org/apache/james/jspf/executor/AsynchronousSPFExecutor.java
@@ -0,0 +1,101 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jspf.executor;
+
+import org.apache.james.jspf.core.DNSLookupContinuation;
+import org.apache.james.jspf.core.DNSResponse;
+import org.apache.james.jspf.core.DNSService;
+import org.apache.james.jspf.core.SPFChecker;
+import org.apache.james.jspf.core.SPFCheckerExceptionCatcher;
+import org.apache.james.jspf.core.SPFSession;
+import org.apache.james.jspf.core.exceptions.NeutralException;
+import org.apache.james.jspf.core.exceptions.NoneException;
+import org.apache.james.jspf.core.exceptions.PermErrorException;
+import org.apache.james.jspf.core.exceptions.SPFResultException;
+import org.apache.james.jspf.core.exceptions.TempErrorException;
+import org.apache.james.jspf.core.exceptions.TimeoutException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Synchronous implementation of SPFExecuter. All queries will get executed synchronously
+ */
+public class AsynchronousSPFExecutor implements SPFExecutor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(AsynchronousSPFExecutor.class);
+
+    private DNSService dnsProbe;
+
+    public AsynchronousSPFExecutor(DNSService service) {
+        this.dnsProbe = service;
+    }
+
+    /**
+     * @see SPFExecutor#execute(SPFSession, FutureSPFResult)
+     */
+    public void execute(SPFSession session, FutureSPFResult result) {
+        SPFChecker checker;
+        while ((checker = session.popChecker()) != null) {
+            // only execute checkers we added (better recursivity)
+            LOGGER.debug("Executing checker: {}", checker);
+            final SPFChecker finalChecker = checker;
+            try {
+                final DNSLookupContinuation cont = checker.checkSPF(session);
+                // if the checker returns a continuation we return it
+                dnsProbe.getRecordsAsync(cont.getRequest())
+                    .thenAccept(results -> {
+                        try {
+                            cont.getListener().onDNSResponse(new DNSResponse(results), session);
+                        } catch (PermErrorException | NoneException | TempErrorException | NeutralException e) {
+                            handleError(session, finalChecker, e);
+                        }
+                    })
+                    .exceptionally(e -> {
+                        if (e instanceof TimeoutException) {
+                            try {
+                                cont.getListener().onDNSResponse(new DNSResponse((TimeoutException) e), session);
+                            } catch (PermErrorException | NoneException | TempErrorException | NeutralException ex2) {
+                                handleError(session, finalChecker, ex2);
+                            }
+                        }
+                        return null;
+                    });
+            } catch (Exception e) {
+                handleError(session, checker, e);
+            }
+        }
+        result.setSPFResult(session);
+    }
+
+    private void handleError(SPFSession session, SPFChecker checker, Exception e) {
+        while (e != null) {
+            while (checker == null || !(checker instanceof SPFCheckerExceptionCatcher)) {
+                checker = session.popChecker();
+            }
+            try {
+                ((SPFCheckerExceptionCatcher) checker).onException(e, session);
+                e = null;
+            } catch (SPFResultException ex) {
+                e = ex;
+            } finally {
+                checker = null;
+            }
+        }
+    }
+}
diff --git a/resolver/src/main/java/org/apache/james/jspf/impl/DNSJnioAsynchService.java b/resolver/src/main/java/org/apache/james/jspf/impl/DNSJnioAsynchService.java
deleted file mode 100644
index e2dc4e2..0000000
--- a/resolver/src/main/java/org/apache/james/jspf/impl/DNSJnioAsynchService.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/****************************************************************

- * Licensed to the Apache Software Foundation (ASF) under one   *

- * or more contributor license agreements.  See the NOTICE file *

- * distributed with this work for additional information        *

- * regarding copyright ownership.  The ASF licenses this file   *

- * to you under the Apache License, Version 2.0 (the            *

- * "License"); you may not use this file except in compliance   *

- * with the License.  You may obtain a copy of the License at   *

- *                                                              *

- *   http://www.apache.org/licenses/LICENSE-2.0                 *

- *                                                              *

- * Unless required by applicable law or agreed to in writing,   *

- * software distributed under the License is distributed on an  *

- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *

- * KIND, either express or implied.  See the License for the    *

- * specific language governing permissions and limitations      *

- * under the License.                                           *

- ****************************************************************/

-

-package org.apache.james.jspf.impl;

-

-import java.util.List;

-

-import org.apache.james.jspf.core.DNSRequest;

-import org.apache.james.jspf.core.exceptions.TimeoutException;

-import org.apache.james.jspf.executor.DNSAsynchLookupService;

-import org.apache.james.jspf.executor.IResponse;

-import org.apache.james.jspf.executor.IResponseQueue;

-import org.xbill.DNS.DClass;

-import org.xbill.DNS.Message;

-import org.xbill.DNS.Name;

-import org.xbill.DNS.Record;

-import org.xbill.DNS.Resolver;

-import org.xbill.DNS.TextParseException;

-import org.xbill.DNS.Type;

-

-import uk.nominet.dnsjnio.ExtendedNonblockingResolver;

-import uk.nominet.dnsjnio.LookupAsynch;

-

-public class DNSJnioAsynchService implements DNSAsynchLookupService {

-

-    private ExtendedNonblockingResolver resolver;

-

-    public DNSJnioAsynchService(ExtendedNonblockingResolver resolver) {

-        this.resolver = resolver;

-        LookupAsynch.setDefaultResolver(resolver);

-    }

-    

-    /**

-     * Set the timeout for the resolvers

-     * @param timeout

-     */

-    public synchronized void setTimeout(int timeout) {

-        Resolver[] res = resolver.getResolvers();

-        for (int i = 0; i < res.length; i++) {

-            res[i].setTimeout(timeout);

-        }

-    }

-    

-    /**

-     * @see org.apache.james.jspf.executor.DNSAsynchLookupService#getRecordsAsynch(org.apache.james.jspf.core.DNSRequest, int, org.apache.james.jspf.executor.IResponseQueue)

-     */

-    public void getRecordsAsynch(DNSRequest request, int id,

-            IResponseQueue responsePool) {

-        

-        Message message;

-        try {

-            message = makeQuery(request, id);

-            LookupAsynch la = new LookupAsynch(message.getQuestion().getName(), message.getQuestion().getType());

-            la.runAsynch(new Runnable() {

-

-                private IResponseQueue responsePool;

-                private Integer id;

-                private LookupAsynch lookup;

-

-                public void run() {

-                    responsePool.insertResponse(new IResponse() {

-

-                        public Exception getException() {

-                            if (lookup.getResult() == LookupAsynch.TRY_AGAIN) {

-                                return new TimeoutException(lookup.getErrorString());

-                            } else {

-                                return null;

-                            }

-                        }

-

-                        public Object getId() {

-                            return id;

-                        }

-

-                        public List<String> getValue() {

-                            return (DNSServiceXBillImpl.convertRecordsToList(lookup.getAnswers()));

-                        }

-                        

-                    });

-                }

-

-                public Runnable setResponsePool(LookupAsynch la, IResponseQueue responsePool,

-                        Integer integer) {

-                    this.lookup = la;

-                    this.responsePool = responsePool;

-                    this.id = integer;

-                    return this;

-                }

-                

-            }.setResponsePool(la, responsePool, new Integer(id)));

-            // this.resolver.sendAsync(message, new Integer(id), new ResponseQueueAdaptor(responsePool));

-        } catch (TextParseException e) {

-            // TODO Auto-generated catch block

-            e.printStackTrace();

-        }

-    }

-

-    private Message makeQuery(DNSRequest request, int id) throws TextParseException {

-        Name name = Name.fromString(request.getHostname(), Name.root);

-        

-        int type;

-        switch (request.getRecordType()) {

-            case DNSRequest.A: type = Type.A; break;

-            case DNSRequest.AAAA: type = Type.AAAA; break;

-            case DNSRequest.MX: type = Type.MX; break;

-            case DNSRequest.PTR: type = Type.PTR; break;

-            case DNSRequest.SPF: type = Type.SPF; break;

-            case DNSRequest.TXT: type = Type.TXT; break;

-            default: 

-                throw new UnsupportedOperationException("Unknown query type: "+request.getRecordType());

-        }

-        

-        Record question = Record.newRecord(name, type, DClass.ANY);

-        Message query = Message.newQuery(question);

-        query.getHeader().setID(id);

-        return query;

-    }

-}

diff --git a/resolver/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java b/resolver/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java
index 99c2690..7e15933 100644
--- a/resolver/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java
+++ b/resolver/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java
@@ -24,6 +24,8 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
 
 import org.apache.james.jspf.core.DNSRequest;
 import org.apache.james.jspf.core.DNSService;
@@ -35,6 +37,7 @@
 import org.xbill.DNS.ARecord;
 import org.xbill.DNS.Lookup;
 import org.xbill.DNS.MXRecord;
+import org.xbill.DNS.Name;
 import org.xbill.DNS.PTRRecord;
 import org.xbill.DNS.Record;
 import org.xbill.DNS.Resolver;
@@ -42,6 +45,7 @@
 import org.xbill.DNS.TXTRecord;
 import org.xbill.DNS.TextParseException;
 import org.xbill.DNS.Type;
+import org.xbill.DNS.lookup.LookupSession;
 
 /**
  * This class contains helper to get all neccassary DNS infos that are needed
@@ -167,7 +171,33 @@
             return null;
         }
     }
-    
+
+    @Override
+    public CompletionStage<List<String>> getRecordsAsync(DNSRequest request) {
+        String recordTypeDescription;
+        int dnsJavaType;
+        switch (request.getRecordType()) {
+            case DNSRequest.A: recordTypeDescription = "A"; dnsJavaType = Type.A; break;
+            case DNSRequest.AAAA: recordTypeDescription = "AAAA"; dnsJavaType = Type.AAAA; break;
+            case DNSRequest.MX: recordTypeDescription = "MX"; dnsJavaType = Type.MX; break;
+            case DNSRequest.PTR: recordTypeDescription = "PTR"; dnsJavaType = Type.PTR; break;
+            case DNSRequest.TXT: recordTypeDescription = "TXT"; dnsJavaType = Type.TXT; break;
+            case DNSRequest.SPF: recordTypeDescription= "SPF"; dnsJavaType = Type.SPF; break;
+            default: // TODO fail!
+                throw new IllegalArgumentException();
+        }
+        LOGGER.debug("Start {}-Record lookup for : {}", recordTypeDescription, request.getHostname());
+        final LookupSession lookupSession = LookupSession.defaultBuilder().build();
+
+        try {
+            return lookupSession.lookupAsync(Name.fromString(request.getHostname()), dnsJavaType)
+                .thenApply(result -> convertRecordsToList(result.getRecords().toArray(new Record[0])));
+        } catch (TextParseException e) {
+            LOGGER.debug("No {} Record found for host: {}", recordTypeDescription, request.getHostname());
+            throw new IllegalArgumentException();
+        }
+    }
+
     /**
      * Convert the given Record array to a List
      * 
diff --git a/resolver/src/main/java/org/apache/james/jspf/impl/SPF.java b/resolver/src/main/java/org/apache/james/jspf/impl/SPF.java
index 8f665ee..b9d8dfc 100644
--- a/resolver/src/main/java/org/apache/james/jspf/impl/SPF.java
+++ b/resolver/src/main/java/org/apache/james/jspf/impl/SPF.java
@@ -22,6 +22,7 @@
 
 import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.concurrent.CompletableFuture;
 
 import org.apache.james.jspf.core.DNSLookupContinuation;
 import org.apache.james.jspf.core.DNSService;
@@ -41,6 +42,7 @@
 import org.apache.james.jspf.core.exceptions.SPFErrorConstants;
 import org.apache.james.jspf.core.exceptions.SPFResultException;
 import org.apache.james.jspf.core.exceptions.TempErrorException;
+import org.apache.james.jspf.executor.AsynchronousSPFExecutor;
 import org.apache.james.jspf.executor.FutureSPFResult;
 import org.apache.james.jspf.executor.SPFExecutor;
 import org.apache.james.jspf.executor.SPFResult;
@@ -215,7 +217,7 @@
         this.parser = new RFC4408SPF1Parser(new DefaultTermsFactory(wiringService));
         // We add this after the parser creation because services cannot be null
         wiringService.put(SPFCheckEnabled.class, this);
-        this.executor = new SynchronousSPFExecutor(dnsProbe);
+        this.executor = new AsynchronousSPFExecutor(dnsProbe);
     }
     
     
diff --git a/resolver/src/test/java/org/apache/james/jspf/AbstractYamlTest.java b/resolver/src/test/java/org/apache/james/jspf/AbstractYamlTest.java
index fa6af83..fa977f8 100644
--- a/resolver/src/test/java/org/apache/james/jspf/AbstractYamlTest.java
+++ b/resolver/src/test/java/org/apache/james/jspf/AbstractYamlTest.java
@@ -27,6 +27,10 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 import org.apache.james.jspf.core.DNSRequest;
 import org.apache.james.jspf.core.DNSService;
@@ -40,7 +44,6 @@
 import org.apache.james.jspf.executor.SPFResult;
 import org.apache.james.jspf.executor.StagedMultipleSPFExecutor;
 import org.apache.james.jspf.executor.SynchronousSPFExecutor;
-import org.apache.james.jspf.impl.DNSJnioAsynchService;
 import org.apache.james.jspf.impl.DNSServiceAsynchSimulator;
 import org.apache.james.jspf.impl.DNSServiceXBillImpl;
 import org.apache.james.jspf.impl.DefaultTermsFactory;
@@ -51,7 +54,6 @@
 import org.apache.james.jspf.wiring.WiringService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.xbill.DNS.Cache;
 import org.xbill.DNS.DClass;
 import org.xbill.DNS.Lookup;
 import org.xbill.DNS.Name;
@@ -61,12 +63,10 @@
 
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
-import uk.nominet.dnsjnio.ExtendedNonblockingResolver;
-import uk.nominet.dnsjnio.LookupAsynch;
-import uk.nominet.dnsjnio.NonblockingResolver;
 
 public abstract class AbstractYamlTest extends TestCase {
     private static final Logger LOGGER = LoggerFactory.getLogger(AbstractYamlTest.class);
+    private static final ExecutorService EXECUTOR_SERVICE = Executors.newCachedThreadPool();
 
     private static final int FAKE_SERVER_PORT = 31348;
     protected static final int TIMEOUT = 10;
@@ -78,7 +78,6 @@
     protected static final int SYNCHRONOUS_EXECUTOR = 1;
     protected static final int STAGED_EXECUTOR = 2;
     protected static final int STAGED_EXECUTOR_MULTITHREADED = 3;
-    protected static final int STAGED_EXECUTOR_DNSJNIO = 4;
     private int spfExecutorType = SYNCHRONOUS_EXECUTOR;
 
     SPFYamlTestDescriptor data;
@@ -161,40 +160,6 @@
             executor = new SynchronousSPFExecutor(dns);
         } else if (getSpfExecutorType() == STAGED_EXECUTOR || getSpfExecutorType() == STAGED_EXECUTOR_MULTITHREADED){
             executor = new StagedMultipleSPFExecutor(new DNSServiceAsynchSimulator(dns, getSpfExecutorType() == STAGED_EXECUTOR_MULTITHREADED));
-        } else if (getSpfExecutorType() == STAGED_EXECUTOR_DNSJNIO) {
-            
-            // reset cache between usages of the asynchronous lookuper
-            LookupAsynch.setDefaultCache(new Cache(), DClass.IN);
-            // reset cache between usages of the asynchronous lookuper
-            LookupAsynch.getDefaultCache(DClass.IN).clearCache();
-
-            try {
-                ExtendedNonblockingResolver resolver;
-                
-                if (getDnsServiceMockStyle() == FAKE_SERVER) {
-                    NonblockingResolver nonblockingResolver = new NonblockingResolver("127.0.0.1");
-                    resolver = ExtendedNonblockingResolver.newInstance(new NonblockingResolver[] {nonblockingResolver});
-                    nonblockingResolver.setPort(FAKE_SERVER_PORT);
-                    nonblockingResolver.setTCP(false);
-                } else if (getDnsServiceMockStyle() == REAL_SERVER) {
-                    resolver = ExtendedNonblockingResolver.newInstance();
-                    Resolver[] resolvers = resolver.getResolvers();
-                    for (int i = 0; i < resolvers.length; i++) {
-                        resolvers[i].setTCP(false);
-                    }
-                } else {
-                    throw new IllegalStateException("DnsServiceMockStyle "+getDnsServiceMockStyle()+" is not supported when STAGED_EXECUTOR_DNSJNIO executor style is used");
-                }
-                
-                DNSJnioAsynchService jnioAsynchService = new DNSJnioAsynchService(resolver);
-                jnioAsynchService.setTimeout(TIMEOUT);
-                executor = new StagedMultipleSPFExecutor(jnioAsynchService);
-
-            } catch (UnknownHostException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-
         } else {
             throw new UnsupportedOperationException("Unknown executor type");
         }
@@ -465,6 +430,19 @@
             }
             return null;
         }
+
+        @Override
+        public CompletionStage<List<String>> getRecordsAsync(DNSRequest request) {
+            CompletableFuture<List<String>> completableFuture = new CompletableFuture<>();
+            EXECUTOR_SERVICE.execute(() -> {
+                try {
+                    completableFuture.complete(getRecords(request));
+                } catch (TimeoutException e) {
+                    completableFuture.completeExceptionally(e);
+                }
+            });
+            return completableFuture;
+        }
         
     }
 
diff --git a/resolver/src/test/java/org/apache/james/jspf/LoggingDNSService.java b/resolver/src/test/java/org/apache/james/jspf/LoggingDNSService.java
index f755c58..941175e 100644
--- a/resolver/src/test/java/org/apache/james/jspf/LoggingDNSService.java
+++ b/resolver/src/test/java/org/apache/james/jspf/LoggingDNSService.java
@@ -19,15 +19,15 @@
 
 package org.apache.james.jspf;
 
+import java.util.List;
+import java.util.concurrent.CompletionStage;
+
 import org.apache.james.jspf.core.DNSRequest;
 import org.apache.james.jspf.core.DNSService;
 import org.apache.james.jspf.core.exceptions.TimeoutException;
-import org.apache.james.jspf.executor.FutureSPFResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.List;
-
 public class LoggingDNSService implements DNSService {
     private static final Logger LOGGER = LoggerFactory.getLogger(LoggingDNSService.class);
 
@@ -93,21 +93,7 @@
     public List<String> getRecords(DNSRequest request) throws TimeoutException {
         try {
             List<String> result = dnsService.getRecords(request);
-            StringBuffer logBuff = new StringBuffer();
-            logBuff.append("getRecords(" + request.getHostname() + "," + request.getRecordType() + ") = ");
-            if (result != null) {
-                for (int i = 0; i < result.size(); i++) {
-                    logBuff.append(result.get(i));
-                    if (i == result.size() - 1) {
-                        logBuff.append("");
-                    } else {
-                        logBuff.append(",");
-                    }
-                }
-            } else {
-                logBuff.append("getRecords-ret: null");
-            }
-            LOGGER.debug(logBuff.toString());
+            debugLog(request, result);
             return result;
         } catch (TimeoutException e) {
             LOGGER.debug("getRecords({}) = TempErrorException[{}]",
@@ -116,4 +102,34 @@
         }
     }
 
+    private void debugLog(DNSRequest request, List<String> result) {
+        StringBuffer logBuff = new StringBuffer();
+        logBuff.append("getRecords(" + request.getHostname() + "," + request.getRecordType() + ") = ");
+        if (result != null) {
+            for (int i = 0; i < result.size(); i++) {
+                logBuff.append(result.get(i));
+                if (i == result.size() - 1) {
+                    logBuff.append("");
+                } else {
+                    logBuff.append(",");
+                }
+            }
+        } else {
+            logBuff.append("getRecords-ret: null");
+        }
+        LOGGER.debug(logBuff.toString());
+    }
+
+    @Override
+    public CompletionStage<List<String>> getRecordsAsync(DNSRequest request) {
+        return getRecordsAsync(request)
+            .thenApply(res -> {
+                debugLog(request, res);
+                return res;
+            })
+            .exceptionally(e -> {
+                LOGGER.debug("getRecords({}) = TempErrorException[{}]", request.getHostname(), e.getMessage());
+                return null;
+            });
+    }
 }
\ No newline at end of file
diff --git a/resolver/src/test/java/org/apache/james/jspf/MailZoneAsynchronousYamlTest.java b/resolver/src/test/java/org/apache/james/jspf/MailZoneAsynchronousYamlTest.java
index 21060a7..46d1889 100644
--- a/resolver/src/test/java/org/apache/james/jspf/MailZoneAsynchronousYamlTest.java
+++ b/resolver/src/test/java/org/apache/james/jspf/MailZoneAsynchronousYamlTest.java
@@ -70,7 +70,7 @@
     }

 

     protected int getSpfExecutorType() {

-        return STAGED_EXECUTOR_DNSJNIO;

+        return STAGED_EXECUTOR_MULTITHREADED;

     }

 

     static class MailZoneAsynchronousSuite extends TestSuite {