From b153267e8dbee9cbc1d4baca6870e09765b8d57e Mon Sep 17 00:00:00 2001 From: Uwe Date: Tue, 3 Mar 2026 07:10:13 +0100 Subject: [PATCH 01/17] Plugin apply tests: use Gradle constants to get names --- .../gradle/PluginApplyAndroidTest.kt | 11 ++++++----- .../objectbox/gradle/PluginApplyJavaTest.kt | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt index 4b809c1f..f6741969 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt @@ -20,6 +20,7 @@ package io.objectbox.gradle import org.gradle.api.Project import org.gradle.api.artifacts.DependencySet +import org.gradle.api.plugins.JavaPlugin import org.gradle.testfixtures.ProjectBuilder import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull @@ -46,9 +47,9 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { project.enableObjectBoxPluginDebugMode() with(project.configurations) { - assertProcessorDependency(getByName("annotationProcessor").dependencies) - assertAndroidDependency(getByName("api").dependencies) - assertNativeDependency(getByName("testImplementation").dependencies) + assertProcessorDependency(getByName(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME).dependencies) + assertAndroidDependency(getByName(JavaPlugin.API_CONFIGURATION_NAME).dependencies) + assertNativeDependency(getByName(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME).dependencies) } assertNotNull(project.tasks.findByPath("objectboxPrepareBuild")) @@ -88,8 +89,8 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { private fun assertKotlinAndroidSetup(project: Project) { with(project.configurations) { assertProcessorDependency(getByName("kapt").dependencies) - assertAndroidDependency(getByName("api").dependencies) - assertNativeDependency(getByName("testImplementation").dependencies) + assertAndroidDependency(getByName(JavaPlugin.API_CONFIGURATION_NAME).dependencies) + assertNativeDependency(getByName(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME).dependencies) } assertNotNull(project.tasks.findByPath("objectboxPrepareBuild")) diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt index 8fcee019..d42a13b6 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt @@ -23,6 +23,7 @@ import org.gradle.api.artifacts.DependencySet import org.gradle.api.internal.plugins.PluginApplicationException import org.gradle.api.internal.project.ProjectInternal import org.gradle.api.plugins.InvalidPluginException +import org.gradle.api.plugins.JavaPlugin import org.gradle.testfixtures.ProjectBuilder import org.hamcrest.CoreMatchers.instanceOf import org.hamcrest.MatcherAssert.assertThat @@ -84,7 +85,7 @@ open class PluginApplyJavaTest : PluginApplyTest() { } project.enableObjectBoxPluginDebugMode() - assertJavaProject(project, "implementation") + assertJavaProject(project, JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) } @Test @@ -96,7 +97,7 @@ open class PluginApplyJavaTest : PluginApplyTest() { } project.enableObjectBoxPluginDebugMode() - assertJavaProject(project, "implementation") + assertJavaProject(project, JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) } @Test @@ -108,12 +109,12 @@ open class PluginApplyJavaTest : PluginApplyTest() { } project.enableObjectBoxPluginDebugMode() - assertJavaProject(project, "api") + assertJavaProject(project, JavaPlugin.API_CONFIGURATION_NAME) } private fun assertJavaProject(project: Project, configuration: String) { with(project.configurations) { - assertProcessorDependency(getByName("annotationProcessor").dependencies) + assertProcessorDependency(getByName(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME).dependencies) getByName(configuration).dependencies.let { assertJavaDependency(it) @@ -127,8 +128,8 @@ open class PluginApplyJavaTest : PluginApplyTest() { // AFTER EVALUATE. // Note: by default only main and test source sets exist. - assertTransformTask(project, "", "classes") - assertTransformTask(project, "Test", "testClasses") + assertTransformTask(project, "", JavaPlugin.CLASSES_TASK_NAME) + assertTransformTask(project, "Test", JavaPlugin.TEST_CLASSES_TASK_NAME) } private fun assertTransformTask( @@ -181,7 +182,7 @@ open class PluginApplyJavaTest : PluginApplyTest() { with(project.configurations) { assertProcessorDependency(getByName("kapt").dependencies) - getByName("api").dependencies.let { deps -> + getByName(JavaPlugin.API_CONFIGURATION_NAME).dependencies.let { deps -> assertEquals(1, deps.count { it.group == "io.objectbox" && it.name == "objectbox-kotlin" && it.version == ProjectEnv.Const.javaVersionToApply @@ -198,8 +199,8 @@ open class PluginApplyJavaTest : PluginApplyTest() { // AFTER EVALUATE. // Note: by default only main and test source sets exist. // Note: transform is not supported for Kotlin code/tasks, so these match plain Java plugin. - assertTransformTask(project, "", "classes") - assertTransformTask(project, "Test", "testClasses") + assertTransformTask(project, "", JavaPlugin.CLASSES_TASK_NAME) + assertTransformTask(project, "Test", JavaPlugin.TEST_CLASSES_TASK_NAME) } private fun assertProcessorDependency(apDeps: DependencySet) { From 2cf872c327945bab82c6c7a414f9cf85a870016d Mon Sep 17 00:00:00 2001 From: Uwe Date: Tue, 3 Mar 2026 07:22:12 +0100 Subject: [PATCH 02/17] Plugin tests: extract common project builder code --- .../gradle/PluginApplyAndroidTest.kt | 37 +++++++------ .../objectbox/gradle/PluginApplyJavaTest.kt | 52 +++++++++---------- .../io/objectbox/gradle/PluginApplyTest.kt | 11 ++++ 3 files changed, 55 insertions(+), 45 deletions(-) diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt index f6741969..e13cbc94 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt @@ -21,7 +21,6 @@ package io.objectbox.gradle import org.gradle.api.Project import org.gradle.api.artifacts.DependencySet import org.gradle.api.plugins.JavaPlugin -import org.gradle.testfixtures.ProjectBuilder import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Test @@ -39,12 +38,12 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { @Test fun apply_afterAndroidPlugin() { - val project = ProjectBuilder.builder().build() - project.pluginManager.apply { - apply("com.android.application") - apply(pluginId) + val project = buildProject { + pluginManager.apply { + apply("com.android.application") + apply(pluginId) + } } - project.enableObjectBoxPluginDebugMode() with(project.configurations) { assertProcessorDependency(getByName(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME).dependencies) @@ -61,27 +60,27 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { @Test fun apply_afterKotlinAndroidAndKaptPlugin() { - val project = ProjectBuilder.builder().build() - project.pluginManager.apply { - apply("com.android.application") - apply("kotlin-android") - apply("kotlin-kapt") - apply(pluginId) + val project = buildProject { + pluginManager.apply { + apply("com.android.application") + apply("kotlin-android") + apply("kotlin-kapt") + apply(pluginId) + } } - project.enableObjectBoxPluginDebugMode() assertKotlinAndroidSetup(project) } @Test fun apply_afterKotlinAndroidPlugin_addsKapt() { - val project = ProjectBuilder.builder().build() - project.pluginManager.apply { - apply("com.android.application") - apply("kotlin-android") - apply(pluginId) + val project = buildProject { + pluginManager.apply { + apply("com.android.application") + apply("kotlin-android") + apply(pluginId) + } } - project.enableObjectBoxPluginDebugMode() assertKotlinAndroidSetup(project) } diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt index d42a13b6..b6b7777b 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt @@ -78,36 +78,36 @@ open class PluginApplyJavaTest : PluginApplyTest() { @Test fun apply_afterJavaPlugin() { - val project = ProjectBuilder.builder().build() - project.pluginManager.apply { - apply("java") - apply(pluginId) + val project = buildProject { + pluginManager.apply { + apply("java") + apply(pluginId) + } } - project.enableObjectBoxPluginDebugMode() assertJavaProject(project, JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) } @Test fun apply_afterApplicationPlugin() { - val project = ProjectBuilder.builder().build() - project.pluginManager.apply { - apply("application") // Note: application plugin adds java plugin. - apply(pluginId) + val project = buildProject { + pluginManager.apply { + apply("application") // Note: application plugin adds java plugin. + apply(pluginId) + } } - project.enableObjectBoxPluginDebugMode() assertJavaProject(project, JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) } @Test fun apply_afterJavaLibraryPlugin() { - val project = ProjectBuilder.builder().build() - project.pluginManager.apply { - apply("java-library") - apply(pluginId) + val project = buildProject { + pluginManager.apply { + apply("java-library") + apply(pluginId) + } } - project.enableObjectBoxPluginDebugMode() assertJavaProject(project, JavaPlugin.API_CONFIGURATION_NAME) } @@ -155,25 +155,25 @@ open class PluginApplyJavaTest : PluginApplyTest() { @Test fun apply_afterKotlinAndKaptPlugin() { - val project = ProjectBuilder.builder().build() - project.pluginManager.apply { - apply("kotlin") - apply("kotlin-kapt") - apply(pluginId) + val project = buildProject { + pluginManager.apply { + apply("kotlin") + apply("kotlin-kapt") + apply(pluginId) + } } - project.enableObjectBoxPluginDebugMode() assertKotlinSetup(project) } @Test fun apply_afterKotlinPlugin_addsKapt() { - val project = ProjectBuilder.builder().build() - project.pluginManager.apply { - apply("kotlin") - apply(pluginId) + val project = buildProject { + pluginManager.apply { + apply("kotlin") + apply(pluginId) + } } - project.enableObjectBoxPluginDebugMode() assertKotlinSetup(project) } diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt index 0f1cddd2..f2e3ee6d 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt @@ -19,6 +19,7 @@ package io.objectbox.gradle import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder import org.junit.Assert.assertTrue @@ -31,6 +32,16 @@ abstract class PluginApplyTest { open val expectedLibWithSyncVariantPrefix = "objectbox" open val expectedLibWithSyncVariantVersion = ProjectEnv.Const.nativeVersionToApply + protected fun buildProject( + configureProject: Project.() -> Unit + ): Project = ProjectBuilder + .builder() + .build() + .apply(configureProject) + .also { + it.enableObjectBoxPluginDebugMode() + } + /** * Test PluginOptions extension is created and can be configured. * To check if it actually is recognized, would have to assert log output, From 6f845d92fd4cf76d00766ee12d8ee673fd20af49 Mon Sep 17 00:00:00 2001 From: Uwe Date: Tue, 3 Mar 2026 13:24:44 +0100 Subject: [PATCH 03/17] ProjectEnv: use Gradle constants to get configuration names --- .../io/objectbox/gradle/ObjectBoxGradlePlugin.kt | 5 +++-- .../main/kotlin/io/objectbox/gradle/ProjectEnv.kt | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt index 914419aa..2a0fbcc7 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt @@ -31,6 +31,7 @@ import org.gradle.api.Task import org.gradle.api.UnknownDomainObjectException import org.gradle.api.artifacts.Dependency import org.gradle.api.plugins.InvalidPluginException +import org.gradle.api.plugins.JavaPlugin import org.gradle.api.tasks.compile.JavaCompile /** @@ -157,9 +158,9 @@ open class ObjectBoxGradlePlugin : Plugin { project.addDep("kapt", processorDep) } - project.hasConfig("annotationProcessor") -> { + project.hasConfig(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME) -> { // Android (Java), also Java Desktop with Gradle 5.0 (best as of 5.2) uses annotationProcessor. - project.addDep("annotationProcessor", processorDep) + project.addDep(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME, processorDep) } project.hasConfig("apt") -> { diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt index 471b98db..ab280f90 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt @@ -64,13 +64,13 @@ class ProjectEnv(val project: Project) { * (used by `applications` plugin). */ val configApiOrImplOrCompile: String by lazy { - if (project.configurations.findByName("api") != null) { + if (project.configurations.findByName(JavaPlugin.API_CONFIGURATION_NAME) != null) { // Projects applying the java-library plugin. // Try to use api by default so consuming projects inherit the dependency. - "api" - } else if (project.configurations.findByName("implementation") != null) { + JavaPlugin.API_CONFIGURATION_NAME + } else if (project.configurations.findByName(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) != null) { // Projects applying the application plugin (does not have api configuration). - "implementation" + JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME } else { "compile" } @@ -83,8 +83,8 @@ class ProjectEnv(val project: Project) { } } val configTestImplOrCompile: String by lazy { - if (project.configurations.findByName("testImplementation") != null) { - "testImplementation" + if (project.configurations.findByName(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME) != null) { + JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME } else { "testCompile" } From 85c4c1626b916291f30c8b158700c9aeac513de5 Mon Sep 17 00:00:00 2001 From: Uwe Date: Tue, 3 Mar 2026 13:26:18 +0100 Subject: [PATCH 04/17] ProjectEnv: remove unsupported compile configurations Gradle 7 and Android Plugin 3 have dropped the compile configurations. https://docs.gradle.org/current/userguide/upgrading_version_6.html https://developer.android.com/build/releases/agp-3-0-0-release-notes --- .../objectbox/gradle/ObjectBoxGradlePlugin.kt | 9 ++++--- .../kotlin/io/objectbox/gradle/ProjectEnv.kt | 27 ++++++------------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt index 2a0fbcc7..7ed9c550 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt @@ -203,7 +203,7 @@ open class ObjectBoxGradlePlugin : Plugin { } private fun addDependencies(env: ProjectEnv) { - val compileConfig = env.configApiOrImplOrCompile + val compileConfig = env.configApiOrImpl val project = env.project // Note: a preview release might apply different versions of the Java and native library, @@ -238,10 +238,13 @@ open class ObjectBoxGradlePlugin : Plugin { // for instrumented unit tests // add jsr305 to prevent conflict with other versions added by test dependencies, like espresso // https://github.com/objectbox/objectbox-java/issues/73 - project.addDep(env.configAndroidTestImplOrCompile, "com.google.code.findbugs:jsr305:3.0.2") + project.addDep( + ProjectEnv.Const.ANDROID_TEST_IMPLEMENTATION_CONFIGURATION_NAME, + "com.google.code.findbugs:jsr305:3.0.2" + ) // for local unit tests - addNativeDependency(env, env.configTestImplOrCompile, true) + addNativeDependency(env, JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, true) } else { addNativeDependency(env, compileConfig, false) } diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt index ab280f90..47931c38 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt @@ -31,6 +31,12 @@ class ProjectEnv(val project: Project) { const val javaVersionToApply = GradlePluginBuildConfig.APPLIES_JAVA_VERSION const val nativeVersionToApply = GradlePluginBuildConfig.APPLIES_NATIVE_VERSION const val nativeSyncVersionToApply = GradlePluginBuildConfig.APPLIES_NATIVE_SYNC_VERSION + + /** + * The name of the default configuration for + * [Android instrumented (runs on devices) tests](https://developer.android.com/training/testing/instrumented-tests). + */ + const val ANDROID_TEST_IMPLEMENTATION_CONFIGURATION_NAME = "androidTestImplementation" } /** Note: Plugin extension, values only available after evaluation phase. */ @@ -57,36 +63,19 @@ class ProjectEnv(val project: Project) { val isMac64 = isMac && is64Bit val isWindows64 = isWindows && is64Bit - /** * See Gradle [java-library plugin configurations](https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_configurations_graph) * and [java plugin configurations](https://docs.gradle.org/current/userguide/java_plugin.html#sec:java_plugin_and_dependency_management) * (used by `applications` plugin). */ - val configApiOrImplOrCompile: String by lazy { + val configApiOrImpl: String by lazy { if (project.configurations.findByName(JavaPlugin.API_CONFIGURATION_NAME) != null) { // Projects applying the java-library plugin. // Try to use api by default so consuming projects inherit the dependency. JavaPlugin.API_CONFIGURATION_NAME - } else if (project.configurations.findByName(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) != null) { + } else { // Projects applying the application plugin (does not have api configuration). JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME - } else { - "compile" - } - } - val configAndroidTestImplOrCompile: String by lazy { - if (project.configurations.findByName("androidTestImplementation") != null) { - "androidTestImplementation" - } else { - "androidTestCompile" - } - } - val configTestImplOrCompile: String by lazy { - if (project.configurations.findByName(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME) != null) { - JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME - } else { - "testCompile" } } From d9cdbcdd829341b8776f54929f3cb3cc592b6c1f Mon Sep 17 00:00:00 2001 From: Uwe Date: Tue, 3 Mar 2026 14:05:47 +0100 Subject: [PATCH 05/17] ProjectEnv: add constant for kapt configuration --- .../kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt | 8 +++++--- .../src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt | 3 +++ .../kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt | 2 +- .../kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt index 7ed9c550..dcebdb83 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt @@ -143,7 +143,9 @@ open class ObjectBoxGradlePlugin : Plugin { private fun addDependenciesAnnotationProcessor(env: ProjectEnv) { val project = env.project - if ((env.hasKotlinPlugin || env.hasKotlinAndroidPlugin) && !project.hasConfig("kapt")) { + if ((env.hasKotlinPlugin || env.hasKotlinAndroidPlugin) && + !project.hasConfig(ProjectEnv.Const.KAPT_CONFIGURATION_NAME) + ) { // Note: no-op if kapt plugin was already applied. project.plugins.apply("kotlin-kapt") env.logDebug { "Applied 'kotlin-kapt'." } @@ -153,9 +155,9 @@ open class ObjectBoxGradlePlugin : Plugin { val processorDep = "io.objectbox:objectbox-processor:${ProjectEnv.Const.pluginVersion}" // Note: check for and use preferred/best config first, potentially ignoring others. when { - project.hasConfig("kapt") -> { + project.hasConfig(ProjectEnv.Const.KAPT_CONFIGURATION_NAME) -> { // Kotlin (Android + Desktop). - project.addDep("kapt", processorDep) + project.addDep(ProjectEnv.Const.KAPT_CONFIGURATION_NAME, processorDep) } project.hasConfig(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME) -> { diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt index 47931c38..18b54a41 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt @@ -37,6 +37,9 @@ class ProjectEnv(val project: Project) { * [Android instrumented (runs on devices) tests](https://developer.android.com/training/testing/instrumented-tests). */ const val ANDROID_TEST_IMPLEMENTATION_CONFIGURATION_NAME = "androidTestImplementation" + + /** Name of the configuration of the [kapt plugin](https://kotlinlang.org/docs/kapt.html). */ + const val KAPT_CONFIGURATION_NAME = "kapt" } /** Note: Plugin extension, values only available after evaluation phase. */ diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt index e13cbc94..7ae0c1ed 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt @@ -87,7 +87,7 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { private fun assertKotlinAndroidSetup(project: Project) { with(project.configurations) { - assertProcessorDependency(getByName("kapt").dependencies) + assertProcessorDependency(getByName(ProjectEnv.Const.KAPT_CONFIGURATION_NAME).dependencies) assertAndroidDependency(getByName(JavaPlugin.API_CONFIGURATION_NAME).dependencies) assertNativeDependency(getByName(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME).dependencies) } diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt index b6b7777b..323cde68 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt @@ -180,7 +180,7 @@ open class PluginApplyJavaTest : PluginApplyTest() { private fun assertKotlinSetup(project: Project) { with(project.configurations) { - assertProcessorDependency(getByName("kapt").dependencies) + assertProcessorDependency(getByName(ProjectEnv.Const.KAPT_CONFIGURATION_NAME).dependencies) getByName(JavaPlugin.API_CONFIGURATION_NAME).dependencies.let { deps -> assertEquals(1, deps.count { From 7af84b3b0bbf12871c450eabb23576676d7b1a37 Mon Sep 17 00:00:00 2001 From: Uwe Date: Tue, 3 Mar 2026 14:06:27 +0100 Subject: [PATCH 06/17] PluginApplyTest: deduplicate processor and database library assertions --- .../gradle/PluginApplyAndroidTest.kt | 19 +----------------- .../objectbox/gradle/PluginApplyJavaTest.kt | 17 ---------------- .../io/objectbox/gradle/PluginApplyTest.kt | 20 +++++++++++++++++++ 3 files changed, 21 insertions(+), 35 deletions(-) diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt index 7ae0c1ed..e024ede8 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt @@ -99,24 +99,7 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { // this is tested using Gradle TestKit in AndroidTransformTest. } - private fun assertProcessorDependency(apDeps: DependencySet) { - assertEquals("objectbox-processor dependency not found", 1, apDeps.count { - it.group == "io.objectbox" && it.name == "objectbox-processor" - && it.version == ProjectEnv.Const.pluginVersion - }) - } - - open fun assertNativeDependency(compileDeps: DependencySet) { - assertEquals("JNI lib dependency not found", 1, compileDeps.count { - it.group == "io.objectbox" - && (it.name == "$expectedLibWithSyncVariantPrefix-linux" - || it.name == "$expectedLibWithSyncVariantPrefix-windows" - || it.name == "$expectedLibWithSyncVariantPrefix-macos") - && it.version == expectedLibWithSyncVariantVersion - }) - } - - open fun assertAndroidDependency(deps: DependencySet) { + private fun assertAndroidDependency(deps: DependencySet) { assertEquals("Android lib dependency not found", 1, deps.count { it.group == "io.objectbox" && it.name == "$expectedLibWithSyncVariantPrefix-android" && it.version == expectedLibWithSyncVariantVersion diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt index 323cde68..b7caf9c0 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt @@ -203,13 +203,6 @@ open class PluginApplyJavaTest : PluginApplyTest() { assertTransformTask(project, "Test", JavaPlugin.TEST_CLASSES_TASK_NAME) } - private fun assertProcessorDependency(apDeps: DependencySet) { - assertEquals("objectbox-processor dependency not found", 1, apDeps.count { - it.group == "io.objectbox" && it.name == "objectbox-processor" - && it.version == ProjectEnv.Const.pluginVersion - }) - } - private fun assertJavaDependency(compileDeps: DependencySet) { assertEquals("objectbox-java dependency not found", 1, compileDeps.count { it.group == "io.objectbox" && it.name == "objectbox-java" @@ -217,14 +210,4 @@ open class PluginApplyJavaTest : PluginApplyTest() { }) } - open fun assertNativeDependency(compileDeps: DependencySet) { - assertEquals("JNI lib dependency not found", 1, compileDeps.count { - it.group == "io.objectbox" - && (it.name == "$expectedLibWithSyncVariantPrefix-linux" - || it.name == "$expectedLibWithSyncVariantPrefix-windows" - || it.name == "$expectedLibWithSyncVariantPrefix-macos") - && it.version == expectedLibWithSyncVariantVersion - }) - } - } \ No newline at end of file diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt index f2e3ee6d..f8203f0d 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt @@ -19,7 +19,9 @@ package io.objectbox.gradle import org.gradle.api.Project +import org.gradle.api.artifacts.DependencySet import org.gradle.testfixtures.ProjectBuilder +import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue @@ -55,4 +57,22 @@ abstract class PluginApplyTest { } assertTrue(extensions.getByType(ObjectBoxPluginExtension::class.java).debug.get()) } + + fun assertProcessorDependency(apDeps: DependencySet) { + assertEquals("objectbox-processor dependency not found", 1, apDeps.count { + it.group == "io.objectbox" && it.name == "objectbox-processor" + && it.version == ProjectEnv.Const.pluginVersion + }) + } + + fun assertNativeDependency(deps: DependencySet) { + assertEquals("JVM database library dependency not found", 1, deps.count { + it.group == "io.objectbox" + && (it.name == "$expectedLibWithSyncVariantPrefix-linux" + || it.name == "$expectedLibWithSyncVariantPrefix-windows" + || it.name == "$expectedLibWithSyncVariantPrefix-macos") + && it.version == expectedLibWithSyncVariantVersion + }) + } + } \ No newline at end of file From 521d6b64a523016c8ecd6eac0d8af60f3dc83300 Mon Sep 17 00:00:00 2001 From: Uwe Date: Tue, 24 Feb 2026 11:48:52 +0100 Subject: [PATCH 07/17] Plugin: detect dependencies added after applying the plugin --- .gitlab-ci.yml | 2 + objectbox-gradle-plugin/build.gradle.kts | 4 +- .../objectbox/gradle/ObjectBoxGradlePlugin.kt | 111 ++++++++++++------ .../kotlin/io/objectbox/gradle/ProjectEnv.kt | 7 +- .../gradle/PluginApplyAndroidTest.kt | 36 ++++++ .../objectbox/gradle/PluginApplyJavaTest.kt | 31 ++++- .../io/objectbox/gradle/PluginApplyTest.kt | 2 + 7 files changed, 150 insertions(+), 43 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index df66a6d1..b22549d0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,8 @@ # https://docs.gitlab.com/ci/yaml/ # Default image for linux builds +# Should contain Android components that are used by tests to avoid downloading them. +# Such as for PluginApplyAndroidTest and AndroidProjectPluginTest and their subclasses. image: objectboxio/buildenv-android:2024-12-09 # With JDK 21, Android SDK 35 pre-installed # Assumes these environment variables are configured in GitLab CI/CD Settings: diff --git a/objectbox-gradle-plugin/build.gradle.kts b/objectbox-gradle-plugin/build.gradle.kts index 582621a7..c6e7201e 100644 --- a/objectbox-gradle-plugin/build.gradle.kts +++ b/objectbox-gradle-plugin/build.gradle.kts @@ -182,7 +182,8 @@ dependencies { implementation(gradleApi()) // Note: Kotlin plugin adds kotlin-stdlib-jdk8 dependency. - compileOnly("com.android.tools.build:gradle-api:7.2.0") + val agpApi = "7.2.0" + compileOnly("com.android.tools.build:gradle-api:$agpApi") compileOnly("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") testImplementation(gradleTestKit()) @@ -200,6 +201,7 @@ dependencies { // For plugin apply tests and outdated TestKit tests (dir "test-gradle-projects"). testImplementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") + testImplementation("com.android.tools.build:gradle-api:$agpApi") agp73TestRuntimeOnly("com.android.tools.build:gradle:$agp73Version") agp81TestRuntimeOnly("com.android.tools.build:gradle:$agp81Version") diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt index dcebdb83..69f3a7a4 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt @@ -30,6 +30,7 @@ import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.UnknownDomainObjectException import org.gradle.api.artifacts.Dependency +import org.gradle.api.artifacts.DependencySet import org.gradle.api.plugins.InvalidPluginException import org.gradle.api.plugins.JavaPlugin import org.gradle.api.tasks.compile.JavaCompile @@ -141,6 +142,11 @@ open class ObjectBoxGradlePlugin : Plugin { } } + /** + * Configure the annotation processor. + * + * Note that this can't happen in [addDependencies] because it would be too late. + */ private fun addDependenciesAnnotationProcessor(env: ProjectEnv) { val project = env.project if ((env.hasKotlinPlugin || env.hasKotlinAndroidPlugin) && @@ -204,63 +210,89 @@ open class ObjectBoxGradlePlugin : Plugin { return ProjectEnv.Const.nativeVersionToApply } + private fun Project.addDepLater(dependencySet: DependencySet, dep: String) { + dependencySet.addLater( + provider { + dependencies.create(dep) + } + ) + } + + /** + * Before dependencies of project configurations are resolved, adds required ObjectBox dependencies, if a + * conflicting one isn't added already: + * + * - Java APIs (objectbox-java) + * - Kotlin APIs (objectbox-kotlin), if the (Android) Kotlin plugin is applied + * - database library for Android or JVM, depending on if the Android plugin is applied + * - Findbugs JSR305 nullable annotations, if the Android plugin is applied, only for instrumented unit tests + */ private fun addDependencies(env: ProjectEnv) { val compileConfig = env.configApiOrImpl val project = env.project - // Note: a preview release might apply different versions of the Java and native library, - // so explicitly apply the Java library to avoid the native library pulling in another version. - if (!env.hasObjectBoxDep("objectbox-java")) { - project.addDep(compileConfig, "io.objectbox:objectbox-java:${ProjectEnv.Const.javaVersionToApply}") - } + // Use Configuration.withDependencies to also detect dependencies that are added after the plugin is applied + // (which, if using modern Gradle plugins syntax, they are always). + project.configurations.getByName(compileConfig).withDependencies { dependencySet -> + // Note: a preview release might apply different versions of the Java and native library, + // so explicitly apply the Java library to avoid the native library pulling in another version. + if (!env.hasObjectBoxDep("objectbox-java")) { + project.addDepLater(dependencySet, "io.objectbox:objectbox-java:${ProjectEnv.Const.javaVersionToApply}") + } - if (env.hasKotlinPlugin || env.hasKotlinAndroidPlugin) { - env.logDebug { "Kotlin plugin detected" } - if (env.hasObjectBoxDep("objectbox-kotlin")) { - env.logDebug { "Detected objectbox-kotlin dependency, not auto-adding." } + if (env.hasKotlinPlugin || env.hasKotlinAndroidPlugin) { + env.logDebug { "Kotlin plugin detected" } + if (env.hasObjectBoxDep("objectbox-kotlin")) { + env.logDebug { "Detected objectbox-kotlin dependency, not auto-adding." } + } else { + project.addDepLater( + dependencySet, + "io.objectbox:objectbox-kotlin:${ProjectEnv.Const.javaVersionToApply}" + ) + } + } + + // If the Android plugin is applied, add the Android database library, otherwise the JVM database library + if (env.hasAndroidPlugin) { + if (!env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_DEFAULT-android") + && !env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_DEFAULT-android-objectbrowser") + && !env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_SYNC-android") + && !env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_SYNC-android-objectbrowser") + && !env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_SYNC-server-android") + ) { + project.addDepLater( + dependencySet, + "io.objectbox:${getLibWithSyncVariantPrefix()}-android:${getLibWithSyncVariantVersion()}" + ) + } } else { - project.addDep(compileConfig, "io.objectbox:objectbox-kotlin:${ProjectEnv.Const.javaVersionToApply}") + addNativeDependency(env, dependencySet, searchTestConfigs = false) } } if (env.hasAndroidPlugin) { - // for this detection to work apply the plugin after the dependencies block - if (!env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_DEFAULT-android") - && !env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_DEFAULT-android-objectbrowser") - && !env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_SYNC-android") - && !env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_SYNC-android-objectbrowser") - && !env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_SYNC-server-android") - ) { - project.addDep( - compileConfig, - "io.objectbox:${getLibWithSyncVariantPrefix()}-android:${getLibWithSyncVariantVersion()}" - ) - } + // For Android local (on developer machine) unit tests add a dependency on the JVM database library + project.configurations.getByName(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME) + .withDependencies { dependencySet -> + addNativeDependency(env, dependencySet, searchTestConfigs = true) + } - // for instrumented unit tests - // add jsr305 to prevent conflict with other versions added by test dependencies, like espresso + // For Android instrumented (on device/emulator) unit tests + // add jsr305 to prevent conflict with other versions added by test dependencies, like espresso. // https://github.com/objectbox/objectbox-java/issues/73 - project.addDep( - ProjectEnv.Const.ANDROID_TEST_IMPLEMENTATION_CONFIGURATION_NAME, - "com.google.code.findbugs:jsr305:3.0.2" - ) - - // for local unit tests - addNativeDependency(env, JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, true) - } else { - addNativeDependency(env, compileConfig, false) + project.configurations + .getByName(ProjectEnv.Const.ANDROID_TEST_IMPLEMENTATION_CONFIGURATION_NAME) + .dependencies + .let { project.addDepLater(it, "com.google.code.findbugs:jsr305:3.0.2") } } } - private fun addNativeDependency(env: ProjectEnv, config: String, searchTestConfigs: Boolean) { - val project = env.project - + private fun addNativeDependency(env: ProjectEnv, dependencySet: DependencySet, searchTestConfigs: Boolean) { env.logDebug { "Detected OS: ${env.osName} is64=${env.is64Bit} " + "isLinux64=${env.isLinux64} isWindows64=${env.isWindows64} isMac64=${env.isMac64}" } - // note: for this detection to work apply the plugin after the dependencies block // Note: use startsWith to detect e.g. -armv7 and -arm64 and any possible future suffixes. if (env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_DEFAULT-linux", searchTestConfigs, startsWith = true) || env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_DEFAULT-macos", searchTestConfigs, startsWith = true) @@ -283,7 +315,7 @@ open class ObjectBoxGradlePlugin : Plugin { if (suffix != null) { val prefix = getLibWithSyncVariantPrefix() val version = getLibWithSyncVariantVersion() - project.addDep(config, "io.objectbox:$prefix-$suffix:$version") + env.project.addDepLater(dependencySet, "io.objectbox:$prefix-$suffix:$version") } else { env.logInfo("Could not set up native dependency for ${env.osName}") } @@ -293,7 +325,8 @@ open class ObjectBoxGradlePlugin : Plugin { /** * Checks for exact name match. Set [startsWith] to true to only check for prefix. * - * Note: for this detection to work the plugin must be applied after the dependencies block. + * Note: for this detection to work for dependencies added after the plugin is applied, must be called within + * [org.gradle.api.artifacts.Configuration.withDependencies]. */ private fun ProjectEnv.hasObjectBoxDep( name: String, diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt index 18b54a41..ee596584 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt @@ -90,8 +90,13 @@ class ProjectEnv(val project: Project) { * Using function for [message] to avoid String getting built unless in debug mode. */ fun logDebug(message: () -> String) { - project.afterEvaluate { + val isEvaluated = project.state.executed + if (isEvaluated) { if (options.debug.get()) log(message()) + } else { + project.afterEvaluate { + if (options.debug.get()) log(message()) + } } } } \ No newline at end of file diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt index e024ede8..d81a38bd 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt @@ -18,8 +18,10 @@ package io.objectbox.gradle +import com.android.build.api.dsl.ApplicationExtension import org.gradle.api.Project import org.gradle.api.artifacts.DependencySet +import org.gradle.api.internal.project.ProjectInternal import org.gradle.api.plugins.JavaPlugin import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull @@ -36,6 +38,38 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { */ abstract fun assertAndroidCompat(project: Project) + private fun Project.configureAndroidProject() { + val androidExtension = extensions.getByName("android") as ApplicationExtension + androidExtension.apply { + compileSdk = 35 // Matches SDK embedded in buildenv-android CI image to avoid downloading it + namespace = "io.objectbox.plugin.test" + } + } + + /** + * Because the plugin adds dependencies using [org.gradle.api.DomainObjectCollection.addLater] it is necessary to + * resolve the dependency graph before being able to inspect them. However, the Android Gradle Plugin only adds the + * needed classpath configurations during project evaluation. So force project evaluation (and configure the Android + * project as needed to do so). + * + * See also [io.objectbox.gradle.PluginApplyJavaTest.resolveDependencyGraphWithoutDownloadingFiles], especially with + * details on why the Android plugin warns about doing this and why we ignore this warning. + */ + private fun Project.resolveDependencyGraphWithoutDownloadingFiles() { + project.configureAndroidProject() + (project as ProjectInternal).evaluate() + + project.configurations.getByName("debugCompileClasspath") + .incoming + .resolutionResult + .allDependencies + + project.configurations.getByName("debugUnitTestCompileClasspath") + .incoming + .resolutionResult + .allDependencies + } + @Test fun apply_afterAndroidPlugin() { val project = buildProject { @@ -45,6 +79,7 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { } } + project.resolveDependencyGraphWithoutDownloadingFiles() with(project.configurations) { assertProcessorDependency(getByName(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME).dependencies) assertAndroidDependency(getByName(JavaPlugin.API_CONFIGURATION_NAME).dependencies) @@ -86,6 +121,7 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { } private fun assertKotlinAndroidSetup(project: Project) { + project.resolveDependencyGraphWithoutDownloadingFiles() with(project.configurations) { assertProcessorDependency(getByName(ProjectEnv.Const.KAPT_CONFIGURATION_NAME).dependencies) assertAndroidDependency(getByName(JavaPlugin.API_CONFIGURATION_NAME).dependencies) diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt index b7caf9c0..2cc2c0a3 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt @@ -112,7 +112,33 @@ open class PluginApplyJavaTest : PluginApplyTest() { assertJavaProject(project, JavaPlugin.API_CONFIGURATION_NAME) } + /** + * The ObjectBox plugin adds dependencies using [org.gradle.api.DomainObjectCollection.addLater] (see + * [ObjectBoxGradlePlugin.addDependencies]). As a side effect they won't appear in the configuration they were added + * to until the dependency graph is resolved. So to assert dependencies were added by the plugin, the graph must be + * resolved. + * + * To resolve the graph [org.gradle.api.artifacts.Configuration.resolve] could be used, but it will download files. + * So instead access all incoming dependencies, which only resolves the graph. + * + * Also use the compileClasspath configuration all others contribute to as the api and implementation + * configurations can not be resolved themselves. + * + * Despite this being similar to what the Kotlin Gradle plugin tests do, note that the Android plugin warns about + * and the Gradle folks [don't recommend resolving configurations before task execution](https://docs.gradle.org/current/userguide/best_practices_tasks.html#dont_resolve_configurations_before_task_execution). + * So if ever enforced (see https://github.com/gradle/gradle/issues/2298 for a discussion), this approach might + * break in the future. An alternative (that does require downloading files) is to use Gradle TestKit instead and + * maybe to inspect output of the dependencies task or to use a custom task to do validation. + */ + private fun Project.resolveDependencyGraphWithoutDownloadingFiles() { + configurations.getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME) + .incoming + .resolutionResult + .allDependencies + } + private fun assertJavaProject(project: Project, configuration: String) { + project.resolveDependencyGraphWithoutDownloadingFiles() with(project.configurations) { assertProcessorDependency(getByName(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME).dependencies) @@ -179,6 +205,7 @@ open class PluginApplyJavaTest : PluginApplyTest() { } private fun assertKotlinSetup(project: Project) { + project.resolveDependencyGraphWithoutDownloadingFiles() with(project.configurations) { assertProcessorDependency(getByName(ProjectEnv.Const.KAPT_CONFIGURATION_NAME).dependencies) @@ -203,8 +230,8 @@ open class PluginApplyJavaTest : PluginApplyTest() { assertTransformTask(project, "Test", JavaPlugin.TEST_CLASSES_TASK_NAME) } - private fun assertJavaDependency(compileDeps: DependencySet) { - assertEquals("objectbox-java dependency not found", 1, compileDeps.count { + private fun assertJavaDependency(deps: DependencySet) { + assertEquals("objectbox-java dependency not found", 1, deps.count { it.group == "io.objectbox" && it.name == "objectbox-java" && it.version == ProjectEnv.Const.javaVersionToApply }) diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt index f8203f0d..e151a863 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt @@ -48,6 +48,8 @@ abstract class PluginApplyTest { * Test PluginOptions extension is created and can be configured. * To check if it actually is recognized, would have to assert log output, * currently not doing that. + * + * This also enables helpful log output to diagnose test failures. */ protected fun Project.enableObjectBoxPluginDebugMode() { extensions.apply { From 9a721697244d2b68fcd8c23d13fecc6ff74056fd Mon Sep 17 00:00:00 2001 From: Uwe Date: Mon, 2 Mar 2026 13:43:58 +0100 Subject: [PATCH 08/17] Plugin: test dependency detection for Java and Kotlin projects --- .../objectbox/gradle/PluginApplyJavaTest.kt | 102 ++++++++++++++++-- 1 file changed, 94 insertions(+), 8 deletions(-) diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt index 2cc2c0a3..8d9bfde7 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt @@ -30,6 +30,7 @@ import org.hamcrest.MatcherAssert.assertThat import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertThrows +import org.junit.Assert.assertTrue import org.junit.Test @@ -100,16 +101,17 @@ open class PluginApplyJavaTest : PluginApplyTest() { assertJavaProject(project, JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) } - @Test - fun apply_afterJavaLibraryPlugin() { - val project = buildProject { + private fun buildJavaLibraryProject(): Project = + buildProject { pluginManager.apply { apply("java-library") apply(pluginId) } } - assertJavaProject(project, JavaPlugin.API_CONFIGURATION_NAME) + @Test + fun apply_afterJavaLibraryPlugin() { + assertJavaProject(buildJavaLibraryProject(), JavaPlugin.API_CONFIGURATION_NAME) } /** @@ -179,9 +181,8 @@ open class PluginApplyJavaTest : PluginApplyTest() { .taskDependencies.getDependencies(classesTask).count { it.name == transformTask.name }) } - @Test - fun apply_afterKotlinAndKaptPlugin() { - val project = buildProject { + private fun buildKotlinKaptProject(): Project = + buildProject { pluginManager.apply { apply("kotlin") apply("kotlin-kapt") @@ -189,7 +190,9 @@ open class PluginApplyJavaTest : PluginApplyTest() { } } - assertKotlinSetup(project) + @Test + fun apply_afterKotlinAndKaptPlugin() { + assertKotlinSetup(buildKotlinKaptProject()) } @Test @@ -237,4 +240,87 @@ open class PluginApplyJavaTest : PluginApplyTest() { }) } + @Test + fun apply_doesNotAddAdditionalJavaLibrary() { + assertOnlySingleDependency( + buildJavaLibraryProject(), + JavaPlugin.API_CONFIGURATION_NAME, + "objectbox-java" + ) + assertOnlySingleDependency( + buildJavaLibraryProject(), + JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, + "objectbox-java" + ) + } + + @Test + fun apply_doesNotAddAdditionalKotlinLibrary() { + assertOnlySingleDependency( + buildKotlinKaptProject(), + JavaPlugin.API_CONFIGURATION_NAME, + "objectbox-kotlin" + ) + assertOnlySingleDependency( + buildKotlinKaptProject(), + JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, + "objectbox-kotlin" + ) + } + + private fun assertOnlySingleDependency(forProject: Project, toConfiguration: String, name: String) { + // Use a custom version that's easy to recognize if this test should fail + val customVersion = "${ProjectEnv.Const.javaVersionToApply}-custom" + forProject.dependencies.add(toConfiguration, "io.objectbox:$name:$customVersion") + + forProject.resolveDependencyGraphWithoutDownloadingFiles() + + val deps = forProject.configurations + .flatMap { configuration -> + configuration.dependencies + .filter { it.name == name } + } + assertTrue( + "Must not add duplicate $name library, but has:\n${deps.joinToString("\n")}", + deps.size == 1 && deps.first().version == customVersion + ) + } + + private val databaseLibraries = listOf( + "objectbox-linux", + "objectbox-macos", + "objectbox-windows", + "objectbox-sync-linux", + "objectbox-sync-server-linux", + "objectbox-sync-macos", + "objectbox-sync-windows" + ) + + @Test + fun apply_doesNotAddAdditionalDatabaseLibrary() { + databaseLibraries.forEach { + assertNoDatabaseLibraryAdded(it) + } + } + + private fun assertNoDatabaseLibraryAdded(name: String) { + val project = buildJavaLibraryProject() + + // Use a custom version that's easy to recognize if this test should fail + val customVersion = "${ProjectEnv.Const.nativeVersionToApply}-custom" + project.dependencies.add(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, "io.objectbox:$name:$customVersion") + + project.resolveDependencyGraphWithoutDownloadingFiles() + val databaseDeps = project.configurations + .flatMap { configuration -> + configuration.dependencies + .filter { databaseLibraries.contains(it.name) } + } + assertEquals( + "Must not add additional database library, but has:\n${databaseDeps.joinToString("\n")}", + 1, + databaseDeps.size + ) + } + } \ No newline at end of file From 75a3718dc2486fc9ab456268395c8a04748cfcf2 Mon Sep 17 00:00:00 2001 From: Uwe Date: Tue, 3 Mar 2026 13:46:05 +0100 Subject: [PATCH 09/17] Plugin: test dependency detection for Android projects --- .../gradle/PluginApplyAndroidTest.kt | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt index d81a38bd..67034958 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt @@ -70,15 +70,18 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { .allDependencies } - @Test - fun apply_afterAndroidPlugin() { - val project = buildProject { + private fun buildAndroidProject(): Project = + buildProject { pluginManager.apply { apply("com.android.application") apply(pluginId) } } + @Test + fun apply_afterAndroidPlugin() { + val project = buildAndroidProject() + project.resolveDependencyGraphWithoutDownloadingFiles() with(project.configurations) { assertProcessorDependency(getByName(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME).dependencies) @@ -142,4 +145,39 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { }) } + private val databaseLibraries = listOf( + "objectbox-android", + "objectbox-android-objectbrowser", + "objectbox-sync-android", + "objectbox-sync-android-objectbrowser", + "objectbox-sync-server-android" + ) + + @Test + fun apply_doesNotAddAdditionalDatabaseLibrary() { + databaseLibraries.forEach { + assertNoDatabaseLibraryAdded(it) + } + } + + private fun assertNoDatabaseLibraryAdded(name: String) { + val project = buildAndroidProject() + + // Use a custom version that's easy to recognize if this test should fail + val customVersion = "${ProjectEnv.Const.nativeVersionToApply}-custom" + project.dependencies.add(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, "io.objectbox:$name:$customVersion") + + project.resolveDependencyGraphWithoutDownloadingFiles() + val databaseDeps = project.configurations + .flatMap { configuration -> + configuration.dependencies + .filter { databaseLibraries.contains(it.name) } + } + assertEquals( + "Must not add additional database library, but has:\n${databaseDeps.joinToString("\n")}", + 1, + databaseDeps.size + ) + } + } \ No newline at end of file From c092ebc8459b6ae25a489f2534a4f88009c44daf Mon Sep 17 00:00:00 2001 From: Uwe Date: Mon, 9 Mar 2026 08:26:22 +0100 Subject: [PATCH 10/17] Plugin apply tests: extract common get dependency function --- .../io/objectbox/gradle/PluginApplyAndroidTest.kt | 6 +----- .../io/objectbox/gradle/PluginApplyJavaTest.kt | 12 ++---------- .../kotlin/io/objectbox/gradle/PluginApplyTest.kt | 13 +++++++++++++ 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt index 67034958..08a786a1 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt @@ -168,11 +168,7 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { project.dependencies.add(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, "io.objectbox:$name:$customVersion") project.resolveDependencyGraphWithoutDownloadingFiles() - val databaseDeps = project.configurations - .flatMap { configuration -> - configuration.dependencies - .filter { databaseLibraries.contains(it.name) } - } + val databaseDeps = project.getDependenciesMatching { databaseLibraries.contains(it.name) } assertEquals( "Must not add additional database library, but has:\n${databaseDeps.joinToString("\n")}", 1, diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt index 8d9bfde7..02fae153 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt @@ -275,11 +275,7 @@ open class PluginApplyJavaTest : PluginApplyTest() { forProject.resolveDependencyGraphWithoutDownloadingFiles() - val deps = forProject.configurations - .flatMap { configuration -> - configuration.dependencies - .filter { it.name == name } - } + val deps = forProject.getDependenciesMatching { it.name == name } assertTrue( "Must not add duplicate $name library, but has:\n${deps.joinToString("\n")}", deps.size == 1 && deps.first().version == customVersion @@ -311,11 +307,7 @@ open class PluginApplyJavaTest : PluginApplyTest() { project.dependencies.add(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, "io.objectbox:$name:$customVersion") project.resolveDependencyGraphWithoutDownloadingFiles() - val databaseDeps = project.configurations - .flatMap { configuration -> - configuration.dependencies - .filter { databaseLibraries.contains(it.name) } - } + val databaseDeps = project.getDependenciesMatching { databaseLibraries.contains(it.name) } assertEquals( "Must not add additional database library, but has:\n${databaseDeps.joinToString("\n")}", 1, diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt index e151a863..dec1883d 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt @@ -19,6 +19,7 @@ package io.objectbox.gradle import org.gradle.api.Project +import org.gradle.api.artifacts.Dependency import org.gradle.api.artifacts.DependencySet import org.gradle.testfixtures.ProjectBuilder import org.junit.Assert.assertEquals @@ -60,6 +61,18 @@ abstract class PluginApplyTest { assertTrue(extensions.getByType(ObjectBoxPluginExtension::class.java).debug.get()) } + /** + * Gets the dependencies matching the given predicate from all [Project.getConfigurations]. + */ + protected fun Project.getDependenciesMatching( + predicate: (Dependency) -> Boolean + ): List = + configurations + .flatMap { configuration -> + configuration.dependencies + .filter(predicate) + } + fun assertProcessorDependency(apDeps: DependencySet) { assertEquals("objectbox-processor dependency not found", 1, apDeps.count { it.group == "io.objectbox" && it.name == "objectbox-processor" From 4271e3def2fd8238575c0f152aa45d349bb7c205 Mon Sep 17 00:00:00 2001 From: Uwe Date: Mon, 9 Mar 2026 08:14:15 +0100 Subject: [PATCH 11/17] Plugin: don't add Java library if Kotlin library is detected --- .../objectbox/gradle/ObjectBoxGradlePlugin.kt | 23 +++++++++++-------- .../objectbox/gradle/PluginApplyJavaTest.kt | 10 +++++++- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt index 69f3a7a4..750eefdf 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt @@ -234,16 +234,12 @@ open class ObjectBoxGradlePlugin : Plugin { // Use Configuration.withDependencies to also detect dependencies that are added after the plugin is applied // (which, if using modern Gradle plugins syntax, they are always). project.configurations.getByName(compileConfig).withDependencies { dependencySet -> - // Note: a preview release might apply different versions of the Java and native library, - // so explicitly apply the Java library to avoid the native library pulling in another version. - if (!env.hasObjectBoxDep("objectbox-java")) { - project.addDepLater(dependencySet, "io.objectbox:objectbox-java:${ProjectEnv.Const.javaVersionToApply}") - } + val hasKotlinPlugin = env.hasKotlinPlugin || env.hasKotlinAndroidPlugin + val hasObxKotlinLibrary = env.hasObjectBoxDep("objectbox-kotlin") - if (env.hasKotlinPlugin || env.hasKotlinAndroidPlugin) { - env.logDebug { "Kotlin plugin detected" } - if (env.hasObjectBoxDep("objectbox-kotlin")) { - env.logDebug { "Detected objectbox-kotlin dependency, not auto-adding." } + if (hasKotlinPlugin) { + if (hasObxKotlinLibrary) { + env.logDebug { "Not adding objectbox-kotlin dependency, a configuration has one" } } else { project.addDepLater( dependencySet, @@ -252,6 +248,15 @@ open class ObjectBoxGradlePlugin : Plugin { } } + // Note: a preview release of the plugin might apply different versions of the Java and database library, + // so always add the Java library to avoid the Android database library pulling in an older Java library + // (only the Android library has a dependency on the Java library as it includes Java APIs). + // But don't add it if the Kotlin library is manually added as it has a dependency on the Java library to + // avoid pulling in a newer, possibly incompatible, Java library. + if (!env.hasObjectBoxDep("objectbox-java") && !hasObxKotlinLibrary) { + project.addDepLater(dependencySet, "io.objectbox:objectbox-java:${ProjectEnv.Const.javaVersionToApply}") + } + // If the Android plugin is applied, add the Android database library, otherwise the JVM database library if (env.hasAndroidPlugin) { if (!env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_DEFAULT-android") diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt index 02fae153..6a593028 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt @@ -256,11 +256,19 @@ open class PluginApplyJavaTest : PluginApplyTest() { @Test fun apply_doesNotAddAdditionalKotlinLibrary() { + val projectApiConfig = buildKotlinKaptProject() assertOnlySingleDependency( - buildKotlinKaptProject(), + projectApiConfig, JavaPlugin.API_CONFIGURATION_NAME, "objectbox-kotlin" ) + // Also check objectbox-java is not added as objectbox-kotlin already has a transitive dependency on it + val javaLibDeps = projectApiConfig.getDependenciesMatching { it.name == "objectbox-java" } + assertTrue( + "Must not add objectbox-java library, but has:\n${javaLibDeps.joinToString("\n")}", + javaLibDeps.isEmpty() + ) + assertOnlySingleDependency( buildKotlinKaptProject(), JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, From 52e0983e134ccc33ef795e6cb633a3b3d5baa870 Mon Sep 17 00:00:00 2001 From: Uwe Date: Mon, 9 Mar 2026 09:14:19 +0100 Subject: [PATCH 12/17] Plugin: log why Java library is not applied --- .../kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt index 750eefdf..8f0b1d8f 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt @@ -253,7 +253,11 @@ open class ObjectBoxGradlePlugin : Plugin { // (only the Android library has a dependency on the Java library as it includes Java APIs). // But don't add it if the Kotlin library is manually added as it has a dependency on the Java library to // avoid pulling in a newer, possibly incompatible, Java library. - if (!env.hasObjectBoxDep("objectbox-java") && !hasObxKotlinLibrary) { + if (env.hasObjectBoxDep("objectbox-java")) { + env.logDebug { "Not adding objectbox-java dependency, a configuration has one" } + } else if (hasObxKotlinLibrary) { + env.logDebug { "Not adding objectbox-java dependency, a configuration has objectbox-kotlin" } + } else { project.addDepLater(dependencySet, "io.objectbox:objectbox-java:${ProjectEnv.Const.javaVersionToApply}") } From 5c61a6f94fac60b7a4264d3aef20632752f7aa24 Mon Sep 17 00:00:00 2001 From: Uwe Date: Mon, 9 Mar 2026 09:14:49 +0100 Subject: [PATCH 13/17] Plugin: log configuration of detected dependencies --- .../io/objectbox/gradle/ObjectBoxGradlePlugin.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt index 8f0b1d8f..b455b5da 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt @@ -29,6 +29,7 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.UnknownDomainObjectException +import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Dependency import org.gradle.api.artifacts.DependencySet import org.gradle.api.plugins.InvalidPluginException @@ -342,9 +343,10 @@ open class ObjectBoxGradlePlugin : Plugin { searchTestConfigs: Boolean = false, startsWith: Boolean = false ): Boolean { - val dependency = findObjectBoxDependency(project, name, searchTestConfigs, startsWith) - logDebug { "$name dependency: $dependency" } - return dependency != null + val (config, dependency) = findObjectBoxDependency(project, name, searchTestConfigs, startsWith) + ?: return false + logDebug { "$name dependency on $config: $dependency" } + return true } private fun findObjectBoxDependency( @@ -352,7 +354,7 @@ open class ObjectBoxGradlePlugin : Plugin { name: String, searchTestConfigs: Boolean, startsWith: Boolean - ): Dependency? { + ): Pair? { if (searchTestConfigs) { project.configurations } else { @@ -360,7 +362,7 @@ open class ObjectBoxGradlePlugin : Plugin { }.forEach { config -> config.dependencies.find { it.group == "io.objectbox" && (if (startsWith) it.name.startsWith(name) else it.name == name) - }?.let { return it } + }?.let { return config to it } } return null } From 474529e552efce9dc92e7c1a3ba3accb1337ea10 Mon Sep 17 00:00:00 2001 From: Uwe Date: Mon, 9 Mar 2026 09:33:19 +0100 Subject: [PATCH 14/17] Plugin: log if Android library dependency is not added Also update message for JVM database library to explicitly mention its the JVM variant. --- .../kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt index b455b5da..a23b6f03 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt @@ -264,6 +264,7 @@ open class ObjectBoxGradlePlugin : Plugin { // If the Android plugin is applied, add the Android database library, otherwise the JVM database library if (env.hasAndroidPlugin) { + val androidDepName = "${getLibWithSyncVariantPrefix()}-android" if (!env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_DEFAULT-android") && !env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_DEFAULT-android-objectbrowser") && !env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_SYNC-android") @@ -272,8 +273,10 @@ open class ObjectBoxGradlePlugin : Plugin { ) { project.addDepLater( dependencySet, - "io.objectbox:${getLibWithSyncVariantPrefix()}-android:${getLibWithSyncVariantVersion()}" + "io.objectbox:$androidDepName:${getLibWithSyncVariantVersion()}" ) + } else { + env.logDebug { "Not adding $androidDepName dependency, a configuration has an Android database library" } } } else { addNativeDependency(env, dependencySet, searchTestConfigs = false) @@ -312,7 +315,7 @@ open class ObjectBoxGradlePlugin : Plugin { || env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_SYNC-macos", searchTestConfigs, startsWith = true) || env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_SYNC-windows", searchTestConfigs, startsWith = true) ) { - env.logDebug { "Detected native dependency, not auto-adding one." } + env.logDebug { "Not adding JVM database library dependency, a configuration has one" } } else { // Note: -armv7 and -arm64 variants of the Linux library are not added automatically, // users are expected to do so themselves if needed. From 43a5a36cfab138e62a705cf3de84ed2e7713cc74 Mon Sep 17 00:00:00 2001 From: Uwe Date: Mon, 9 Mar 2026 14:15:56 +0100 Subject: [PATCH 15/17] ProjectEnv constants: properly (re)name, add for group and dependencies --- .../io/objectbox/gradle/GradleBuildTracker.kt | 4 +- .../objectbox/gradle/ObjectBoxGradlePlugin.kt | 49 +++++++++---------- .../gradle/ObjectBoxSyncGradlePlugin.kt | 2 +- .../kotlin/io/objectbox/gradle/ProjectEnv.kt | 18 ++++--- .../io/objectbox/gradle/BuildTrackerTest.kt | 6 +-- .../gradle/PluginApplyAndroidTest.kt | 12 +++-- .../objectbox/gradle/PluginApplyJavaTest.kt | 36 ++++++++------ .../io/objectbox/gradle/PluginApplyTest.kt | 13 ++--- .../gradle/SyncPluginApplyAndroidTest.kt | 2 +- .../gradle/SyncPluginApplyJavaTest.kt | 2 +- 10 files changed, 79 insertions(+), 65 deletions(-) diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/GradleBuildTracker.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/GradleBuildTracker.kt index c3336110..75abe503 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/GradleBuildTracker.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/GradleBuildTracker.kt @@ -30,7 +30,7 @@ import java.util.* open class GradleBuildTracker(toolName: String) : BasicBuildTracker(toolName) { override fun version(): String? { - return ProjectEnv.Const.pluginVersion + return ProjectEnv.Const.OBX_PLUGIN_VERSION } fun trackBuild(env: ProjectEnv) { @@ -61,7 +61,7 @@ open class GradleBuildTracker(toolName: String) : BasicBuildTracker(toolName) { val hasKotlinPlugin = env.hasKotlinAndroidPlugin || env.hasKotlinPlugin event.key("Kotlin").value(hasKotlinPlugin.toString()).comma() event.key("Java").value(env.hasJavaPlugin.toString()).comma() - event.key("Version").value(ProjectEnv.Const.pluginVersion).comma() + event.key("Version").value(ProjectEnv.Const.OBX_PLUGIN_VERSION).comma() event.key("Target").value(if (env.hasAndroidPlugin) "Android" else "Other").comma() if (env.hasAndroidPlugin) { event.key("AGP").value(AndroidCompat.getPluginVersion(env.project)).comma() diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt index a23b6f03..9d6bafb6 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt @@ -18,6 +18,7 @@ package io.objectbox.gradle +import io.objectbox.gradle.ProjectEnv.Const import io.objectbox.gradle.transform.AndroidPluginCompat import io.objectbox.gradle.transform.ObjectBoxJavaClassesTransformTask import io.objectbox.gradle.transform.ObjectBoxJavaTransform @@ -151,7 +152,7 @@ open class ObjectBoxGradlePlugin : Plugin { private fun addDependenciesAnnotationProcessor(env: ProjectEnv) { val project = env.project if ((env.hasKotlinPlugin || env.hasKotlinAndroidPlugin) && - !project.hasConfig(ProjectEnv.Const.KAPT_CONFIGURATION_NAME) + !project.hasConfig(Const.KAPT_CONFIGURATION_NAME) ) { // Note: no-op if kapt plugin was already applied. project.plugins.apply("kotlin-kapt") @@ -159,12 +160,12 @@ open class ObjectBoxGradlePlugin : Plugin { } // Note: use plugin version for processor dependency as processor is part of this project. - val processorDep = "io.objectbox:objectbox-processor:${ProjectEnv.Const.pluginVersion}" + val processorDep = "${Const.OBX_GROUP}:${Const.OBX_PROCESSOR}:${Const.OBX_PLUGIN_VERSION}" // Note: check for and use preferred/best config first, potentially ignoring others. when { - project.hasConfig(ProjectEnv.Const.KAPT_CONFIGURATION_NAME) -> { + project.hasConfig(Const.KAPT_CONFIGURATION_NAME) -> { // Kotlin (Android + Desktop). - project.addDep(ProjectEnv.Const.KAPT_CONFIGURATION_NAME, processorDep) + project.addDep(Const.KAPT_CONFIGURATION_NAME, processorDep) } project.hasConfig(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME) -> { @@ -180,8 +181,9 @@ open class ObjectBoxGradlePlugin : Plugin { else -> { project.logger.warn( - "ObjectBox: Could not add dependency on objectbox-processor, " + - "no supported configuration (kapt, annotationProcessor, apt) found." + "ObjectBox: Could not add dependency on ${Const.OBX_PROCESSOR}, " + + "no supported configuration (${Const.KAPT_CONFIGURATION_NAME}, " + + "${JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME}, apt) found." ) } } @@ -205,10 +207,10 @@ open class ObjectBoxGradlePlugin : Plugin { /** * Version for libraries that have Sync enabled versions. - * All others always use [ProjectEnv.Const.nativeVersionToApply]. + * All others always use [ProjectEnv.Const.OBX_DATABASE_VERSION]. */ internal open fun getLibWithSyncVariantVersion(): String { - return ProjectEnv.Const.nativeVersionToApply + return Const.OBX_DATABASE_VERSION } private fun Project.addDepLater(dependencySet: DependencySet, dep: String) { @@ -219,6 +221,9 @@ open class ObjectBoxGradlePlugin : Plugin { ) } + private fun Project.addObjectBoxDepLater(dependencySet: DependencySet, name: String, version: String) = + addDepLater(dependencySet, "${Const.OBX_GROUP}:$name:$version") + /** * Before dependencies of project configurations are resolved, adds required ObjectBox dependencies, if a * conflicting one isn't added already: @@ -236,16 +241,13 @@ open class ObjectBoxGradlePlugin : Plugin { // (which, if using modern Gradle plugins syntax, they are always). project.configurations.getByName(compileConfig).withDependencies { dependencySet -> val hasKotlinPlugin = env.hasKotlinPlugin || env.hasKotlinAndroidPlugin - val hasObxKotlinLibrary = env.hasObjectBoxDep("objectbox-kotlin") + val hasObxKotlinLibrary = env.hasObjectBoxDep(Const.OBX_KOTLIN) if (hasKotlinPlugin) { if (hasObxKotlinLibrary) { - env.logDebug { "Not adding objectbox-kotlin dependency, a configuration has one" } + env.logDebug { "Not adding ${Const.OBX_KOTLIN} dependency, a configuration has one" } } else { - project.addDepLater( - dependencySet, - "io.objectbox:objectbox-kotlin:${ProjectEnv.Const.javaVersionToApply}" - ) + project.addObjectBoxDepLater(dependencySet, Const.OBX_KOTLIN, Const.OBX_JAVA_VERSION) } } @@ -254,12 +256,12 @@ open class ObjectBoxGradlePlugin : Plugin { // (only the Android library has a dependency on the Java library as it includes Java APIs). // But don't add it if the Kotlin library is manually added as it has a dependency on the Java library to // avoid pulling in a newer, possibly incompatible, Java library. - if (env.hasObjectBoxDep("objectbox-java")) { - env.logDebug { "Not adding objectbox-java dependency, a configuration has one" } + if (env.hasObjectBoxDep(Const.OBX_JAVA)) { + env.logDebug { "Not adding ${Const.OBX_JAVA} dependency, a configuration has one" } } else if (hasObxKotlinLibrary) { - env.logDebug { "Not adding objectbox-java dependency, a configuration has objectbox-kotlin" } + env.logDebug { "Not adding ${Const.OBX_JAVA} dependency, a configuration has ${Const.OBX_KOTLIN}" } } else { - project.addDepLater(dependencySet, "io.objectbox:objectbox-java:${ProjectEnv.Const.javaVersionToApply}") + project.addObjectBoxDepLater(dependencySet, Const.OBX_JAVA, Const.OBX_JAVA_VERSION) } // If the Android plugin is applied, add the Android database library, otherwise the JVM database library @@ -271,10 +273,7 @@ open class ObjectBoxGradlePlugin : Plugin { && !env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_SYNC-android-objectbrowser") && !env.hasObjectBoxDep("$LIBRARY_NAME_PREFIX_SYNC-server-android") ) { - project.addDepLater( - dependencySet, - "io.objectbox:$androidDepName:${getLibWithSyncVariantVersion()}" - ) + project.addObjectBoxDepLater(dependencySet, androidDepName, getLibWithSyncVariantVersion()) } else { env.logDebug { "Not adding $androidDepName dependency, a configuration has an Android database library" } } @@ -294,7 +293,7 @@ open class ObjectBoxGradlePlugin : Plugin { // add jsr305 to prevent conflict with other versions added by test dependencies, like espresso. // https://github.com/objectbox/objectbox-java/issues/73 project.configurations - .getByName(ProjectEnv.Const.ANDROID_TEST_IMPLEMENTATION_CONFIGURATION_NAME) + .getByName(Const.ANDROID_TEST_IMPLEMENTATION_CONFIGURATION_NAME) .dependencies .let { project.addDepLater(it, "com.google.code.findbugs:jsr305:3.0.2") } } @@ -328,7 +327,7 @@ open class ObjectBoxGradlePlugin : Plugin { if (suffix != null) { val prefix = getLibWithSyncVariantPrefix() val version = getLibWithSyncVariantVersion() - env.project.addDepLater(dependencySet, "io.objectbox:$prefix-$suffix:$version") + env.project.addObjectBoxDepLater(dependencySet, "$prefix-$suffix", version) } else { env.logInfo("Could not set up native dependency for ${env.osName}") } @@ -364,7 +363,7 @@ open class ObjectBoxGradlePlugin : Plugin { project.configurations.filterNot { it.name.contains("test", ignoreCase = true) } }.forEach { config -> config.dependencies.find { - it.group == "io.objectbox" && (if (startsWith) it.name.startsWith(name) else it.name == name) + it.group == Const.OBX_GROUP && (if (startsWith) it.name.startsWith(name) else it.name == name) }?.let { return config to it } } return null diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxSyncGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxSyncGradlePlugin.kt index ffc0dbf9..2ce4a547 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxSyncGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxSyncGradlePlugin.kt @@ -32,7 +32,7 @@ class ObjectBoxSyncGradlePlugin : ObjectBoxGradlePlugin() { } override fun getLibWithSyncVariantVersion(): String { - return ProjectEnv.Const.nativeSyncVersionToApply + return ProjectEnv.Const.OBX_DATABASE_SYNC_VERSION } } \ No newline at end of file diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt index ee596584..8dd1df5e 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt @@ -26,11 +26,16 @@ import java.util.* class ProjectEnv(val project: Project) { object Const { - const val name: String = "objectbox" - const val pluginVersion = GradlePluginBuildConfig.VERSION - const val javaVersionToApply = GradlePluginBuildConfig.APPLIES_JAVA_VERSION - const val nativeVersionToApply = GradlePluginBuildConfig.APPLIES_NATIVE_VERSION - const val nativeSyncVersionToApply = GradlePluginBuildConfig.APPLIES_NATIVE_SYNC_VERSION + const val EXTENSION_NAME: String = "objectbox" + const val OBX_PLUGIN_VERSION = GradlePluginBuildConfig.VERSION + const val OBX_JAVA_VERSION = GradlePluginBuildConfig.APPLIES_JAVA_VERSION + const val OBX_DATABASE_VERSION = GradlePluginBuildConfig.APPLIES_NATIVE_VERSION + const val OBX_DATABASE_SYNC_VERSION = GradlePluginBuildConfig.APPLIES_NATIVE_SYNC_VERSION + + const val OBX_GROUP = "io.objectbox" + const val OBX_PROCESSOR = "objectbox-processor" + const val OBX_JAVA = "objectbox-java" + const val OBX_KOTLIN = "objectbox-kotlin" /** * The name of the default configuration for @@ -43,7 +48,8 @@ class ProjectEnv(val project: Project) { } /** Note: Plugin extension, values only available after evaluation phase. */ - val options: ObjectBoxPluginExtension = project.extensions.create(Const.name, ObjectBoxPluginExtension::class.java) + val options: ObjectBoxPluginExtension = + project.extensions.create(Const.EXTENSION_NAME, ObjectBoxPluginExtension::class.java) // Note: can not use types as this project uses Android and Kotlin plugin API as compileOnly, // so the classes might be missing from projects that do not have the Android or Kotlin plugin on the classpath. diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/BuildTrackerTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/BuildTrackerTest.kt index 6a65cb18..bb52b4ce 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/BuildTrackerTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/BuildTrackerTest.kt @@ -56,7 +56,7 @@ class BuildTrackerTest { `when`(project.extensions).thenReturn(extensionContainer) val options = mock(ObjectBoxPluginExtension::class.java) - `when`(extensionContainer.create(ProjectEnv.Const.name, ObjectBoxPluginExtension::class.java)).thenReturn( + `when`(extensionContainer.create(ProjectEnv.Const.EXTENSION_NAME, ObjectBoxPluginExtension::class.java)).thenReturn( options ) @@ -74,7 +74,7 @@ class BuildTrackerTest { val distinctId = properties["distinct_id"] as String assertEquals(analytics.hashBase64WithoutPadding(aid), properties["AAID"]) assertEquals(toolName, properties["Tool"]) - assertEquals(ProjectEnv.Const.pluginVersion, properties["Version"]) + assertEquals(ProjectEnv.Const.OBX_PLUGIN_VERSION, properties["Version"]) assertEquals(GradleVersion.current().version, properties["Gradle"]) val analytics2 = spy(GradleBuildTracker(toolName)) @@ -93,7 +93,7 @@ class BuildTrackerTest { @Suppress("UNCHECKED_CAST") val properties = json["properties"] as Map - assertEquals(ProjectEnv.Const.pluginVersion, properties["Version"]) + assertEquals(ProjectEnv.Const.OBX_PLUGIN_VERSION, properties["Version"]) val exStack = properties["ExStack"] as String assertTrue(exStack, exStack.contains("Banana")) diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt index 08a786a1..2a05fe4a 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyAndroidTest.kt @@ -19,6 +19,7 @@ package io.objectbox.gradle import com.android.build.api.dsl.ApplicationExtension +import io.objectbox.gradle.ProjectEnv.Const import org.gradle.api.Project import org.gradle.api.artifacts.DependencySet import org.gradle.api.internal.project.ProjectInternal @@ -126,7 +127,7 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { private fun assertKotlinAndroidSetup(project: Project) { project.resolveDependencyGraphWithoutDownloadingFiles() with(project.configurations) { - assertProcessorDependency(getByName(ProjectEnv.Const.KAPT_CONFIGURATION_NAME).dependencies) + assertProcessorDependency(getByName(Const.KAPT_CONFIGURATION_NAME).dependencies) assertAndroidDependency(getByName(JavaPlugin.API_CONFIGURATION_NAME).dependencies) assertNativeDependency(getByName(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME).dependencies) } @@ -140,7 +141,7 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { private fun assertAndroidDependency(deps: DependencySet) { assertEquals("Android lib dependency not found", 1, deps.count { - it.group == "io.objectbox" && it.name == "$expectedLibWithSyncVariantPrefix-android" + it.group == Const.OBX_GROUP && it.name == "$expectedLibWithSyncVariantPrefix-android" && it.version == expectedLibWithSyncVariantVersion }) } @@ -164,8 +165,11 @@ abstract class PluginApplyAndroidTest : PluginApplyTest() { val project = buildAndroidProject() // Use a custom version that's easy to recognize if this test should fail - val customVersion = "${ProjectEnv.Const.nativeVersionToApply}-custom" - project.dependencies.add(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, "io.objectbox:$name:$customVersion") + val customVersion = "${Const.OBX_DATABASE_VERSION}-custom" + project.dependencies.add( + JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, + "${Const.OBX_GROUP}:$name:$customVersion" + ) project.resolveDependencyGraphWithoutDownloadingFiles() val databaseDeps = project.getDependenciesMatching { databaseLibraries.contains(it.name) } diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt index 6a593028..0d83a926 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyJavaTest.kt @@ -18,6 +18,7 @@ package io.objectbox.gradle +import io.objectbox.gradle.ProjectEnv.Const import org.gradle.api.Project import org.gradle.api.artifacts.DependencySet import org.gradle.api.internal.plugins.PluginApplicationException @@ -210,12 +211,12 @@ open class PluginApplyJavaTest : PluginApplyTest() { private fun assertKotlinSetup(project: Project) { project.resolveDependencyGraphWithoutDownloadingFiles() with(project.configurations) { - assertProcessorDependency(getByName(ProjectEnv.Const.KAPT_CONFIGURATION_NAME).dependencies) + assertProcessorDependency(getByName(Const.KAPT_CONFIGURATION_NAME).dependencies) getByName(JavaPlugin.API_CONFIGURATION_NAME).dependencies.let { deps -> assertEquals(1, deps.count { - it.group == "io.objectbox" && it.name == "objectbox-kotlin" - && it.version == ProjectEnv.Const.javaVersionToApply + it.group == Const.OBX_GROUP && it.name == Const.OBX_KOTLIN + && it.version == Const.OBX_JAVA_VERSION }) assertJavaDependency(deps) assertNativeDependency(deps) @@ -234,9 +235,9 @@ open class PluginApplyJavaTest : PluginApplyTest() { } private fun assertJavaDependency(deps: DependencySet) { - assertEquals("objectbox-java dependency not found", 1, deps.count { - it.group == "io.objectbox" && it.name == "objectbox-java" - && it.version == ProjectEnv.Const.javaVersionToApply + assertEquals("${Const.OBX_JAVA} dependency not found", 1, deps.count { + it.group == Const.OBX_GROUP && it.name == Const.OBX_JAVA + && it.version == Const.OBX_JAVA_VERSION }) } @@ -245,12 +246,12 @@ open class PluginApplyJavaTest : PluginApplyTest() { assertOnlySingleDependency( buildJavaLibraryProject(), JavaPlugin.API_CONFIGURATION_NAME, - "objectbox-java" + Const.OBX_JAVA ) assertOnlySingleDependency( buildJavaLibraryProject(), JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, - "objectbox-java" + Const.OBX_JAVA ) } @@ -260,26 +261,26 @@ open class PluginApplyJavaTest : PluginApplyTest() { assertOnlySingleDependency( projectApiConfig, JavaPlugin.API_CONFIGURATION_NAME, - "objectbox-kotlin" + Const.OBX_KOTLIN ) // Also check objectbox-java is not added as objectbox-kotlin already has a transitive dependency on it - val javaLibDeps = projectApiConfig.getDependenciesMatching { it.name == "objectbox-java" } + val javaLibDeps = projectApiConfig.getDependenciesMatching { it.name == Const.OBX_JAVA } assertTrue( - "Must not add objectbox-java library, but has:\n${javaLibDeps.joinToString("\n")}", + "Must not add ${Const.OBX_JAVA} library, but has:\n${javaLibDeps.joinToString("\n")}", javaLibDeps.isEmpty() ) assertOnlySingleDependency( buildKotlinKaptProject(), JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, - "objectbox-kotlin" + Const.OBX_KOTLIN ) } private fun assertOnlySingleDependency(forProject: Project, toConfiguration: String, name: String) { // Use a custom version that's easy to recognize if this test should fail - val customVersion = "${ProjectEnv.Const.javaVersionToApply}-custom" - forProject.dependencies.add(toConfiguration, "io.objectbox:$name:$customVersion") + val customVersion = "${Const.OBX_JAVA_VERSION}-custom" + forProject.dependencies.add(toConfiguration, "${Const.OBX_GROUP}:$name:$customVersion") forProject.resolveDependencyGraphWithoutDownloadingFiles() @@ -311,8 +312,11 @@ open class PluginApplyJavaTest : PluginApplyTest() { val project = buildJavaLibraryProject() // Use a custom version that's easy to recognize if this test should fail - val customVersion = "${ProjectEnv.Const.nativeVersionToApply}-custom" - project.dependencies.add(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, "io.objectbox:$name:$customVersion") + val customVersion = "${Const.OBX_DATABASE_VERSION}-custom" + project.dependencies.add( + JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME, + "${Const.OBX_GROUP}:$name:$customVersion" + ) project.resolveDependencyGraphWithoutDownloadingFiles() val databaseDeps = project.getDependenciesMatching { databaseLibraries.contains(it.name) } diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt index dec1883d..4a85fcf3 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt @@ -18,6 +18,7 @@ package io.objectbox.gradle +import io.objectbox.gradle.ProjectEnv.Const import org.gradle.api.Project import org.gradle.api.artifacts.Dependency import org.gradle.api.artifacts.DependencySet @@ -33,7 +34,7 @@ abstract class PluginApplyTest { open val pluginId = "io.objectbox" open val expectedLibWithSyncVariantPrefix = "objectbox" - open val expectedLibWithSyncVariantVersion = ProjectEnv.Const.nativeVersionToApply + open val expectedLibWithSyncVariantVersion = Const.OBX_DATABASE_VERSION protected fun buildProject( configureProject: Project.() -> Unit @@ -54,7 +55,7 @@ abstract class PluginApplyTest { */ protected fun Project.enableObjectBoxPluginDebugMode() { extensions.apply { - configure("objectbox") { + configure(Const.EXTENSION_NAME) { it.debug.set(true) } } @@ -74,15 +75,15 @@ abstract class PluginApplyTest { } fun assertProcessorDependency(apDeps: DependencySet) { - assertEquals("objectbox-processor dependency not found", 1, apDeps.count { - it.group == "io.objectbox" && it.name == "objectbox-processor" - && it.version == ProjectEnv.Const.pluginVersion + assertEquals("${Const.OBX_PROCESSOR} dependency not found", 1, apDeps.count { + it.group == Const.OBX_GROUP && it.name == Const.OBX_PROCESSOR + && it.version == Const.OBX_PLUGIN_VERSION }) } fun assertNativeDependency(deps: DependencySet) { assertEquals("JVM database library dependency not found", 1, deps.count { - it.group == "io.objectbox" + it.group == Const.OBX_GROUP && (it.name == "$expectedLibWithSyncVariantPrefix-linux" || it.name == "$expectedLibWithSyncVariantPrefix-windows" || it.name == "$expectedLibWithSyncVariantPrefix-macos") diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyAndroidTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyAndroidTest.kt index 22713e48..c2977173 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyAndroidTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyAndroidTest.kt @@ -25,6 +25,6 @@ abstract class SyncPluginApplyAndroidTest : PluginApplyAndroidTest() { override val pluginId = "io.objectbox.sync" override val expectedLibWithSyncVariantPrefix = "objectbox-sync" - override val expectedLibWithSyncVariantVersion = ProjectEnv.Const.nativeSyncVersionToApply + override val expectedLibWithSyncVariantVersion = ProjectEnv.Const.OBX_DATABASE_SYNC_VERSION } \ No newline at end of file diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyJavaTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyJavaTest.kt index b4ae29a0..a68eb4fa 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyJavaTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyJavaTest.kt @@ -26,6 +26,6 @@ class SyncPluginApplyJavaTest : PluginApplyJavaTest() { override val pluginId = "io.objectbox.sync" override val expectedLibWithSyncVariantPrefix = "objectbox-sync" - override val expectedLibWithSyncVariantVersion = ProjectEnv.Const.nativeSyncVersionToApply + override val expectedLibWithSyncVariantVersion = ProjectEnv.Const.OBX_DATABASE_SYNC_VERSION } \ No newline at end of file From 481e9f78766e278fdbb01bcd0a18e829c9be47e4 Mon Sep 17 00:00:00 2001 From: Uwe Date: Mon, 9 Mar 2026 14:19:44 +0100 Subject: [PATCH 16/17] Plugin: drop unused apt support The lowest supported Gradle version (7.0) does support the new annotationProcessor configuration since a few releases. Plugins that use the apt configuration aren't maintained for many years. --- .../kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt index 9d6bafb6..bfdda91f 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt @@ -173,17 +173,11 @@ open class ObjectBoxGradlePlugin : Plugin { project.addDep(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME, processorDep) } - project.hasConfig("apt") -> { - // https://bitbucket.org/hvisser/android-apt or custom apt - // https://docs.gradle.org/current/userguide/java_plugin.html#sec:java_compile_avoidance - project.addDep("apt", processorDep) - } - else -> { project.logger.warn( "ObjectBox: Could not add dependency on ${Const.OBX_PROCESSOR}, " + "no supported configuration (${Const.KAPT_CONFIGURATION_NAME}, " + - "${JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME}, apt) found." + "${JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME}) found." ) } } From 229c48296eefa2f38b354afeff4a2573056c8e8b Mon Sep 17 00:00:00 2001 From: Uwe Date: Mon, 9 Mar 2026 14:27:34 +0100 Subject: [PATCH 17/17] ProjectEnv constants: add for plugin IDs --- .../kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt | 5 +++-- .../kotlin/io/objectbox/gradle/ObjectBoxSyncGradlePlugin.kt | 6 ++++-- .../src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt | 2 ++ .../src/test/kotlin/io/objectbox/gradle/GradleTestRunner.kt | 3 ++- .../src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt | 2 +- .../io/objectbox/gradle/SyncPluginApplyAndroidTest.kt | 6 ++++-- .../kotlin/io/objectbox/gradle/SyncPluginApplyJavaTest.kt | 4 +++- 7 files changed, 19 insertions(+), 9 deletions(-) diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt index bfdda91f..77265595 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxGradlePlugin.kt @@ -48,9 +48,10 @@ import org.gradle.api.tasks.compile.JavaCompile open class ObjectBoxGradlePlugin : Plugin { /** - * The Gradle plugin id as registered in resources/META-INF/gradle-plugins. + * The Gradle plugin id as registered in resources/META-INF/gradle-plugins (but actually configured using the + * Gradle plugin development plugin in the build script using the gradlePlugin extension). */ - internal open val pluginId = "io.objectbox" + internal open val pluginId = Const.PLUGIN_ID private val buildTracker = GradleBuildTracker("GradlePlugin") diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxSyncGradlePlugin.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxSyncGradlePlugin.kt index 2ce4a547..0104e7db 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxSyncGradlePlugin.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ObjectBoxSyncGradlePlugin.kt @@ -18,13 +18,15 @@ package io.objectbox.gradle +import io.objectbox.gradle.ProjectEnv.Const + /** * Like [ObjectBoxGradlePlugin], but adds native libraries that are sync-enabled as dependencies. */ class ObjectBoxSyncGradlePlugin : ObjectBoxGradlePlugin() { - override val pluginId = "io.objectbox.sync" + override val pluginId = Const.SYNC_PLUGIN_ID override fun getLibWithSyncVariantPrefix(): String { // Use Sync version. @@ -32,7 +34,7 @@ class ObjectBoxSyncGradlePlugin : ObjectBoxGradlePlugin() { } override fun getLibWithSyncVariantVersion(): String { - return ProjectEnv.Const.OBX_DATABASE_SYNC_VERSION + return Const.OBX_DATABASE_SYNC_VERSION } } \ No newline at end of file diff --git a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt index 8dd1df5e..f85d3f5d 100644 --- a/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt +++ b/objectbox-gradle-plugin/src/main/kotlin/io/objectbox/gradle/ProjectEnv.kt @@ -26,6 +26,8 @@ import java.util.* class ProjectEnv(val project: Project) { object Const { + const val PLUGIN_ID = "io.objectbox" + const val SYNC_PLUGIN_ID = "io.objectbox.sync" const val EXTENSION_NAME: String = "objectbox" const val OBX_PLUGIN_VERSION = GradlePluginBuildConfig.VERSION const val OBX_JAVA_VERSION = GradlePluginBuildConfig.APPLIES_JAVA_VERSION diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/GradleTestRunner.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/GradleTestRunner.kt index 3985fc5e..f6a9032d 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/GradleTestRunner.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/GradleTestRunner.kt @@ -18,6 +18,7 @@ package io.objectbox.gradle +import io.objectbox.gradle.ProjectEnv.Const import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.GradleRunner import org.intellij.lang.annotations.Language @@ -76,7 +77,7 @@ class GradleTestRunner( plugins { ${additionalPlugins.joinToString(separator = "\n") { "id(\"$it\")" }} - id("io.objectbox") + id("${Const.PLUGIN_ID}") } java { diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt index 4a85fcf3..66d71d65 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/PluginApplyTest.kt @@ -32,7 +32,7 @@ import org.junit.Assert.assertTrue */ abstract class PluginApplyTest { - open val pluginId = "io.objectbox" + open val pluginId = Const.PLUGIN_ID open val expectedLibWithSyncVariantPrefix = "objectbox" open val expectedLibWithSyncVariantVersion = Const.OBX_DATABASE_VERSION diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyAndroidTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyAndroidTest.kt index c2977173..58a95ed9 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyAndroidTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyAndroidTest.kt @@ -18,13 +18,15 @@ package io.objectbox.gradle +import io.objectbox.gradle.ProjectEnv.Const + /** * Base class to test applying [ObjectBoxSyncGradlePlugin] configures a Java or Kotlin Android Gradle project as expected. */ abstract class SyncPluginApplyAndroidTest : PluginApplyAndroidTest() { - override val pluginId = "io.objectbox.sync" + override val pluginId = Const.SYNC_PLUGIN_ID override val expectedLibWithSyncVariantPrefix = "objectbox-sync" - override val expectedLibWithSyncVariantVersion = ProjectEnv.Const.OBX_DATABASE_SYNC_VERSION + override val expectedLibWithSyncVariantVersion = Const.OBX_DATABASE_SYNC_VERSION } \ No newline at end of file diff --git a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyJavaTest.kt b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyJavaTest.kt index a68eb4fa..dda26572 100644 --- a/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyJavaTest.kt +++ b/objectbox-gradle-plugin/src/test/kotlin/io/objectbox/gradle/SyncPluginApplyJavaTest.kt @@ -18,13 +18,15 @@ package io.objectbox.gradle +import io.objectbox.gradle.ProjectEnv.Const + /** * Tests applying [ObjectBoxSyncGradlePlugin] configures a Java or Kotlin desktop Gradle project as expected. */ class SyncPluginApplyJavaTest : PluginApplyJavaTest() { - override val pluginId = "io.objectbox.sync" + override val pluginId = Const.SYNC_PLUGIN_ID override val expectedLibWithSyncVariantPrefix = "objectbox-sync" override val expectedLibWithSyncVariantVersion = ProjectEnv.Const.OBX_DATABASE_SYNC_VERSION