apache/dubbo · error · IllegalArgumentException

non-public interfaces class from different packages

Error message

non-public interfaces class from different packages

What it means

Thrown by Mixin.mixin when two or more DELEGATE classes (the dcs array) are non-public AND come from different Java packages. Dubbo generates a single mixin class in one package; non-public types from other packages cannot be referenced there, so the JVM would reject the bytecode. The guard fails fast with IllegalArgumentException.

Solutions

  1. Make the delegate classes public so the generated mixin can reference them from any package.
  2. Restrict all non-public delegates to the same single package.
  3. Wrap the non-public delegates behind a public facade before passing them to Mixin.

Example fix

// before
package a.b;
class DelegateA {} // package-private
package c.d;
class DelegateB {} // package-private
Mixin.mixin(ics, new Class[]{ DelegateA.class, DelegateB.class });

// after
package a.b;
public class DelegateA {} // make public (or keep all delegates in one package)
Defensive patterns

Strategy: validation

Validate before calling

for (Class<?> dc : dcs) {
    if (!Modifier.isPublic(dc.getModifiers())) {
        // ensure all non-public delegates share one package
    }
}

Prevention

When it happens

Trigger: Mixin.mixin(ics, dcs) where dcs contains package-private delegate classes whose packages differ from each other (or from the first non-public delegate).

Common situations: Passing internal/package-private implementation classes from multiple modules as delegates; mixing delegates from library A (package a.b) and library B (package c.d), both non-public.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/dc9ee7285a6b0838. Report an issue: GitHub.

Appendix: source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Mixin.java:98

    public static Mixin mixin(Class<?>[] ics, Class<?>[] dcs, ClassLoader cl) {
        assertInterfaceArray(ics);

        long id = MIXIN_CLASS_COUNTER.getAndIncrement();
        String pkg = null;
        ClassGenerator ccp = null, ccm = null;
        try {
            ccp = ClassGenerator.newInstance(cl);

            // impl constructor
            StringBuilder code = new StringBuilder();
            for (int i = 0; i < dcs.length; i++) {
                if (!Modifier.isPublic(dcs[i].getModifiers())) {
                    String npkg = dcs[i].getPackage().getName();
                    if (pkg == null) {
                        pkg = npkg;
                    } else {
                        if (!pkg.equals(npkg)) {
                            throw new IllegalArgumentException("non-public interfaces class from different packages");
                        }
                    }
                }

                ccp.addField("private " + dcs[i].getName() + " d" + i + ";");

                code.append('d')
                        .append(i)
                        .append(" = (")
                        .append(dcs[i].getName())
                        .append(")$1[")
                        .append(i)
                        .append("];\n");
                if (MixinAware.class.isAssignableFrom(dcs[i])) {
                    code.append('d').append(i).append(".setMixinInstance(this);\n");
                }
            }
            ccp.addConstructor(Modifier.PUBLIC, new Class<?>[] {Object[].class}, code.toString());

View on GitHub (pinned to 3a3043227f)