Browse Source

docs: add comprehensive AAR integration troubleshooting guide

- Add AAR Duplicate Class Issues section to BUILDING.md with step-by-step solutions
- Create dedicated docs/aar-integration-troubleshooting.md with complete troubleshooting guide
- Document project reference approach (recommended) vs AAR-only approach
- Add verification steps, prevention strategies, and best practices
- Update README.md with links to new documentation
- Resolve duplicate class issues through proper project reference configuration

Fixes AAR integration issues that caused build failures due to plugin being
included both as project reference and AAR file simultaneously.
master
Matthew Raymer 1 day ago
parent
commit
ef37b10503
  1. 72
      BUILDING.md
  2. 2
      README.md
  3. 372
      docs/aar-integration-troubleshooting.md

72
BUILDING.md

@ -537,6 +537,45 @@ adb install app/build/outputs/apk/debug/app-debug.apk
- Interactive testing interface
- Comprehensive logging and debugging
**Plugin Integration Approach:**
The Vue 3 test app uses a **project reference approach** for plugin integration:
1. **Project Reference Configuration**:
```gradle
// capacitor.settings.gradle
include ':timesafari-daily-notification-plugin'
project(':timesafari-daily-notification-plugin').projectDir = new File('../../../android/plugin')
// capacitor.build.gradle
implementation project(':timesafari-daily-notification-plugin')
```
2. **Required Dependencies**:
```gradle
// app/build.gradle
implementation 'androidx.work:work-runtime:2.9.0'
implementation 'androidx.lifecycle:lifecycle-service:2.7.0'
implementation 'com.google.code.gson:gson:2.10.1'
```
3. **Plugin Discovery**:
```json
// assets/capacitor.plugins.json
[
{
"id": "DailyNotification",
"name": "DailyNotification",
"class": "com.timesafari.dailynotification.DailyNotificationPlugin"
}
]
```
**Troubleshooting Integration Issues:**
- **Duplicate Classes**: Use project reference instead of AAR to avoid conflicts
- **Gradle Cache**: Clear completely (`rm -rf ~/.gradle`) when switching approaches
- **Path Issues**: Ensure correct project path (`../../../android/plugin`)
- **Dependencies**: Include required WorkManager and Gson dependencies
### Integration Testing
#### 1. Create External Test Capacitor App
@ -857,6 +896,39 @@ npm list @timesafari/daily-notification-plugin
npx cap sync android
```
#### AAR Duplicate Class Issues
```bash
# Problem: Duplicate class errors when integrating plugin AAR
# Error: "Duplicate class com.timesafari.dailynotification.BootReceiver found in modules"
# Root Cause: Plugin being included both as project reference and as AAR file
# Solution 1: Use Project Reference Approach (Recommended)
# 1. Clear Gradle cache completely
./gradlew --stop
rm -rf ~/.gradle
rm -rf app/build
rm -rf build
# 2. Configure project reference in capacitor.settings.gradle
include ':timesafari-daily-notification-plugin'
project(':timesafari-daily-notification-plugin').projectDir = new File('../../../android/plugin')
# 3. Add dependency in capacitor.build.gradle
implementation project(':timesafari-daily-notification-plugin')
# 4. Remove AAR dependency from app/build.gradle
# Comment out: implementation(name: 'plugin-debug', ext: 'aar')
# Solution 2: AAR-Only Approach (Alternative)
# 1. Remove project references from capacitor.settings.gradle and capacitor.build.gradle
# 2. Ensure only AAR dependency in app/build.gradle
# 3. Remove any duplicate classes.jar files from libs/ directory
# 4. Clear Gradle cache and rebuild
# Verification: Check that plugin is included only once
./gradlew :app:dependencies | grep timesafari
```
### Debug Commands
#### Android Debugging

2
README.md

@ -735,6 +735,8 @@ MIT License - see [LICENSE](LICENSE) file for details.
- **API Reference**: Complete TypeScript definitions
- **Migration Guide**: [doc/migration-guide.md](doc/migration-guide.md)
- **Integration Guide**: [INTEGRATION_GUIDE.md](INTEGRATION_GUIDE.md) - Complete integration instructions
- **Building Guide**: [BUILDING.md](BUILDING.md) - Comprehensive build instructions and troubleshooting
- **AAR Integration Troubleshooting**: [docs/aar-integration-troubleshooting.md](docs/aar-integration-troubleshooting.md) - Resolving duplicate class issues
- **Implementation Guide**: [doc/STARRED_PROJECTS_POLLING_IMPLEMENTATION.md](doc/STARRED_PROJECTS_POLLING_IMPLEMENTATION.md) - Generic polling interface
- **UI Requirements**: [doc/UI_REQUIREMENTS.md](doc/UI_REQUIREMENTS.md) - Complete UI component requirements
- **Host App Examples**: [examples/hello-poll.ts](examples/hello-poll.ts) - Generic polling integration

372
docs/aar-integration-troubleshooting.md

@ -0,0 +1,372 @@
# AAR Integration Troubleshooting Guide
**Author**: Matthew Raymer
**Last Updated**: 2025-01-27
**Version**: 1.0.0
## Overview
This document provides comprehensive troubleshooting guidance for integrating the DailyNotification plugin AAR into Android applications, specifically addressing the common duplicate class issues that occur during plugin integration.
## Table of Contents
- [Common Issues](#common-issues)
- [Root Cause Analysis](#root-cause-analysis)
- [Solution Approaches](#solution-approaches)
- [Step-by-Step Resolution](#step-by-step-resolution)
- [Verification Steps](#verification-steps)
- [Prevention Strategies](#prevention-strategies)
- [Best Practices](#best-practices)
## Common Issues
### Duplicate Class Errors
**Error Message:**
```
Duplicate class com.timesafari.dailynotification.BootReceiver found in modules:
- plugin-debug.aar -> plugin-debug-runtime (:plugin-debug:)
- plugin-debug.aar -> plugin-debug-runtime (plugin-debug.aar)
```
**Symptoms:**
- Build fails with duplicate class errors
- Plugin classes appear twice in dependency tree
- Gradle build process hangs or fails
- AAR integration appears broken
### Gradle Cache Corruption
**Error Message:**
```
Could not read workspace metadata from /home/user/.gradle/caches/8.13/transforms/.../metadata.bin
No matching variant of project :timesafari-daily-notification-plugin was found
```
**Symptoms:**
- Gradle sync failures
- Project reference resolution issues
- Inconsistent build behavior
- Cache-related build errors
## Root Cause Analysis
### Primary Cause: Dual Inclusion
The duplicate class issue occurs when the plugin is included **twice** in the build process:
1. **As Project Reference**: Capacitor's automatic plugin discovery includes the plugin as a project reference
2. **As AAR File**: The AAR file is also included directly in the build dependencies
### Contributing Factors
1. **Capacitor Auto-Discovery**: Capacitor automatically discovers plugins via `capacitor.plugins.json`
2. **Symlinked Dependencies**: Node modules may create symlinks that confuse Gradle
3. **Gradle Cache Issues**: Corrupted cache can cause inconsistent behavior
4. **Path Resolution**: Incorrect project paths can cause module resolution failures
### Technical Details
**Project Reference Path:**
```gradle
project(':timesafari-daily-notification-plugin').projectDir = new File('../../../android/plugin')
```
**AAR File Path:**
```gradle
implementation(name: 'plugin-debug', ext: 'aar')
```
**Capacitor Discovery:**
```json
{
"id": "DailyNotification",
"name": "DailyNotification",
"class": "com.timesafari.dailynotification.DailyNotificationPlugin"
}
```
## Solution Approaches
### Approach 1: Project Reference (Recommended)
**Advantages:**
- ✅ No duplicate class issues
- ✅ Better development experience
- ✅ Automatic dependency resolution
- ✅ Easier debugging and testing
**Disadvantages:**
- ❌ Requires correct project structure
- ❌ More complex initial setup
- ❌ Path-dependent configuration
### Approach 2: AAR-Only
**Advantages:**
- ✅ Simpler dependency management
- ✅ Self-contained distribution
- ✅ No project structure dependencies
**Disadvantages:**
- ❌ Prone to duplicate class issues
- ❌ Requires manual dependency management
- ❌ Harder to debug and test
## Step-by-Step Resolution
### Method 1: Project Reference Resolution
#### Step 1: Clear Gradle Cache
```bash
# Stop Gradle daemon
./gradlew --stop
# Clear all Gradle caches
rm -rf ~/.gradle
# Clear project build directories
rm -rf app/build
rm -rf build
```
#### Step 2: Configure Project Reference
```gradle
# capacitor.settings.gradle
include ':timesafari-daily-notification-plugin'
project(':timesafari-daily-notification-plugin').projectDir = new File('../../../android/plugin')
```
#### Step 3: Add Project Dependency
```gradle
# capacitor.build.gradle
dependencies {
implementation project(':timesafari-daily-notification-plugin')
}
```
#### Step 4: Remove AAR Dependency
```gradle
# app/build.gradle
dependencies {
// Comment out or remove AAR dependency
// implementation(name: 'plugin-debug', ext: 'aar')
// Keep required dependencies
implementation 'androidx.work:work-runtime:2.9.0'
implementation 'androidx.lifecycle:lifecycle-service:2.7.0'
implementation 'com.google.code.gson:gson:2.10.1'
}
```
#### Step 5: Verify Plugin Discovery
```json
// assets/capacitor.plugins.json
[
{
"id": "DailyNotification",
"name": "DailyNotification",
"class": "com.timesafari.dailynotification.DailyNotificationPlugin"
}
]
```
### Method 2: AAR-Only Resolution
#### Step 1: Remove Project References
```gradle
# capacitor.settings.gradle - Comment out project reference
// include ':timesafari-daily-notification-plugin'
// project(':timesafari-daily-notification-plugin').projectDir = new File('../../../android/plugin')
# capacitor.build.gradle - Comment out project dependency
// implementation project(':timesafari-daily-notification-plugin')
```
#### Step 2: Ensure AAR-Only Dependency
```gradle
# app/build.gradle
dependencies {
implementation(name: 'plugin-debug', ext: 'aar')
implementation 'androidx.work:work-runtime:2.9.0'
implementation 'androidx.lifecycle:lifecycle-service:2.7.0'
implementation 'com.google.code.gson:gson:2.10.1'
}
```
#### Step 3: Remove Duplicate Files
```bash
# Remove any duplicate classes.jar files
rm -f libs/classes.jar
rm -f libs/*.jar
# Clean and rebuild
./gradlew clean build
```
## Verification Steps
### 1. Check Dependency Tree
```bash
# Verify plugin is included only once
./gradlew :app:dependencies | grep timesafari
```
**Expected Output:**
```
+--- project :timesafari-daily-notification-plugin
```
**Problematic Output:**
```
+--- project :timesafari-daily-notification-plugin
+--- plugin-debug.aar
```
### 2. Build Verification
```bash
# Clean build should succeed
./gradlew clean assembleDebug
```
**Success Indicators:**
- ✅ Build completes without errors
- ✅ No duplicate class warnings
- ✅ APK generated successfully
### 3. Runtime Verification
```bash
# Install and test
adb install app/build/outputs/apk/debug/app-debug.apk
adb logcat | grep DailyNotification
```
**Success Indicators:**
- ✅ App launches without crashes
- ✅ Plugin detected in logs
- ✅ Plugin methods accessible
## Prevention Strategies
### 1. Consistent Approach Selection
**Choose One Approach:**
- **Development**: Use project reference for better debugging
- **Production**: Use AAR for simpler distribution
- **Never Mix**: Don't use both approaches simultaneously
### 2. Gradle Cache Management
**Regular Maintenance:**
```bash
# Weekly cache cleanup
./gradlew --stop
rm -rf ~/.gradle/caches
```
**Before Major Changes:**
```bash
# Clear cache before switching approaches
rm -rf ~/.gradle
```
### 3. Project Structure Validation
**Verify Paths:**
```bash
# Check project structure
ls -la ../../../android/plugin/
ls -la libs/
```
**Validate Configuration:**
```bash
# Check Gradle configuration
./gradlew :app:dependencies --configuration debugRuntimeClasspath
```
## Best Practices
### 1. Development Workflow
**Initial Setup:**
1. Choose integration approach (project reference recommended)
2. Configure all necessary files
3. Clear Gradle cache
4. Build and test
**Ongoing Development:**
1. Avoid switching approaches mid-development
2. Clear cache when making structural changes
3. Test integration after major updates
### 2. Configuration Management
**File Organization:**
- Keep `capacitor.settings.gradle` minimal
- Use `capacitor.build.gradle` for dependencies
- Maintain `capacitor.plugins.json` for discovery
**Version Consistency:**
- Use consistent Android Gradle Plugin versions
- Align Gradle wrapper versions
- Match dependency versions across modules
### 3. Testing Strategy
**Build Testing:**
- Test both debug and release builds
- Verify on multiple Android versions
- Check dependency resolution
**Runtime Testing:**
- Test plugin functionality
- Verify permission handling
- Check background task execution
## Troubleshooting Checklist
### Before Starting
- [ ] Clear Gradle cache (`rm -rf ~/.gradle`)
- [ ] Stop Gradle daemon (`./gradlew --stop`)
- [ ] Verify project structure
- [ ] Check file permissions
### During Integration
- [ ] Use only one integration approach
- [ ] Verify all configuration files
- [ ] Check dependency tree
- [ ] Test build process
### After Integration
- [ ] Verify app launches
- [ ] Test plugin functionality
- [ ] Check logs for errors
- [ ] Validate permissions
### Common Mistakes
- [ ] Mixing project reference and AAR approaches
- [ ] Incorrect project paths
- [ ] Forgetting to clear Gradle cache
- [ ] Missing required dependencies
- [ ] Incorrect plugin discovery configuration
## Support and Resources
### Documentation
- [BUILDING.md](../BUILDING.md) - Main build documentation
- [INTEGRATION_GUIDE.md](../INTEGRATION_GUIDE.md) - Integration guide
- [API.md](../API.md) - Plugin API documentation
### Community
- [GitHub Issues](https://github.com/timesafari/daily-notification-plugin/issues)
- [Capacitor Community](https://github.com/ionic-team/capacitor/discussions)
### Tools
- `./gradlew :app:dependencies` - Dependency analysis
- `adb logcat | grep DailyNotification` - Runtime debugging
- `./gradlew clean build` - Clean build verification
---
**Remember**: The key to successful AAR integration is consistency. Choose one approach, configure it properly, and maintain it throughout development. When in doubt, clear the Gradle cache and start fresh.
Loading…
Cancel
Save