# 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 org.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": "org.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": "org.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://gitea.anomalistdesign.com/trent_larson/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.
