marunjar / anewjkuapp

GNU General Public License v3.0
16 stars 4 forks source link

Fix commons-lang3:3.11 bug by downgrading. #150

Closed rnbwdsh closed 3 years ago

rnbwdsh commented 3 years ago

Warning: This bug only appears on systems that haven't yet loaded an ics timetable cal yet. So wiping data + cache + reinstalling app (or even better: wiping the emulator) is highly suggested for reproduction.

When using the current app on a blank emulator/phone, and updating the time table after logging in you get the exception (and the timetable doesn't load):

2020-10-02 14:32:05.716 4131-4180/org.voidsink.anewjkuapp.debug E/WM-WorkerWrapper: Work [ id=7980203f-bc2a-444e-83e2-2fd1bd9605ca, tags={ org.voidsink.anewjkuapp.worker.ImportCalendarWorker, UPDATE_CAL_LVA } ] failed because it threw an exception/error
    java.util.concurrent.ExecutionException: java.lang.NoSuchMethodError: No static method requireNonNull(Ljava/lang/Object;Ljava8/util/function/Supplier;)Ljava/lang/Object; in class Ljava/util/Objects; or its super classes (declaration of 'java.util.Objects' appears in /apex/com.android.runtime/javalib/core-oj.jar)
        at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:516)
        at androidx.work.impl.utils.futures.AbstractFuture.get(AbstractFuture.java:475)
        at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:298)
        at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
        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:919)
     Caused by: java.lang.NoSuchMethodError: No static method requireNonNull(Ljava/lang/Object;Ljava8/util/function/Supplier;)Ljava/lang/Object; in class Ljava/util/Objects; or its super classes (declaration of 'java.util.Objects' appears in /apex/com.android.runtime/javalib/core-oj.jar)
        at org.apache.commons.lang3.Validate.notBlank(Validate.java:440)
        at net.fortuna.ical4j.model.TimeZoneRegistryImpl.getTimeZone(TimeZoneRegistryImpl.java:165)
        at net.fortuna.ical4j.data.DefaultContentHandler.resolveTimezones(DefaultContentHandler.java:183)
        at net.fortuna.ical4j.data.DefaultContentHandler.endCalendar(DefaultContentHandler.java:72)
        at net.fortuna.ical4j.data.CalendarParserImpl.parseCalendar(CalendarParserImpl.java:127)
        at net.fortuna.ical4j.data.CalendarParserImpl.parseCalendarList(CalendarParserImpl.java:180)
        at net.fortuna.ical4j.data.CalendarParserImpl.parse(CalendarParserImpl.java:149)
        at net.fortuna.ical4j.data.CalendarBuilder.build(CalendarBuilder.java:183)
        at net.fortuna.ical4j.data.CalendarBuilder.build(CalendarBuilder.java:171)
        at net.fortuna.ical4j.data.CalendarBuilder.build(CalendarBuilder.java:158)
        at org.voidsink.anewjkuapp.kusss.KusssHandler.loadIcalJsoup(KusssHandler.java:407)
        at org.voidsink.anewjkuapp.kusss.KusssHandler.loadIcal(KusssHandler.java:357)
        at org.voidsink.anewjkuapp.kusss.KusssHandler.getIcal(KusssHandler.java:322)
        at org.voidsink.anewjkuapp.worker.ImportCalendarWorker.importCalendar(ImportCalendarWorker.java:176)
        at org.voidsink.anewjkuapp.worker.ImportCalendarWorker.doWork(ImportCalendarWorker.java:102)
        at androidx.work.Worker$1.run(Worker.java:85)
        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:919) 

This is an error in the KUSSS-Calendar-Exported-ICS importing. Repeatedly git-downgrading until i found a version that works revealed that the breaking change was back on 5.4.2020 when commons:commons-lang3:3.9 was upgraded to 3.10. Downgrading back to 3.9 fixes the issue. However I couldn't find out why Objects.requireNonNull doesn't exist in that context / why it isn't detected compile time.

Tested on emulator + real phone.

2nd commit optional, to spot it when it breaks again easier.

rnbwdsh commented 3 years ago

Additional info i digged up: In 3.9 the notBlank method looks like this:

    public static <T extends CharSequence> T notBlank(final T chars, final String message, final Object... values) {
        if (chars == null) {
            throw new NullPointerException(String.format(message, values));
        }
        if (StringUtils.isBlank(chars)) {
            throw new IllegalArgumentException(String.format(message, values));
        }
        return chars;
    }

After 3.9, it uses Objects.requireNonNull. Which was added in API level 24 / the Objects was added in 19. As we're at a smaller minSdk this seems to cause it. No idea why the compiler doesn't pick up on it.

marunjar commented 3 years ago

@rnbwdsh Thanks for finding this bug, i'll merge and release a fix version as soon as possible.

Funny thing as proguard should backport java 8 features, maybe support will be better when desugaring is finally available in D8

marunjar commented 3 years ago

@rnbwdsh update is now rolling out