{"record":{"id":"3f93ce99d76f043e","repo":"apache/cordova-android","slug":"unsupported-system-library-does-not-work-with-gra","errorCode":null,"errorMessage":"Unsupported system library (does not work with gradle): ${p}","messagePattern":"Unsupported system library \\(does not work with gradle\\): (.+?)","errorType":"validation","errorClass":"CordovaError","httpStatus":null,"severity":"error","filePath":"lib/builders/ProjectBuilder.js","lineNumber":270,"sourceCode":"        propertiesObj.systemLibs.forEach(function (p) {\n            let mavenRef;\n            // It's already in gradle form if it has two ':'s\n            if (/:.*:/.exec(p)) {\n                mavenRef = p;\n            } else if (/:.*/.exec(p)) {\n                // Support BoM imports\n                mavenRef = p;\n                events.emit('warn', 'Library expects a BoM package: ' + p);\n            } else {\n                for (let i = 0; i < SYSTEM_LIBRARY_MAPPINGS.length; ++i) {\n                    const pair = SYSTEM_LIBRARY_MAPPINGS[i];\n                    if (pair[0].exec(p)) {\n                        mavenRef = p.replace(pair[0], pair[1]);\n                        break;\n                    }\n                }\n                if (!mavenRef) {\n                    throw new CordovaError('Unsupported system library (does not work with gradle): ' + p);\n                }\n            }\n            depsList += '    implementation \"' + mavenRef + '\"\\n';\n        });\n\n        buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\\s\\S]*(\\/\\/ SUB-PROJECT DEPENDENCIES END)/, '$1\\n' + depsList + '    $2');\n        let includeList = '';\n\n        propertiesObj.gradleIncludes.forEach(function (includePath) {\n            includeList += 'apply from: \"../' + includePath + '\"\\n';\n        });\n        buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\\s\\S]*(\\/\\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\\n' + includeList + '$2');\n        // This needs to be stored in the app gradle, not the root grade\n        fs.writeFileSync(path.join(this.root, 'app', 'build.gradle'), buildGradle);\n    }\n\n    prepEnv (opts) {\n        const self = this;","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/apache/cordova-android/blob/7c1e190064e349ffa4bbc6ac37b77cd773e4dbd3/lib/builders/ProjectBuilder.js#L252-L288","documentation":"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.","triggerScenarios":"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.","commonSituations":"Legacy pre-gradle Cordova plugins declaring <lib src=\"...jar\"> style references; hand-added jar paths; plugin never updated for gradle-based builds.","solutions":["Replace the entry with Maven coordinates: `cordova.system.library.2=com.google.code.gson:gson:2.10.1`.","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.","Remove the legacy plugin/library if unused.","Fix the plugin's <lib>/<framework> declaration upstream so it emits gradle coordinates."],"exampleFix":"# before\ncordova.system.library.2=libs/gson.jar\n\n# after\ncordova.system.library.2=com.google.code.gson:gson:2.10.1","handlingStrategy":"validation","validationCode":"const LEGACY = [\n  /^\\/?extras\\/android\\/support\\/(.*)$/,\n  /^\\/?google\\/google_play_services\\/libproject\\/google-play-services_lib\\/?$/\n];\nconst isUsableSystemLib = (v) => /:.*:/.test(v) || /:/.test(v) || LEGACY.some(rx => rx.test(v));\n\nconst props = fs.readFileSync('platforms/android/project.properties', 'utf8');\nfor (const m of props.matchAll(/^\\s*cordova\\.system\\.library\\.\\d+=(\\S+)/gm)) {\n  if (!isUsableSystemLib(m[1])) {\n    throw new Error(`'${m[1]}' is not gradle-compatible - convert to group:name:version`);\n  }\n}","typeGuard":"const isGradleDependencyRef = (v) => /:/.test(v) || /^extras\\/android\\/support\\//.test(v) || /^google\\/google_play_services\\//.test(v);","tryCatchPattern":"try {\n  await androidApi.build(opts);\n} catch (e) {\n  if (/Unsupported system library/.test(e.message)) {\n    // the message names the offending value; find its cordova.system.library.N line and convert it\n  }\n  throw e;\n}","preventionTips":["Express every <lib>/<framework> dependency as Maven coordinates rather than jar paths.","Audit legacy plugins for pre-gradle declarations before upgrading cordova-android.","Keep local jars wired via app/build.gradle files(...) instead of project.properties."],"tags":["gradle","system-library","legacy-plugin","dependency-notation"],"backgroundTag":"unsupported-dependency-type","analyzedSha":"7c1e190064e349ffa4bbc6ac37b77cd773e4dbd3","analyzedAt":"2026-08-22T04:57:58.868Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}