Core: documented keep rules do not preserve reflective model construction under strict R8
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 半日
- 初心者へのやさしさ
- 40/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- java
- 領域
- build-system, data
調査の方向性
Start with the standalone rules in google-http-client-assembly/proguard-google-http-client.txt and the reflective path in google-http-client/src/main/java/com/google/api/client/util/Types.java (newInstance, around lines 101-119). Run the reproducer's run.py against the documented and workaround rule sets to see the three parsing cases fail and pass. Done when the documented rules keep public no-argument constructors for model classes, those cases pass, and an R8 regression test covers reflective model construction.
索引モデルが issue の本文から書いたものです。
説明
JSON parsing can fail under strict R8 full mode even when using the library’s documented ProGuard rules. I reproduced this with the latest published google-http-client and google-http-client-gson 2.2.0.
The documented rules preserve generic signatures, annotations, and @Key fields, but do not explicitly preserve model classes and their public no-argument constructors. In the reproducer, R8 makes a GenericJson response model abstract and removes its constructor. Parsing then fails when the library attempts to construct that model reflectively.
Environment
- macOS 26.5
- OpenJDK/JBR 25.0.3
google-http-clientandgoogle-http-client-gson2.2.0- Gson 2.11.0 and Guava 33.4.8-android
- R8 9.4.24, bundled with AGP 9.4.1
- R8 release mode, with
setProguardCompatibility(false)andenableLegacyFullModeForKeepRules(false)
Reproduction
The attached reproducer.zip contains synthetic model fixtures, both rule configurations, and a runner. Extract it and run:
cd reproducer
python3 run.py --r8-jar /path/to/builder-9.4.1.jar
The runner downloads the pinned parsing dependencies, compiles an unminified control, and runs R8 with the documented rules and with the workaround below. R8 processes the fixture and both Google HTTP Client JARs together. Gson and Guava are supplied as library dependencies.
The runner checks these results automatically:
| Test | Unminified | Documented rules | With workaround |
|---|---|---|---|
| Plain model with typed nested list | Pass | Fail | Pass |
GenericJson model with typed nested list |
Pass | Fail | Pass |
| Supplied root with reflected nested model | Pass | Fail | Pass |
| Parameterized request serialization | Pass | Pass | Pass |
The parsing tests assert scalar values and nested model types. The runner exits successfully only when the expected failures and successes are observed.
Representative failure
The retraced GenericJson failure includes:
Caused by: java.lang.IllegalArgumentException: unable to create new instance of class repro.a because it is abstract and because it has no accessible default constructor
at com.google.api.client.util.Types.handleExceptionForNewInstance(Types.java:162)
at com.google.api.client.util.Types.newInstance(Types.java:117)
at com.google.api.client.util.Data.newMapInstance(Data.java:550)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:766)
...
Caused by: java.lang.NoSuchMethodException: repro.a.<init>()
The mapping identifies repro.a as the fixture’s GenericRoot model. The other two parsing failures are ClassCastException failures associated with lost reflected model/type retention; they are not separate demonstrations of missing constructors.
Workaround
Keep the existing attribute and annotated-field rules, and additionally use:
-keepclasseswithmembers,allowobfuscation class * {
@com.google.api.client.util.Key <fields>;
public <init>();
}
This fixes all three parsing cases in the reproducer.
The original annotated-field rule remains necessary for models that do not match this constructor rule, including request classes with only parameterized constructors. It also preserves field names when @Key uses its default name, while the additional rule permits class-name obfuscation.
Reflective construction in 2.2.0
In 2.2.0, JSON model construction reaches Types.newInstance(), which calls Class.newInstance() and requires a public no-argument constructor.
The release’s standalone ProGuard configuration preserves attributes and annotated fields but omits constructor protection. The core JAR also does not bundle Android consumer keep rules.
Could the project update the documented rules, ship appropriate consumer rules, and add an R8 regression test for reflective model construction?
Related: #1843 reports missing documentation and a similar full-mode construction failure. PR #2171 restores the documentation using the existing rules.
For simplicity, this reproducer uses JVM classfile output. It does not test an Android APK using 2.2.0.
- 主要言語
- Java
- スター
- 1.4k
- フォーク
- 476
- 平均マージ
- 10時間 47分
- マージ済み PR(30日)
- 3
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
googleapis/google-http-java-client のほかの issue
-
Core: Validate header names and values to prevent CRLF injection対応中かも @insaf021 が 106 日前に担当しました。 オープンpriority: p3
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
Core: XmlPullParser processes external DTD entities (XXE) — disable FEATURE_PROCESS_DOCDECL in Xml#createParser()対応中かも @insaf021 が 106 日前に担当しました。 オープンpriority: p3
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
-
Core: LowLevelHttpResponse not disconnected when HttpResponse construction throws RuntimeException対応中かも @insaf021 が 106 日前に担当しました。 オープンpriority: p3
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
-
type: cleanup
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
-
org.apache.http.conn.ssl.SSLSocketFactory is deprecated再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンpriority: p2 type: cleanup
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
googleapis/google-http-java-client の issue をすべて見る
似ている issue
-
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
-
難易度 2/5 1時間未満 初心者へのやさしさ 84/100
cpp-best-practices/project_validator#251 ·
メンテナーはふだん 1 日以内に返信
-
backend enhancement
難易度 2/5 半日 初心者へのやさしさ 70/100
damodharg6/payledger#16 ·
-
[Bug]: An initiative list with no current entry logs an error on every change対応中かも @dwizard0 が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
メンテナーはふだん 1 日以内に返信