Michael
Michael

Reputation: 721

AsyncTask causing NoClassDefFoundError

I'm have an asynctask defined to execute a task periodically. It works. I've tested it countless times. However, for some reason it keeps crashing occasionally. I can't find the source of the problem since the stacktrace is quite vague. Here's the stacktrace:

Fatal Exception: java.lang.RuntimeException: An error occured while executing doInBackground()
       at android.os.AsyncTask$3.done(AsyncTask.java:299)
       at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
       at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
       at java.util.concurrent.FutureTask.run(FutureTask.java:239)
       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
       at java.lang.Thread.run(Thread.java:856)
Caused by java.lang.NoClassDefFoundError: android.system.ErrnoException
       at dita.dev.myportal.SyncManager$GetData.doInBackground(Unknown Source)
       at dita.dev.myportal.SyncManager$GetData.doInBackground(Unknown Source)
       at android.os.AsyncTask$2.call(AsyncTask.java:287)
       at java.util.concurrent.FutureTask.run(FutureTask.java:234)
       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
       at java.lang.Thread.run(Thread.java:856)

At first I thought it was because I was using proguard and jsoup, but I tested it after adding jsoup rules and it works. Here's my rules for jsoup:

-keeppackagenames org.jsoup.nodes
-keep public class org.jsoup.** {
    public *;
}

Here's the task being executed:

private static class GetData extends AsyncTask<Void, Integer, Boolean> {

        private Context context;
        private String message;

        GetData(Context context) {
            this.context = context;
        }

        @Override
        protected Boolean doInBackground(Void... voids) {
            String username = Preferences.getString(context, "username");
            String password = Preferences.getString(context, "password");
            if (username == null) {
                return false;
            }
            PortalCrawler crawler = new PortalCrawler(Config.BASE_URL1);

            try {
                crawler.start(username, password);
                crawler.saveData();
                return true;
            } catch (Exception e) {
                if (e instanceof SocketTimeoutException || e instanceof UnknownHostException ||
                        e instanceof ErrnoException || e instanceof SocketException) {
                    crawler.setBaseUrl(Config.BASE_URL2);
                    try {
                        crawler.start(username, password);
                        crawler.saveData();
                        return  true;
                    } catch (Exception e1) {
                        e1.printStackTrace();

                        if (e1 instanceof SocketTimeoutException || e1 instanceof UnknownHostException
                                || e1 instanceof ErrnoException || e1 instanceof SocketException) {
                            message = "Unable to connect";
                        } else {
                            Crashlytics.logException(e.getCause());
                            message = "An error occurred";
                        }
                    }

                } else {
                    e.printStackTrace();
                    Crashlytics.logException(e.getCause());
                    message = "An error occurred";
                }

            }
            return false;
        }

        @Override
        protected void onPostExecute(Boolean success) {
            if (success) {
                Preferences.setBoolean(context, "initialSync", true);
                message = "Sync completed";
            }
            EventBus.getDefault().post(new Events.SyncDone(success, message));
        }
    }
}

Upvotes: 0

Views: 208

Answers (1)

G. Blake Meike
G. Blake Meike

Reputation: 6715

I believe the problem is here:

e instanceof ErrnoException

I suspect you are attempting to run this application on a pre API-21 device, on which android.system.ErrnoException does not exist. It was introduced in 21.

You compiled it against a post 21 API but are then attempting to run it on a pre 21 device.

Upvotes: 1

Related Questions