Kelvin Chung
02/17/2025, 5:43 AMNamedDomainObjectContainer
, but applied to a NamedDomainObjectList
?jonathan gafner
02/18/2025, 11:33 AMFelix de Souza
02/18/2025, 3:35 PMProject#getVersion
going to be changed in Gradle 9 to be property aware? I thought it would, but I’m not seeing the annotation in the master
branch, unless there is another branch tracking 9.x ?Kelvin Chung
02/18/2025, 5:44 PMExtensiblePolymorphicDomainObjectContainer
? I have a BuildService
that contains an instance of it, and thus there are possible use cases for which duplicate registrations could happen.Kelvin Chung
02/18/2025, 6:24 PMabstract class MyExtension @Inject constructor(val service: Provider<MyService>) {
// ...
}
class MyPlugin : Plugin<PluginAware> {
override fun apply(target: PluginAware) {
val gradle = when (target) {
// ...
}
val service = gradle.sharedServices.registerIfAbsent(...)
}
}
The intent is that if the plugin was applied to a Project
, then I would create a MyExtension
object in the project's extension container, but if the plugin was applied to a Settings
, then the plugin would create a MyExtension
project in both the settings and every project (and similarly if the plugin was applied to a Gradle
. The question is: is that a good idea, and if so, how would I go about that?no
02/20/2025, 11:13 AM@Before
annotation had no effect (it's part of junit4).
Is there a systematic way of preventing junit4 classes from creeping in to my junit5 project? And also vice versa?Daniele Segato
02/28/2025, 8:43 AMinterface EnvironmentPluginExtension : Named {
val applicationId: Property<String?>
val applicationIdSuffix: Property<String?>
val versionNameSuffix: Property<String?>
val disableDebugBuild: Property<Boolean>
val disableReleaseBuild: Property<Boolean>
}
Than I in the plugin I had
pluginManager.apply("com.android.application")
val extension = extensions.getByType<ApplicationExtension>()
val envContainer = objects.domainObjectContainer(EnvironmentPluginExtension::class.java)
(extension as ExtensionAware).extensions.add("environments", envContainer)
envContainer.whenObjectAdded {
val customSuffix = applicationIdSuffix.orNull // always null
// ...
}
and used it to configure environments in the android application
from the build.gradle.kts file I could do stuff like this
android {
environments {
create("dev")
create("stage") {
applicationIdSuffix = ".staging"
}
}
}
I remember it used to work - but I used defaults values since I set this up.
now that I needed it - several gradle versions laters - I noticed it doesn’t work anymore
apparently whenObjectAdded
is now running BEFORE the domain object is configured (which is absurd imho).
I cannot use afterEvaluate
can anyone give me some way of achieving what I need?Vampire
02/28/2025, 11:55 AMProperty
times I had an @Internal
property that was set to either,
and then a derived @Optional @InputFile
read-only property
and a derived @Optional @InputDirectory
read-only property
which checked whether the internal property is a file or directory
and at execution time checked that exactly one of them is set.
I'm thinking about cleaner ways to rewrite this, without splitting the task into multiple tasks.Charlie Hubbard
02/28/2025, 6:40 PMapply
method looks like this:
class SslCertGenPlugin implements Plugin<Project> {
void apply(Project project) {
Security.addProvider(new BouncyCastleProvider())
CertificateExtension certificate = project.extensions.create( "certificate", CertificateExtension )
project.tasks.register("generateCert", X509Certificate, project, certificate )
}
}
However, in a multi-project build where the plugin could be applied to a subproject this doesn’t work. It assumes the plugin is defined at the root project even when it’s not. So how does a plugin know the difference? When it was applied at the root vs a subproject?Clayton Walker
03/05/2025, 9:12 PMsolonovamax
03/08/2025, 10:35 PMfun configureProject() {
project.configure<KotlinProjectExtension> {
if (this is HasConfigurableKotlinCompilerOptions<*>)
configureCommonCompilerOptions()
when (this) {
is KotlinJvmProjectExtension -> {
configureJvmCompilerOptions()
}
is KotlinMultiplatformExtension -> {
targets.withType<KotlinJvmTarget>().configureEach {
configureJvmCompilerOptions()
}
targets.withType<KotlinJsIrTarget>().configureEach {
configureJsCompilerOptions()
}
}
}
}
}
private fun HasConfigurableKotlinCompilerOptions<*>.configureCommonCompilerOptions() {
val nyx = this@NyxKotlinExtension
compilerOptions {
// ...
}
}
however, the problem I'm facing is that when I add this plugin to another project and this code gets executed, then the following exception will be thrown:
Caused by: java.lang.ClassCastException: class org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension_Decorated cannot be cast to class org.jetbrains.kotlin.gradle.dsl.HasConfigurableKotlinCompilerOptions (org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension_Decorated and org.jetbrains.kotlin.gradle.dsl.HasConfigurableKotlinCompilerOptions are in unnamed module of loader org.gradle.internal.classloader.VisitableURLClassLoader$InstrumentingVisitableURLClassLoader @47f6e669)
this makes absolutely no sense as to why it's occurring, as KotlinJvmProjectExtension
definitely inherits from HasConfigurableKotlinCompilerOptions
.
if you would like to see exactly what I'm doing, then that can be found here:
https://github.com/solo-studios/nyx/blob/ae325df6221244572757ff661767621c8de01262/src/main/kotlin/ca/solostudios/nyx/plugin/compile/NyxKotlinExtension.kt#L370-L439
you can test this behaviour by doing the following in any gradle project:
first, add the following to your `settings.gradle.kts`:
pluginManagement {
repositories {
maven("<https://maven.solo-studios.ca/snapshots/>")
mavenCentral()
gradlePluginPortal()
}
resolutionStrategy {
eachPlugin {
if (requested.id.id == "ca.solo-studios.nyx") {
useModule("ca.solo-studios:nyx:0.3.0-20250308.223428-37")
}
}
}
}
then, add the following to your `build.gradle.kts`:
plugins {
id("ca.solo-studios.nyx") version "0.3.0-SNAPSHOT"
}
re-import the project, and it will fail.
the source code for the entire project can be found on github.
edit: I have published a workaround, so you need to do funny resolution stuff to get the broken version.gmazzo
03/10/2025, 10:24 AMsinging
plugin to the project), we end up concluding the Plugin Portal
is somehow ignoring .asc
files, they are not there when requested by URL. Which is not the case for Maven Central's URL.
Does anyone knows if this an intentional behavior of Plugins Portal, or a bug?Benoît Liessens
03/11/2025, 6:25 PMclass QualityPlugin : Plugin<Project> {
override fun apply(target: Project) {
target.pluginManager.apply(DetektPlugin::class.java)
target.extensions.configure(DetektExtension::class.java) {
allRules = true
}
}
}
Now I have a project where I want to apply my QualityPlugin and, additionally, set a Detekt base line:
plugins {
id("my quality plugin name")
}
detekt {
baseline = file("config/detekt-baseline-test.xml")
}
I was expecting Gradle to graciously merge the allRules
and baseline
settings in the DetektExtension but alas. The baseline is ignored.
What am I doing wrong?
ThanksHarshjeet Patil
03/14/2025, 4:58 PMDenis Berestinsky
03/15/2025, 12:46 PMTransformAction
. There is a case when inputArtifact
for TransformAction
doesn't exist (But it has to be an output artifact of an another subproject). What's the proper way to handle this case? And what are the possible causes of it?Vampire
03/17/2025, 5:09 PMCircularReferenceException
in task ordering besides "just seeing the problem"?
I have a cycle and I have no idea where it comes from right now.Kelvin Chung
03/17/2025, 5:56 PMValueSource
, is there a serializability requirement on the parameters?
eg.
abstract class MyValueSource : ValueSource<String, MyValueSource.Parameters> {
interface Parameters : ValueSourceParameters {
val myClient: Property<MyClient>
}
}
vs.
abstract class MyValueSource : ValueSource<String, MyValueSource.Parameters> {
interface Parameters : ValueSourceParameters {
val myService: Property<MyService> // from a BuildService provider
val clientName: Property<String>
}
private val myClient = parameters.myService.zip(parameters.myClient) { ... }
}
I seem to recall that there being a case, but I want to make sure, since you can certainly design without.Ben Madore
03/18/2025, 1:34 PMmaven-publish
plugin, configuring publication. e.g.
val artifactName: Property<String> = project.objects.property(String::class.java)
used as
fooConventions {
artifactName = "my-artifact-name"
}
a few times we’ve run into issues where someone copy-pastes some code and duplicates the artifact name, this unfortunately isn’t caught until the jar file is attempted to be published to artifactory, and user gets an unclear message that the artifact has already been published, and they tend to think it’s a CI problem instead of a project problem.
What would be the most ideal way to validate that the configuration across all sub-projects does not contain any duplicates between each project’s conventions.artifactName
property? Is this a valid use of a Shared Build Service? I could do it simply at the top level project and reach down into the subprojects, but i think then it’d have to be in an afterEvaluate
which, as i understand it, is detrimental to config caching.no
03/21/2025, 8:02 AM<https://storage.googleapis.com/r8-releases/>
. I would normally add an ivy repository from my Gradle plugin to do this but this doesn't work if the consuming project has
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
}
I could use a Gradle task to download the jar but then it wouldn't be cached like a dependency download is. Are there other alternatives here?Ben Bader
03/21/2025, 3:25 PMjava.nio.file.Path
into a FileTreeElement
? The paths are not guaranteed to point to files within the Gradle project; my interest here is in using a PatternSet
to filter them, but the spec it creates only operates on FileTreeElement
instances.
Is such a thing even possible with the public API?Slackbot
03/23/2025, 7:59 AMKarunakara NH
03/25/2025, 7:37 AMLebomodiko
03/25/2025, 9:01 AMClayton Walker
03/26/2025, 4:18 PMextension {
version = configuraitons.oneOfThem.incoming.platforms.matching("spring-boot-dependencies").versionOf("some-sub-dep")
}
That way I lazily retrieve a sub-version of a bomSergey Morgunov
03/26/2025, 5:36 PMcom.example.myplugin
Working version so far:
com.example.myplugin-java
com.example.myplugin-scala
But I don’t really like this mixing of separators 🙃RTAkland
04/03/2025, 5:20 AMtarget.extensions.getByType(KotlinMultiplatformExtension::class.java)
.sourceSets.findByName(it.value.targetName)?.kotlin
?.srcDir("build/generated/kotlin/${it.value.targetName}")
but it not work, only commonMain sourceSet are be setSuhas Sharma
04/07/2025, 5:22 PMKevin Brightwell
04/10/2025, 8:06 PMdependencyProject
property anymore. What is the Gradle 9 way to do this?Adam
04/11/2025, 10:12 AMincludeBuild
the directory in our settings script
This works fine, however, I want to add all these plugins to the project classpath as such by adding them to the root project build script
plugins {
alias(libs.plugins.internal.company.plugin) apply false
alias(libs.plugins.internal.company.otherPlugin) apply false
// etc
}
When I do this, it works fine until I include the build for local iteration. I basically can’t sync because of the following error Error resolving plugin [id: 'plugin.name', version: '1.0.43'] > The request for this plugin could not be satisfied because the plugin is already on the classpath with an unknown version, so compatibility cannot be checked.
I’m guessing this happens because when I include the build, gradle seems to add the plugins in it to the classpath with an unknown
version, but then also tries to grab the latest published versions since I’m also trying to add them to the classpath, thus creating a conflict. Is there any way to work around this or will I have to resort to just commenting out my plugins from the plugins
block whenever I want to work on them locally?Callum Rogers
04/14/2025, 2:12 PMConfiguration
with custom attributes a la https://docs.gradle.org/current/userguide/cross_project_publications.html#sec:variant-aware-sharing? Or is there some other way to safely read data from other projects?