Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IllegalAccessException when enqueueing work with WorkManager

I get IllegalAccessException when trying to enqueue work with WorkManager 1.0 stable. Here's the stack trace:

E/WM-WorkerFactory: Could not instantiate com.pocket.sdk.util.service.BackgroundSync$SyncJob
    java.lang.IllegalAccessException: java.lang.Class<com.example.BackgroundManager$BackgroundWorker> is not accessible from java.lang.Class<androidx.work.WorkerFactory>
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
        at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:92)
        at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:233)
        at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:127)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)

The worker is an inner class declared like so:

private static class BackgroundWorker extends Worker {
    // ...
}

How can I fix this exception?

like image 326
Marcin Koziński Avatar asked Mar 12 '19 11:03

Marcin Koziński


People also ask

Is WorkManager deprecated?

This method is deprecated.

How do I cancel WorkManager on Android?

Stop a running Worker You explicitly asked for it to be cancelled (by calling WorkManager. cancelWorkById(UUID) , for example). In the case of unique work, you explicitly enqueued a new WorkRequest with an ExistingWorkPolicy of REPLACE . The old WorkRequest is immediately considered cancelled.


1 Answers

Looks like WorkManager is using reflection to create an instance of the worker. However because it is declared as a private inner class it is inaccessible to the WorkerFactory class that tries to do this.

What I've done is to simply declare my workers as public inner classes, like so:

public static class BackgroundWorker extends Worker {
    // ...
}

I have also made sure that the constructor is public.

But I would love to find a solution that doesn't require exposing the workers to the whole world.

like image 88
Marcin Koziński Avatar answered Oct 27 '22 11:10

Marcin Koziński