From 87c2e8d3c51bdb314d46e4faaac3647562b02ca8 Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Wed, 1 Jul 2026 15:30:04 +0530 Subject: [PATCH 1/2] feat(java): Spring Boot 3 starter module --- sdks/java/settings.gradle.kts | 1 + sdks/java/spring/build.gradle.kts | 56 +++++++++++++++++++ .../spring/TaskitoAutoConfiguration.java | 35 ++++++++++++ .../taskito/spring/TaskitoProperties.java | 40 +++++++++++++ .../byteveda/taskito/spring/package-info.java | 7 +++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + 6 files changed, 140 insertions(+) create mode 100644 sdks/java/spring/build.gradle.kts create mode 100644 sdks/java/spring/src/main/java/org/byteveda/taskito/spring/TaskitoAutoConfiguration.java create mode 100644 sdks/java/spring/src/main/java/org/byteveda/taskito/spring/TaskitoProperties.java create mode 100644 sdks/java/spring/src/main/java/org/byteveda/taskito/spring/package-info.java create mode 100644 sdks/java/spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports diff --git a/sdks/java/settings.gradle.kts b/sdks/java/settings.gradle.kts index df678ee9..351c8802 100644 --- a/sdks/java/settings.gradle.kts +++ b/sdks/java/settings.gradle.kts @@ -3,3 +3,4 @@ rootProject.name = "taskito" include(":processor") include(":test-support") include(":graalvm-smoke") +include(":spring") diff --git a/sdks/java/spring/build.gradle.kts b/sdks/java/spring/build.gradle.kts new file mode 100644 index 00000000..8e15e366 --- /dev/null +++ b/sdks/java/spring/build.gradle.kts @@ -0,0 +1,56 @@ +// taskito-spring: a Spring Boot 3 starter that auto-configures a Taskito bean. +// Spring Boot 3 requires Java 17, which matches the SDK baseline. +plugins { + `java-library` + checkstyle + id("com.diffplug.spotless") version "7.2.1" +} + +group = "org.byteveda" + +version = "0.18.0" + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +tasks.withType().configureEach { options.release.set(17) } + +repositories { mavenCentral() } + +val springBoot = "3.3.5" + +dependencies { + api(project(":")) + compileOnly("org.springframework.boot:spring-boot-autoconfigure:$springBoot") + annotationProcessor("org.springframework.boot:spring-boot-configuration-processor:$springBoot") + + testImplementation(platform("org.junit:junit-bom:5.10.3")) + testImplementation("org.junit.jupiter:junit-jupiter") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + testImplementation("org.springframework.boot:spring-boot-autoconfigure:$springBoot") + testImplementation("org.springframework.boot:spring-boot-test:$springBoot") + testImplementation("org.springframework:spring-test:6.1.14") + // AssertableApplicationContext implements AssertJ's AssertProvider, so the + // type must be on the test classpath even though we assert with JUnit. + testImplementation("org.assertj:assertj-core:3.25.3") +} + +spotless { + java { + target("src/**/*.java") + palantirJavaFormat("2.50.0") + removeUnusedImports() + trimTrailingWhitespace() + endWithNewline() + } +} + +checkstyle { + toolVersion = "10.21.4" + configFile = file("../config/checkstyle/checkstyle.xml") + isIgnoreFailures = false +} + +tasks.test { useJUnitPlatform() } diff --git a/sdks/java/spring/src/main/java/org/byteveda/taskito/spring/TaskitoAutoConfiguration.java b/sdks/java/spring/src/main/java/org/byteveda/taskito/spring/TaskitoAutoConfiguration.java new file mode 100644 index 00000000..e7fbd314 --- /dev/null +++ b/sdks/java/spring/src/main/java/org/byteveda/taskito/spring/TaskitoAutoConfiguration.java @@ -0,0 +1,35 @@ +package org.byteveda.taskito.spring; + +import org.byteveda.taskito.Taskito; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; + +/** + * Auto-configures a single {@link Taskito} bean from {@link TaskitoProperties}. + * The bean is closed with the application context. Define your own {@code Taskito} + * bean to override it. + */ +@AutoConfiguration +@ConditionalOnClass(Taskito.class) +@EnableConfigurationProperties(TaskitoProperties.class) +public class TaskitoAutoConfiguration { + + @Bean(destroyMethod = "close") + @ConditionalOnMissingBean + public Taskito taskito(TaskitoProperties properties) { + Taskito.Builder builder = Taskito.builder(); + if (properties.getUrl() != null) { + builder.url(properties.getUrl()); + } + if (properties.getPoolSize() != null) { + builder.poolSize(properties.getPoolSize()); + } + if (properties.getNamespace() != null) { + builder.namespace(properties.getNamespace()); + } + return builder.open(); + } +} diff --git a/sdks/java/spring/src/main/java/org/byteveda/taskito/spring/TaskitoProperties.java b/sdks/java/spring/src/main/java/org/byteveda/taskito/spring/TaskitoProperties.java new file mode 100644 index 00000000..ca5bed64 --- /dev/null +++ b/sdks/java/spring/src/main/java/org/byteveda/taskito/spring/TaskitoProperties.java @@ -0,0 +1,40 @@ +package org.byteveda.taskito.spring; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** Configuration for the auto-configured {@link org.byteveda.taskito.Taskito} bean, bound from {@code taskito.*}. */ +@ConfigurationProperties(prefix = "taskito") +public class TaskitoProperties { + /** Connection URL / DSN (e.g. a SQLite path, or a {@code postgres://}/{@code redis://} URL). */ + private String url; + + /** Connection-pool size; unset uses the backend default. */ + private Integer poolSize; + + /** Optional namespace isolating this app's jobs within a shared store. */ + private String namespace; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public Integer getPoolSize() { + return poolSize; + } + + public void setPoolSize(Integer poolSize) { + this.poolSize = poolSize; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } +} diff --git a/sdks/java/spring/src/main/java/org/byteveda/taskito/spring/package-info.java b/sdks/java/spring/src/main/java/org/byteveda/taskito/spring/package-info.java new file mode 100644 index 00000000..0dd3e0c6 --- /dev/null +++ b/sdks/java/spring/src/main/java/org/byteveda/taskito/spring/package-info.java @@ -0,0 +1,7 @@ +/** + * Spring Boot 3 starter for Taskito. On the classpath, it auto-configures a + * {@link org.byteveda.taskito.Taskito} bean from {@code taskito.*} properties + * (see {@link org.byteveda.taskito.spring.TaskitoProperties}). Define your own + * {@code Taskito} bean to override it. + */ +package org.byteveda.taskito.spring; diff --git a/sdks/java/spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sdks/java/spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..0932fce2 --- /dev/null +++ b/sdks/java/spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.byteveda.taskito.spring.TaskitoAutoConfiguration From 3ba24e5e8b058444fa73f3be94376e6252a6183c Mon Sep 17 00:00:00 2001 From: Pratyush Sharma <56130065+pratyush618@users.noreply.github.com> Date: Wed, 1 Jul 2026 15:30:05 +0530 Subject: [PATCH 2/2] test(java): cover the Spring auto-configuration --- .../spring/TaskitoAutoConfigurationTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 sdks/java/spring/src/test/java/org/byteveda/taskito/spring/TaskitoAutoConfigurationTest.java diff --git a/sdks/java/spring/src/test/java/org/byteveda/taskito/spring/TaskitoAutoConfigurationTest.java b/sdks/java/spring/src/test/java/org/byteveda/taskito/spring/TaskitoAutoConfigurationTest.java new file mode 100644 index 00000000..0bf03f8e --- /dev/null +++ b/sdks/java/spring/src/test/java/org/byteveda/taskito/spring/TaskitoAutoConfigurationTest.java @@ -0,0 +1,27 @@ +package org.byteveda.taskito.spring; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.file.Path; +import org.byteveda.taskito.Taskito; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.api.io.TempDir; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +class TaskitoAutoConfigurationTest { + + private final ApplicationContextRunner runner = + new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(TaskitoAutoConfiguration.class)); + + @Test + @Timeout(30) + void providesTaskitoBeanFromProperties(@TempDir Path dir) { + runner.withPropertyValues("taskito.url=" + dir.resolve("s.db")).run(ctx -> { + assertTrue(ctx.getStartupFailure() == null); + assertNotNull(ctx.getBean(Taskito.class)); + }); + } +}