pxb1988/dex2jar · error · RuntimeException

array is used multiple times

Error message

array is used multiple times

What it means

FillArrayTransformer lowers filled-array IR (fill-array-data). For each created array it expects either exactly one use of the array or zero uses. If the array local is referenced more than once after creation (it cannot rewrite a filled array whose reference escapes to multiple consumers), it throws this RuntimeException.

Solutions

  1. Re-check which pass duplicated the array local's uses; run SSA/local renaming so each value has one use
  2. Keep FillArrayTransformer ordered after the passes it depends on (as in the default Transform pipeline)
  3. Rewrite the method to use the array reference only once before translation
  4. Catch the exception and fall back to skipping fill-array lowering for that method

Example fix

// guard in caller
try {
    method = new FillArrayTransformer().transform(method);
} catch (RuntimeException e) {
    if (!e.getMessage().startsWith("array is used")) throw e;
    LOG.warn("skipping fill-array transform for " + method); // keep untransformed method
}
Defensive patterns

Strategy: validation

Validate before calling

// before transforming, assert single use of filled-array locals
for (Local arr : filledArrayLocals) {
    if (method.countUsesOf(arr) > 1) {
        throw new IllegalStateException("array local " + arr + " used multiple times");
    }
}

Try / catch

try {
    method = new FillArrayTransformer().transform(method);
} catch (RuntimeException e) {
    if (e.getMessage() == null || !e.getMessage().contains("array is used multiple times")) throw e;
    // keep untransformed method
}

Prevention

When it happens

Trigger: Running FillArrayTransformer.transform on an IrMethod where a Local holding a filled-array value (NewFilledArrayExpr) is used by more than one statement, so ao.used.size() > 1.

Common situations: DEX code that copies a filled-array reference into several registers or passes it to two calls; IR produced by earlier passes that duplicated local uses without SSA renaming.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of pxb1988/dex2jar@b5bda4fb49 (2026-09-08). Data as JSON: /api/errors/82690e4c056f6abf. Report an issue: GitHub.

Appendix: source

Thrown at dex-ir/src/main/java/com/googlecode/dex2jar/ir/ts/array/FillArrayTransformer.java:220

                    }
                    return v;
                }
            };

            if (ao.used.size() == 1) {
                Stmt stmt = ao.used.get(0);
                if (method.stmts.contains(stmt)) { // the stmt is not removed by pre array replacement
                    Cfg.travelMod(stmt, tcb, false);
                } else {
                    int size = filledArrayExprs.size();
                    for (int i = 0; i < size; i++) {
                        Cfg.travelMod(filledArrayExprs.get(i), tcb);
                    }
                }
            } else if (ao.used.size() == 0) {
                // the array is never used, ignore
            } else {
                throw new RuntimeException("array is used multiple times");
            }
        }
    }

    // FIXME poor performance
    private void makeSureArrayUsedAfterAllElementAssigned(IrMethod method, final Map<Local, ArrayObject> arraySizes) {

        for (Local local : method.locals) {
            local._ls_index = -1;
        }
        final int MAX = 50;
        if (arraySizes.size() < MAX) {
            makeSureArrayUsedAfterAllElementAssigned0(method, arraySizes);
        } else {

            // this method consumes too many memory, case 'java.lang.OutOfMemoryError: Java heap space', we have to cut
            // it
            Map<Local, ArrayObject> keptInAll = new HashMap<>();

View on GitHub (pinned to b5bda4fb49)