---
title: "ProGuard Setup for Dex Protection"
description: "Required ProGuard/R8 configuration when using DoveRunner Dex Protection on Android."
---
> For the complete documentation index, see [llms.txt](/llms.txt).

import { Aside } from '@astrojs/starlight/components';

<Aside type="caution">
This guide applies to sealing versions **3.0.0.0 – 3.1.0.0**. The requirement may change in 3.2.0.0 and later — check the release notes for your sealing version before applying these rules.
</Aside>

When Dex Protection is enabled, DoveRunner identifies your business code by locating packages declared in the APK/AAB manifest. If ProGuard or R8 has repackaged those classes elsewhere, DoveRunner may not be able to find them — and they won't be obfuscated.

The fix is a single rule that tells ProGuard/R8 to preserve your package structure while still obfuscating class and member names.

## Required Rule

Add the following to your `proguard-rules.pro`, replacing `com.example` with your app's base package name:

```proguard
-keeppackagenames 'com.example.**'
```

This preserves the package path as-is while class, method, and field names are still obfuscated normally.

| Original | After obfuscation |
| :------- | :---------------- |
| `com.example.api.UserService.fetchUser()` | `com.example.api.a.b()` |
| `com.example.model.Profile.userName` | `com.example.model.c.a` |

## Rules to Avoid

The following rules relocate or flatten package paths and will break the package structure that DoveRunner relies on. Avoid using them alongside `-keeppackagenames`:

```proguard
-repackageclasses 'x'
-flattenpackagehierarchy 'x'
```

<Aside>
These rules are not applied by R8 by default and are not included in `proguard-android-optimize.txt`. You are safe unless you or a third-party library explicitly added them. Check your external library consumer-rules if you are unsure.
</Aside>

## Library Compatibility

`-keeppackagenames` only preserves package paths — class and member names are still obfuscated. Some libraries require additional ProGuard rules to function correctly at runtime (for example, libraries that rely on reflection or serialization).

If a library you use provides its own required ProGuard rules, apply them as-is. `-keeppackagenames` does not interfere with standard `-keep` rules for specific classes or members, so there is no conflict as long as you avoid the package-relocating rules listed above (`-repackageclasses`, `-flattenpackagehierarchy`).

## Verifying the Setup

After a release build, open the mapping file and confirm that package paths are preserved while class names are obfuscated:

```
app/build/outputs/mapping/release/mapping.txt
```

Expected output:

```
com.example.api.UserService -> com.example.api.a:
    void fetchUser() -> b
com.example.model.Profile -> com.example.model.c:
    java.lang.String userName -> a
```

The package path (`com.example.api`, `com.example.model`) must be intact, and class/member names must be replaced with short symbols.

<details>
<summary>AGP version compatibility details</summary>

`-keeppackagenames` works correctly across all AGP versions. The main difference is how aggressively R8 optimizes in each mode.

| AGP Version | R8 Mode | Notes |
| :---------- | :------ | :---- |
| < 3.4 | ProGuard | Works normally |
| 3.4 – 6.x | R8 compat mode | Existing rules work mostly as-is |
| 7.0 – 7.x | R8 full mode (opt-in) | Enable via `android.enableR8.fullMode=true` |
| 8.0+ | R8 full mode (default) | More aggressive: class merging, inlining |
| 9.x+ | R8 full mode + extra optimizations | See official release notes |

In R8 full mode, some classes inside a preserved package may disappear due to merging or inlining. This is expected behavior and does not affect DoveRunner's ability to identify and obfuscate the package — as long as surviving classes retain their package paths.

</details>