{"record":{"id":"8633016ba9e262b8","repo":"Tencent/tinker","slug":"this-plugin-must-be-applied-after-java-or-com-a","errorCode":null,"errorMessage":"This plugin must be applied after \"java\" or \"com.android.library\" plugin","messagePattern":"This plugin must be applied after \"java\" or \"com\\.android\\.library\" plugin","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"gradle/WeChatPublish.gradle","lineNumber":13,"sourceCode":"\ndef extensionClass\n\n// Detect supported plugin modules\nif (plugins.hasPlugin('com.android.library')) {\n    // Android library mode\n    extensionClass = WeChatAndroidLibraryPublishExtension.class\n} else if (plugins.hasPlugin('java')) {\n    // Java library mode\n    extensionClass = WeChatJavaLibraryPublishExtension.class\n} else {\n    // TODO: Support more languages\n    throw new GradleException('This plugin must be applied after \"java\" or \"com.android.library\" plugin')\n}\n\n// Register wechatPublish extension\nextensions.create('wechatPublish', extensionClass, project)\next.artifactId = name\n\nclass WeChatPublishExtension {\n\n    boolean isSnapshot = true\n    private String versionSuffix = ''\n    protected boolean printModules = false\n\n    boolean withJavadoc = true\n    boolean withSources = true\n    boolean withNativeSymbols = true\n    boolean withDependencies = true\n\n    boolean publishToBintray = false /* Deprecated */","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/gradle/WeChatPublish.gradle#L1-L31","documentation":"This GradleException is thrown by gradle/WeChatPublish.gradle when the wechatPublish script is applied to a project in which neither the 'com.android.library' nor the 'java' Gradle plugin has already been applied. The script branches at apply time on plugins.hasPlugin(...) to pick the right extension class (WeChatAndroidLibraryPublishExtension vs WeChatJavaLibraryPublishExtension); if neither plugin is present it cannot build a publishing extension, so it aborts. It is a pure plugin-ordering/configuration contract violation, not a runtime failure.","triggerScenarios":"Applying 'gradle/WeChatPublish.gradle' (or a plugin that applies it) in a module where: (a) apply from: ...WeChatPublish.gradle appears BEFORE apply plugin: 'java' / 'com.android.library'; (b) the module only applies 'com.android.application' (an app module, not a library); (c) the module applies none of the supported plugins at all (e.g. a plain groovy/kotlin/server module — the source comment says 'TODO: Support more languages').","commonSituations":"Copying the publish script into an app module of the Tinker sample; reordering plugin/apply-from statements while refactoring root or module build scripts; using the script in an Android application project assuming it publishes APKs; hoisting the apply from into allprojects/subprojects blocks where some subprojects are not java/android-library modules.","solutions":["In the module's build.gradle, ensure 'java' (or 'com.android.library') is applied BEFORE the line 'apply from: <path>/WeChatPublish.gradle'.","If the module is an Android app (com.android.application), move wechatPublish to a library module — the script only supports Java/Android library publishing.","If you need it in a multi-module build, apply it selectively: subprojects { if (it.plugins.hasPlugin('java') || it.plugins.hasPlugin('com.android.library')) apply from: rootProject.file('gradle/WeChatPublish.gradle') }.","If you control the script, use pluginManager.withPlugin('java') { ... } / withPlugin('com.android.library') { ... } hooks instead of an immediate hasPlugin check so apply order no longer matters."],"exampleFix":"// before (app/build.gradle)\napply from: rootProject.file('gradle/WeChatPublish.gradle')\napply plugin: 'com.android.library'\n\n// after\napply plugin: 'com.android.library'\napply from: rootProject.file('gradle/WeChatPublish.gradle')","handlingStrategy":"validation","validationCode":"// in the module (or a root allprojects hook) BEFORE applying the publish script\nif (!plugins.hasPlugin('java') && !plugins.hasPlugin('com.android.library')) {\n    throw new GradleException(\"wechatPublish requires 'java' or 'com.android.library' first\")\n}\napply from: rootProject.file('gradle/WeChatPublish.gradle')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always apply plugin: 'java' or 'com.android.library' before apply from WeChatPublish.gradle.","Never apply this script to com.android.application modules; it publishes libraries only.","In multi-module builds, guard the apply with a hasPlugin check per subproject."],"tags":["gradle","build","publishing","plugin-order","configuration"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}