Any clues on this one folks <https://stackoverflow...
# gradle
r
m
Try adding the Android library plugin to the parent build.gradle.kts with
apply false
. Only if a plugin is in the
plugins
block synthetic accessors like
android {}
will get created.
r
Added
Copy code
plugins {
  id(Plugin.androidApp) apply false
}
right under the top level
build.gradle
buildscript block And error message in child module is slightly different
Copy code
app/build.gradle.kts' line: 4

* What went wrong:
Plugin [id: 'com.android.application'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (plugin dependency must include a version number for this source)
m
You’ll need both, the Android library plugin and the Kotlin Android plugin
the latter depends on the former
r
Just tried with both in the parent build file. Same result. This doesn't seem right to me, why would I apply a plugin to all modules, even when some of them are not of that type ?
m
You don’t apply them if you use
apply false
, you merely load them. Unless the Android plugin is loaded Gradle doesn’t know that it should create plugin-specific Kotlin accessors like
android { … }
.
r
Ah ok, that makes sense.
m
Unfortunately it doesn’t seem to create the accessors unless the plugin is indeed applied 😕
r
Yep, looks like it. Although the error message is complaining in the child module
app/
. So I'm wondering if I missing something else here 🤔
m
You need to actually apply the plugins in the submodules
but still, I can’t use
android {}
in the parent with
apply false
☹️ 1
r
It's applied in all the children modules already
m
It's definitely not as good but maybe you can do without typesafety until there's a solution:```extensions.getByName("android") as BaseAppModuleExtension```
Also: shouldn't you invoke
project.android
in the root gradle file and not just
android
?
e
Posted to SO 🙂
stackoverflow 1
👍 1
r
Thanks! That worked. Now I am stuck on a different problem with the parent
build.gradle.kts
not finding the
com.android.application
plugin for it to use, even though it's in the
buildscript
block
Copy code
buildscript {
  repositories {
    google()
    mavenCentral()
  }
  dependencies {
    classpath(Classpath.androidGradle)
    classpath(Classpath.kotlinGradle)
  }
}

plugins {
  id(Plugin.androidApp) version "3.4.2" apply false
  id(Plugin.kotlinAndroid) version "1.3.41" apply false
}
Copy code
project-root/build.gradle.kts' line: 22

* What went wrong:
Plugin [id: 'com.android.application', version: '3.4.2', apply: false] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'com.android.application:com.android.application.gradle.plugin:3.4.2')
  Searched in the following repositories:
    Gradle Central Plugin Repository
e
When you use the
plugins
block, it is evaluated first (in my opinion, even before buildscript block). As you can see Gradle tries to resolve the plugins from the core (/bundled) plugins and then from the gradle plugin repository. But the android (and kotlin) gradle plugin(s) is(are) not published to the gradle plugin portal 🙂. To aid Gradle in resolving the plugin you will need to add this block to the project-level
settings.gradle(.kts)
file.
Copy code
pluginManagement {
  repositories {
    google()
    mavenCentral()
    gradlePluginPortal() // 
  }
  resolutionStrategy {
    eachPlugin {
      if (requested.id.id.startsWith("com.android.")) useModule(Plugin.androidApp)
      // ... add declaration for kotlin gradle plugin too
    }
  }
}
m
Don't use a version number for the android plugin because you already pass it when loading via classpath. Afaik it will cause Gradle to look in the repos instead where it can't find the plugin
r
@Marc Knaup removing the version did not solve the issue. It just failed with the same error, but shorter, as it could try to fetch the plugin from the repository without having a version
@efemoney that moved things forward a bit. However now I'm facing a different issue and it is starting to look like going down the rabbit hole.
Copy code
Build file '/application/build.gradle.kts' line: 4
An exception occurred applying plugin request [id: 'com.android.application', artifact: 'com.android.tools.build:gradle:3.4.2']
> Failed to apply plugin [class 'org.gradle.api.plugins.BasePlugin']
   > Extension of type 'BaseExtension' does not exist. Currently registered extension types: [ExtraPropertiesExtension, DefaultArtifactPublicationSet]
m
I've lost track of how your project is structured 😅 I'm using
buildSrc
to load the Android Gradle Plugin, not
buildscript
. No idea if there's a difference.
e
@robertoestivill The
BasePlugin
class you need to check for is the android one 😄 and it has a generic type parameter (before agp version 3.6.0-alpha06) so
Copy code
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.BasePlugin
and then
plugins.withType<BasePlugin<*>> { ... }
@Marc Knaup I was gonna get there next after walking @robertoestivill through his case.
r
I guess it got to the point where I should explain a bit better the way things are structured and what I'm trying to accomplish Basically, I have a multimodule project with a layout similar to (simplified)
Copy code
application/       -> android application module (depends on all features)
buildSrc/          -> kotlin dsl enabled
feature-a/         -> android library
feature-b/         -> android library
feature-c/         -> android library
...
build.gradle       -> parent gradle
settings.gradle
buildSrc
was created to expose kotlin constants with the dependencies coordinates, versions, android configuration, etc. No logic was included in buildSrc, just constants that we wanted to define in a single place. All gradle files were written in Groovy until I started working on this. The tricky part that triggered this conversation and the StackOverflow issue is in the parent
build.gradle
. This script configured all the children modules common
android { }
blocks in a single place, allowing children modules to just apply plugins and dependencies, and have a single point of configuration for all ocurrences of the android plugin. The current state of things was not intentionally decided or designed so I understand your concerns about how is this working. However, this is more the result of the evolution of the codebase coming from people like me, not really experts on gradle, other than something we created from scratch or consciously decided on. Now, I have migrated all the children modules build scripts to kotlin and that works fine as long as I don't migrate the parent groovy build.gradle, but I am struggling to replicate the behavior that the parent script had on it's equivalent kotlin version. Sorry for the confusion, and thanks for the help so far 🙂
r
@efemoney yes! it moved one step forward, now onto deal with Crashlytics haha. But yes, at least the build gets configured and the execution is started properly. Will love to understand more about all this, as I'm definitely not understanding the logic behind all this configuration. Any resource to read on? Thanks again
e
The Gradle documentation is pretty complete with all of this information. For kotlin dsl I always recommend starting at the kotlin dsl primer https://docs.gradle.org/current/userguide/kotlin_dsl.html
r
Thanks again @efemoney this has been quite informative, will take a look at that 👍
g
Also, this doesn't really solve the problem of generated accessors
buildSrc also can help with it, if you move configuration to precompiled script plugin
104 Views