Android: List.of() (API 30+) used in core since 0.24.0 contradicts the README's "minimum API level is 19"
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 74/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- mobile-dev
Research direction
Start by reviewing the listed List.of, Set.of, and Map.of occurrences in the commonmark module and the Android test setup in .github/workflows/ci.yml. Reproduce the API 24–29 failure without core library desugaring, then verify that the chosen resolution keeps the README, runtime behavior, and Android support expectations consistent.
Written by the indexing model from the issue text.
Description
Summary
Since 0.24.0 the core commonmark module uses java.util.List.of(...) (and a few Set.of/Map.of). On Android these methods exist only from API 30 (Android 11). The README still says:
It works on Android too, but that is on a best-effort basis, please report problems. For Android the minimum API level is 19
An app with minSdk < 30 that does not enable core library desugaring crashes on the first parse on API < 30 devices:
java.lang.NoSuchMethodError: No static method of(Ljava/lang/Object;)Ljava/util/List;
at org.commonmark.internal.InlineParserImpl.parse(InlineParserImpl.java)
This is the same class of problem as #366 / #373 (Objects.requireNonNullElseGet, fixed by #369). The List.of usages were introduced deliberately in #322 as a Java 11 clean-up, so this is a report that the clean-up and the Android support statement now disagree — not a claim that the change was wrong.
Steps to reproduce
Android app, minSdk 24, no coreLibraryDesugaring, org.commonmark:commonmark:0.30.0, run on an API 24–29 emulator:
Parser.builder().build().parse("*a*") // NoSuchMethodError: List.of
With isCoreLibraryDesugaringEnabled = true + com.android.tools:desugar_jdk_libs:2.1.5 the same code works on API 24 (verified on an API 24 emulator).
Where the API 30+ calls live (0.30.0, commonmark module)
List.of / Set.of / Map.of occurrences by file:
| File | Count |
|---|---|
internal/InlineParserImpl.java |
8 |
renderer/markdown/CoreMarkdownNodeRenderer.java |
3 |
renderer/html/CoreHtmlNodeRenderer.java |
3 |
parser/Parser.java |
3 (incl. Javadoc example) |
internal/ParagraphParser.java |
2 |
internal/IndentedCodeBlockParser.java |
2 |
renderer/text/CoreTextContentNodeRenderer.java, renderer/markdown/MarkdownRenderer.java, renderer/html/HtmlWriter.java, renderer/html/DefaultUrlSanitizer.java, parser/block/AbstractBlockParser.java, node/SourceSpans.java |
1 each |
0.22.0 had none; 0.24.0 introduced 8 in InlineParserImpl.
Why CI did not catch it
commonmark-android-test is only run through ./gradlew :app:lint in .github/workflows/ci.yml (minSdk 19, no emulator run), so a runtime NoSuchMethodError never surfaces there.
Possible resolutions
Either would be fine from a consumer's point of view — the important part is that the README and the code agree:
- Keep API 19 support — replace the factory calls with Java 8 equivalents (
Collections.emptyList()/singletonList(x)/unmodifiableList(Arrays.asList(a, b)), same forSet/Map). Mechanical, ~26 sites, keeps immutability. I can send a PR if you want this. - Document the new requirement — state in the README that Android needs API 30+ or core library desugaring, and ideally have
commonmark-android-testrun on an emulator (or fail lint onNewApi) so future regressions are visible.
Context: I hit this while building an Android Markdown renderer on top of commonmark-java (https://github.com/Jimmy-Jung/RichMarkdown-Android). We chose minSdk 30 for now, so this is not blocking us — reporting because the README statement is likely to mislead other Android users.
- Dominant language
- Java
- Stars
- 2.7k
- Forks
- 337
- Avg merge
- 15d 9h
- Merged PRs (30d)
- 1
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from commonmark/commonmark-java
-
Unclosed link reference definition title keeps the partial title and the following paragraph's source spans (0.30.0)Possibly taken @sean0407 claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
commonmark/commonmark-java#460 · 1 comment ·
-
Difficulty 3/5 1-2 days Newbie friendliness 48/100
commonmark/commonmark-java#443 · 4 comments ·
-
Option to define custom flanking/canOpen/canClose rules for delimitersMay be free again @abhiramaab claimed this 60 days ago, and no pull request is open. Openenhancement
Difficulty 4/5 3-5 days Newbie friendliness 45/100
commonmark/commonmark-java#428 · 4 comments ·
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 25/100
commonmark/commonmark-java#414 · 1 comment · 1 reaction ·
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 30/100
commonmark/commonmark-java#411 · 2 comments ·
All issues in commonmark/commonmark-java
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
utopia-rise/godot-jvm#1004 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
spring-projects/spring-grpc#442 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
resilience4j/resilience4j#2547 ·
Maintainers usually reply within 9 days
-
Clock.MakeDate continues execution and returns a rolled-over instant after dispatching error on invalid datePossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 1/5 Under an hour Newbie friendliness 82/100
mit-cml/appinventor-sources#4155 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 1-3 hours Newbie friendliness 62/100
Hira-shi/PW1-DAI-Carrel-Egal-Eyer#28 ·
Maintainers usually reply within 1 day