Skip to content

Conversation

@esezen
Copy link
Contributor

@esezen esezen commented Jan 7, 2026

Fix R8/ProGuard Obfuscation for Release Builds

Problem

SDK fails in release builds with R8 enabled:

java.lang.IllegalArgumentException: Unexpected signature for
io.constructor.data.model.dataadapter.ResultDataAdapter.fromJson(...)

R8 obfuscates @FromJson method signatures, breaking Moshi's reflection-based adapter discovery.

Solution

Bundle ProGuard rules with the AAR via consumerProguardFiles. Rules auto-apply when consumers build with minification.

Changes

File Change
consumer-rules.pro New file - bundled rules for consumers
build.gradle Added consumerProguardFiles 'consumer-rules.pro'
proguard-rules.pro Fixed package: constructor.ioio.constructor

Rules Applied

# Keep Moshi adapter methods
-keepclassmembers class * {
    @com.squareup.moshi.FromJson <methods>;
    @com.squareup.moshi.ToJson <methods>;
}

# Keep SDK model classes
-keep class io.constructor.data.model.** { *; }

Backwards Compatibility

  • No API changes
  • Existing users: rules auto-apply, no action needed
  • Users with manual rules: no conflicts
  • Debug/non-minified builds: unaffected

Copilot AI review requested due to automatic review settings January 7, 2026 12:51
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a build issue by correcting the package naming convention in ProGuard rules from constructor.io to io.constructor and adds consumer ProGuard rules to ensure proper code preservation in consuming applications.

  • Corrected package name format in ProGuard keep rules from reverse domain notation to standard Java package notation
  • Added new consumer ProGuard rules file with Moshi serialization and SDK model preservation rules
  • Configured the library's release build to include consumer ProGuard rules

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
library/proguard-rules.pro Fixed package names from constructor.io.* to io.constructor.* format
library/consumer-rules.pro Added new consumer ProGuard rules for Moshi annotations and SDK model classes
library/build.gradle Configured release build to include consumer ProGuard rules file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@constructor-claude-bedrock
Copy link

Code Review Summary

This PR addresses a critical build issue by adding consumer ProGuard rules that are bundled with the library's AAR and automatically applied to consuming applications. The changes include:

  1. Adding consumerProguardFiles 'consumer-rules.pro' to the release build type in library/build.gradle
  2. Creating a new consumer-rules.pro file with Moshi and SDK-specific keep rules
  3. Fixing package name inconsistencies in the existing proguard-rules.pro file

The changes are well-structured and follow Android library best practices for ProGuard configuration.


Detailed Feedback

[File: library/build.gradle Line: 41] - Consumer ProGuard Configuration

Good: Adding consumerProguardFiles 'consumer-rules.pro' is the correct approach. This ensures that consuming applications automatically receive the necessary ProGuard rules when they minify their release builds, preventing runtime crashes due to stripped classes.

Note: This is only applied to the release build type. Consider whether you also want to apply this to the debug build type if consumers might enable minification in debug builds. However, the current approach (release only) is the standard practice.


[File: library/consumer-rules.pro Lines: 1-22] - Consumer ProGuard Rules Structure

Good: The new consumer rules file is well-organized with clear section headers and appropriate comments explaining why each rule is needed.

Observations:

  1. Moshi Rules (Lines 5-14): The rules correctly preserve Moshi's @FromJson/@ToJson annotations and Kotlin metadata, which is essential given the ResultDataAdapter.kt file uses @FromJson.

  2. SDK Model Classes (Line 19): The broad wildcard rule -keep class io.constructor.data.model.** { *; } ensures all model classes and their members are preserved for Moshi serialization.

  3. Custom Moshi Adapters (Line 22): Specifically keeping the dataadapter package protects the custom adapter classes like ResultDataAdapter.

Minor Suggestion: Consider documenting in the PR description or in code comments whether all fields in io.constructor.data.model.** truly need to be kept with { *; }, or if you could use more specific rules like:

-keep class io.constructor.data.model.** { <fields>; }

This would still keep all fields but allow ProGuard to optimize unused methods. However, if Moshi relies on both fields AND methods (getters/setters/constructors), the current approach is safer.


[File: library/proguard-rules.pro Lines: 23, 26] - Package Name Corrections

Excellent: Fixed the inconsistent package names:

  • Changed constructor.io.data.model.**io.constructor.data.model.**
  • Changed constructor.io.sample.**io.constructor.sample.**

These corrections align with the actual package structure (io.constructor.*) as confirmed by the codebase exploration. This is a critical bug fix that would have caused the ProGuard rules to be ineffective.


🔍 [General] - Missing Debug Build Type Consumer Rules

Observation: The consumerProguardFiles directive is only added to the release build type. While this is standard practice (minification is typically disabled in debug builds), if any consuming app enables minification in debug mode, they won't automatically receive these rules.

Recommendation: This is likely intentional and correct, but verify with your team that this aligns with your SDK's usage patterns.


🔍 [General] - Completeness of Rules

Question: The consumer rules focus on Moshi and model classes. Consider whether you need additional rules for:

  1. Retrofit interfaces (if exposed to consumers)
  2. Public API classes that consumers interact with directly
  3. Any classes using reflection beyond Moshi

The existing proguard-rules.pro has Retrofit and Okio rules (lines 1-8), but these may only be needed for the library's internal testing, not for consumers.

Recommendation: If the current rules are sufficient for your testing and no issues have been reported, the PR is likely complete. However, consider testing with a sample app that has minification enabled to ensure no runtime crashes occur.


[General] - Consumer Rules vs Library Rules Separation

Good: The separation between consumer-rules.pro (rules for consuming apps) and proguard-rules.pro (rules for library itself) is clean and appropriate. The consumer rules are minimal and focused on what's necessary for the library to function correctly in consuming apps.


Conclusion

Verdict: ✅ Approve with minor observations

This PR successfully addresses the build issue with a proper, well-structured solution. The changes demonstrate:

  • ✅ Correct use of consumerProguardFiles for library distribution
  • ✅ Appropriate ProGuard rules for Moshi serialization
  • ✅ Critical bug fixes in package name corrections
  • ✅ Clean separation of concerns between library and consumer rules

Action Items (optional, not blocking):

  1. Consider adding a test case or documentation on how to verify these rules work correctly in a consuming app with minification enabled
  2. If not already done, test the generated AAR to ensure the consumer rules are properly bundled

The code quality is high, and the changes are focused and purposeful. Great work on identifying and fixing the package name issues in the existing rules! 🎯

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants