apache/cordova-android · error · CordovaError

Unsupported system library (does not work with gradle): ${p}

Error message

Unsupported system library (does not work with gradle): ${p}

What it means

For each colon-free `cordova.system.library.N` entry (systemLibs), ProjectBuilder either passes it through as gradle coordinates (two colons), warns and passes it through as a BoM-style ref (one colon), or maps legacy SDK paths via SYSTEM_LIBRARY_MAPPINGS (extras/android/support/... -> com.android.support:support-*:+, google_play_services_libproject -> com.google.android.gms:play-services:+). Thrown when the value matches none of these - an old-style system library reference that gradle cannot consume.

Source

Thrown at lib/builders/ProjectBuilder.js:270

        propertiesObj.systemLibs.forEach(function (p) {
            let mavenRef;
            // It's already in gradle form if it has two ':'s
            if (/:.*:/.exec(p)) {
                mavenRef = p;
            } else if (/:.*/.exec(p)) {
                // Support BoM imports
                mavenRef = p;
                events.emit('warn', 'Library expects a BoM package: ' + p);
            } else {
                for (let i = 0; i < SYSTEM_LIBRARY_MAPPINGS.length; ++i) {
                    const pair = SYSTEM_LIBRARY_MAPPINGS[i];
                    if (pair[0].exec(p)) {
                        mavenRef = p.replace(pair[0], pair[1]);
                        break;
                    }
                }
                if (!mavenRef) {
                    throw new CordovaError('Unsupported system library (does not work with gradle): ' + p);
                }
            }
            depsList += '    implementation "' + mavenRef + '"\n';
        });

        buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + '    $2');
        let includeList = '';

        propertiesObj.gradleIncludes.forEach(function (includePath) {
            includeList += 'apply from: "../' + includePath + '"\n';
        });
        buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\s\S]*(\/\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\n' + includeList + '$2');
        // This needs to be stored in the app gradle, not the root grade
        fs.writeFileSync(path.join(this.root, 'app', 'build.gradle'), buildGradle);
    }

    prepEnv (opts) {
        const self = this;

View on GitHub (pinned to 7c1e190064)

Solutions

  1. Replace the entry with Maven coordinates: `cordova.system.library.2=com.google.code.gson:gson:2.10.1`.
  2. If the jar has no Maven artifact, reference it from app/build.gradle directly (implementation files('libs/x.jar')) and remove the project.properties line.
  3. Remove the legacy plugin/library if unused.
  4. Fix the plugin's <lib>/<framework> declaration upstream so it emits gradle coordinates.

Example fix

# before
cordova.system.library.2=libs/gson.jar

# after
cordova.system.library.2=com.google.code.gson:gson:2.10.1
Defensive patterns

Strategy: validation

Validate before calling

const LEGACY = [
  /^\/?extras\/android\/support\/(.*)$/,
  /^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/
];
const isUsableSystemLib = (v) => /:.*:/.test(v) || /:/.test(v) || LEGACY.some(rx => rx.test(v));

const props = fs.readFileSync('platforms/android/project.properties', 'utf8');
for (const m of props.matchAll(/^\s*cordova\.system\.library\.\d+=(\S+)/gm)) {
  if (!isUsableSystemLib(m[1])) {
    throw new Error(`'${m[1]}' is not gradle-compatible - convert to group:name:version`);
  }
}

Type guard

const isGradleDependencyRef = (v) => /:/.test(v) || /^extras\/android\/support\//.test(v) || /^google\/google_play_services\//.test(v);

Try / catch

try {
  await androidApi.build(opts);
} catch (e) {
  if (/Unsupported system library/.test(e.message)) {
    // the message names the offending value; find its cordova.system.library.N line and convert it
  }
  throw e;
}

Prevention

When it happens

Trigger: A project.properties line like `cordova.system.library.2=libs/gson.jar` or `/libs/mylib.jar` - no colon, not one of the two legacy SDK path patterns. Reached during build prep when the dependency block of app/build.gradle is written.

Common situations: Legacy pre-gradle Cordova plugins declaring <lib src="...jar"> style references; hand-added jar paths; plugin never updated for gradle-based builds.

Related errors


AI-assisted analysis of apache/cordova-android@7c1e190064 (2026-08-22). Data as JSON: /api/errors/3f93ce99d76f043e. Report an issue: GitHub.