Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zxing-core 3.4.0 crashes on Android < 7.0 when decoding QR code #1170

Closed
miraculix-druids opened this issue May 22, 2019 · 33 comments
Closed

Comments

@miraculix-druids
Copy link

miraculix-druids commented May 22, 2019

I'm using com.google.zxing:core:3.4.0 with com.google.zxing:android-core:3.3.0 and com.google.zxing:android-integration:3.3.0 in an Android app.
Everytime I scan a QR code with an Android device with Android < 7.0 (API 24) the app crashes with the following exception:

java.lang.NoSuchMethodError: No interface method sort(Ljava/util/Comparator;)V in class Ljava/util/List; or its super classes (declaration of 'java.util.List' appears in /system/framework/core-libart.jar)
        at com.google.zxing.qrcode.detector.FinderPatternFinder.selectBestPatterns(FinderPatternFinder.java:616)
        at com.google.zxing.qrcode.detector.FinderPatternFinder.find(FinderPatternFinder.java:164)
        at com.google.zxing.qrcode.detector.Detector.detect(Detector.java:81)
        at com.google.zxing.qrcode.QRCodeReader.decode(QRCodeReader.java:77)
        at com.google.zxing.MultiFormatReader.decodeInternal(MultiFormatReader.java:173)
        at com.google.zxing.MultiFormatReader.decodeWithState(MultiFormatReader.java:87)
        at com.google.zxing.client.android.DecodeHandler.decode(DecodeHandler.java:98)
        at com.google.zxing.client.android.DecodeHandler.handleMessage(DecodeHandler.java:59)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at com.google.zxing.client.android.DecodeThread.run(DecodeThread.java:112)

It looks like the java.util.List.sort(...) method used in FinderPatternFinder.java:616 is not available on Android < API 24: https://developer.android.com/reference/java/util/List.html#sort(java.util.Comparator%3C?%2520super%2520E%3E)

Proposed solution: Use Collections.sort(possibleCenters, moduleComparator) instead of possibleCenters.sort(moduleComparator);

To make things more complicated: Android support for Java8 depends on the Android version. Some language features might be only available on newer Android versions: https://developer.android.com/studio/write/java8-support
Requiring Java8 for zxing-core means either checking all used Java8 features if they are available Android < 7.0 or dropping support for Android < 7.0 completely.

@srowen
Copy link
Contributor

srowen commented May 22, 2019

Tough call there. On the one hand I can't publish the Android app anymore, so it's kind of 'deprecated'. The core library can still be used outside Android, or in another Android app. That app would have to target API 24, yes. The app in the project can't target API 24, so it also doesn't quite make sense to leave it in a state where it won't run on API < 24. Another solution is to modify the Android app to depend on the 3.3.x core library and leave it there.

@srowen
Copy link
Contributor

srowen commented May 22, 2019

Resolved in 4b573da by just using the older library version.

@srowen srowen closed this as completed May 22, 2019
@githubZYQ
Copy link

Hello,I had the same problem yesterday!
compileOptions { targetCompatibility 1.8 sourceCompatibility 1.8 }
I tried to use Java 8 in my projects,However, it still failed to run on my phone(Android API 23).
As long as I want to be compatible with phones under API 24, I can only use zxing-core lib under 3.3.3 .
If I want to use zxing-core 3.4.0, I must set a minimum api 24。
minSdkVersion 24
Is that right?

@srowen
Copy link
Contributor

srowen commented May 23, 2019

Yes that's correct.

@adriancretu
Copy link

How could this possibly escaped as a release? We've updated zxing to 3.4.0 into production since it didn't trigger any compiler or LINT or Gradle warnings, and this issue became instantly the #1 crash.

And why did this happen? Well, why bother updating your Android library manifest to specify minSdk as 24? Let the users discover by themselves.

@srowen
Copy link
Contributor

srowen commented Jun 2, 2019

@adriancretu not sure I understand. The release is fine; there are no more releases of the app in this project, and the released version continues to be fine. I made the change above as a sort of convenience for anyone who still compiles it manually.

3.4.0 is usable in Android apps if you target a higher min SDK. I'll update the release notes to call that out, but you need to test and understand the implication of updating in your app. Also: the core library isn't just used in Android apps.

@adriancretu
Copy link

Well, this sort of problem (a breaking update) is usually solved in 2 ways:
a) Do a major version bump and break existing API, so users are aware.
b) Release as an Android lib and take advantage of minSdk in gradle or the manifest.

Requiring Java 8 but still allowing for compile to work fine with Java 7 projects (like Android) is not really a "minor" update.

@srowen
Copy link
Contributor

srowen commented Jun 2, 2019

This project has never been an android library, and that part isn't released anymore. Whether semver suggests a major version bump for requiring a newer dependency is unclear but I don't think it warranted a major version, as the primary audience now is Java apps, not Android, and Java 8 is already EOL there. Requiring it doesn't do much of anything outside . You can simply increase minSdk or use 3.3.3. Surely this shows up easily in testing

@adriancretu
Copy link

Thanks for clarifying the status of this project. I know for sure that the core library is used in major higher-level frameworks, so time will tell whether it's acceptable for devs to drop 50% of Android devices just for one lib. In our case, the minSdk is 18, so raising to 24 is unacceptable. Reverted to 3.3.3 for the foreseeable future, though it's sad to see the "there's a new version for this dependency" warning..

@githubZYQ
Copy link

Yes that's correct.

Thank you for your answer.

@ligi
Copy link

ligi commented Jun 5, 2019

dam - that bug really sucks - do you plan on releasing 3.4.1 with the workaround?
@adriancretu wonder if you found a good replacement for zxing as android does not seem to be really supported anymore if I read this conversation correctly

@srowen
Copy link
Contributor

srowen commented Jun 5, 2019

There is no bug here...?

@ligi
Copy link

ligi commented Jun 5, 2019

ok - that regression really sucks

@srowen
Copy link
Contributor

srowen commented Jun 5, 2019

Folks: this change was on purpose and the Android app here is not part of a release.

@adriancretu
Copy link

But you're surely aware that a LOT of other apps besides the one you're talking about (and of which nobody really cares) depended on your library. Maybe you don't see it as a bug, but yes, it sucks, and I am also looking for a replacemente due to this.

@ligi
Copy link

ligi commented Jun 5, 2019

@adriancretu https://github.com/lessthanoptimal/BoofCV/ https://boofcv.org looks very promising and is also actively developed and not in "Maintenance Mode Only" like zxing. I think I will move there with my apps.

@srowen
Copy link
Contributor

srowen commented Jun 5, 2019

Yes, I'm aware of what it requires and did it on purpose. You should probably be finding another library if you can't target API 24. Or: simply use 3.3.3. These aren't hard, but, do what you need to do.

@adriancretu
Copy link

I think everyone understands what you are saying, its just a matter of following a culture of backwards-comaptibility that has been broken here a little. There are tons of libraries that simply release as a completely different package when major changes like switching to JRE 8 is involved, exactly for these reasons. And on purpose.

@zjupure
Copy link

zjupure commented Sep 19, 2019

I meet the same problem. Can you use Collections.sort() api instead of List.sort()?
As an app developer, we need to compatiable sdk version to 14, but zxing break backwards-comaptibility.

@srowen
Copy link
Contributor

srowen commented Sep 19, 2019

No, just use the last 3.3.x version. It's all but identical.

@Nyconing
Copy link

Nyconing commented Sep 20, 2019

hi, please make a compatible codes as android support library can do it. simply check the api level before some 'feature' like List.sort(), and fallback to compatbility mode if level arent targeted.

Im fixed it by

FinderPatternFinder.java
...
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
      possibleCenters.sort(moduleComparator);
    }else {
      Collections.sort(possibleCenters, moduleComparator);
    }

And I found List.sort() only in FinderPatternFinder.java, do anyone found it on any file?

and again, if you do so, please, dont increase contrived complexity further more. it was pain to read the codes.

@srowen
Copy link
Contributor

srowen commented Sep 20, 2019

Please read all of the messages above. You can a) use 3.3.x, or b) target API 24.

@awenger
Copy link
Contributor

awenger commented Oct 16, 2019

Requires Java 8+. Note: Android apps using this version must target API 24 or higher.

Please read all of the messages above. You can a) use 3.3.x, or b) target API 24.

This statements are a bit misleading. On android the target sdk is something different then the min sdk. And if I haven't missed some essential part of this discussion the requirement is to have min sdk level of 24, right? See: https://developer.android.com/guide/topics/manifest/uses-sdk-element

@srowen
Copy link
Contributor

srowen commented Oct 16, 2019

Yes, I mean require API 24 as the min.

markusfisch added a commit to markusfisch/BinaryEye that referenced this issue Nov 13, 2019
Do NOT upgrade ZXing because newer versions won't work on API < 24.
For details see: zxing/zxing#1170
markusfisch added a commit to markusfisch/BinaryEye that referenced this issue Nov 14, 2019
Newer ZXing versions won't work on API levels below 24 because
ZXing requires support for Java 8 now. See;
zxing/zxing#1170

Because this is a major leap forward, this commit also migrates
to AndroidX (since the support library is deprecated) and removes
everything that isn't required anymore.

Development for API levels 9 to 23 will continue in the master
branch. I'm not going to drop support for API levels below 24!
@vvb2060
Copy link

vvb2060 commented Nov 20, 2019

https://developer.android.com/studio/preview/features/?utm_medium=studio-assistant&utm_source=android-studio#j8-desugar

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }

  compileOptions {
    // Flag to enable support for the new language APIs
    coreLibraryDesugaringEnabled true
    // Sets Java compatibility to Java 8
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

D8 compiles a separate library DEX file that contains an implementation of the missing APIs and includes it in your app.

    .line 614
    iget-object v3, v0, Lcom/google/zxing/qrcode/detector/FinderPatternFinder;->possibleCenters:Ljava/util/List;

    sget-object v4, Lcom/google/zxing/qrcode/detector/FinderPatternFinder;->moduleComparator:Lcom/google/zxing/qrcode/detector/FinderPatternFinder$EstimatedModuleComparator;

    invoke-static {v3, v4}, Lj$/util/List$-EL;->sort(Ljava/util/List;Ljava/util/Comparator;)V

Now, we can keep minSdk in 19.

@ZQ173
Copy link

ZQ173 commented Nov 22, 2019

https://developer.android.com/studio/preview/features/?utm_medium=studio-assistant&utm_source=android-studio#j8-desugar

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }

  compileOptions {
    // Flag to enable support for the new language APIs
    coreLibraryDesugaringEnabled true
    // Sets Java compatibility to Java 8
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

D8 compiles a separate library DEX file that contains an implementation of the missing APIs and includes it in your app.

    .line 614
    iget-object v3, v0, Lcom/google/zxing/qrcode/detector/FinderPatternFinder;->possibleCenters:Ljava/util/List;

    sget-object v4, Lcom/google/zxing/qrcode/detector/FinderPatternFinder;->moduleComparator:Lcom/google/zxing/qrcode/detector/FinderPatternFinder$EstimatedModuleComparator;

    invoke-static {v3, v4}, Lj$/util/List$-EL;->sort(Ljava/util/List;Ljava/util/Comparator;)V

Now, we can keep minSdk in 19.

3Q,coreLibraryDesugaringEnabled it is work with me !

@srowen
Copy link
Contributor

srowen commented Nov 22, 2019

Yes indeed, that's another solution, to enable Java 8 compatibility. Good tip @ZQ173 , I'll add that to the notes.

@adriancretu
Copy link

That "solution" requires Android Studio 4.0, which is currently not even in a beta stage. There's no guarantee it will even be a thing, in the end. Look at what happened to the jack & jill compiler...

@yuantailing
Copy link

hi, please make a compatible codes as android support library can do it. simply check the api level before some 'feature' like List.sort(), and fallback to compatbility mode if level arent targeted.

Im fixed it by

FinderPatternFinder.java
...
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
      possibleCenters.sort(moduleComparator);
    }else {
      Collections.sort(possibleCenters, moduleComparator);
    }

And I found List.sort() only in FinderPatternFinder.java, do anyone found it on any file?

and again, if you do so, please, dont increase contrived complexity further more. it was pain to read the codes.

Can I simply change the code to Collections.sort(possibleCenters, moduleComparator) without judging SDK version?

@nikkitagupta
Copy link

Resolved in 4b573da by just using the older library version.

which zxing version did you used to fix the issue ?

@rodrigoarias
Copy link

3 years late, but this thread was fun to read.

@hzy00
Copy link

hzy00 commented Jun 20, 2023

zxing core 3.5.1 still crash

@Nyconing
Copy link

Fork it or download it, and modify where it is not compatible for your current project.

FinderPatternFinder.java
...
    Collections.sort(possibleCenters, moduleComparator);

Or, just target android 7 (sdk version 24), in 2023 it was super majority.

Or, just use old version of zxing. (3.3.3)

Stop contributing your comments on this issue because apparently this project owner refuse to do it, that why this issue never reopen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests