diff --git a/okapi-core/src/main/kotlin/com/softwaremill/okapi/core/OutboxProcessor.kt b/okapi-core/src/main/kotlin/com/softwaremill/okapi/core/OutboxProcessor.kt index 84cc82d..6006e3c 100644 --- a/okapi-core/src/main/kotlin/com/softwaremill/okapi/core/OutboxProcessor.kt +++ b/okapi-core/src/main/kotlin/com/softwaremill/okapi/core/OutboxProcessor.kt @@ -18,7 +18,7 @@ import java.time.Duration * fire-flush-await — making per-entry timing meaningless). Use * [OutboxProcessorListener.onBatchProcessed] when you need batch-level timing. */ -class OutboxProcessor( +class OutboxProcessor @JvmOverloads constructor( private val store: OutboxStore, private val entryProcessor: OutboxEntryProcessor, private val listener: OutboxProcessorListener? = null, diff --git a/okapi-core/src/test/java/com/softwaremill/okapi/core/JavaOutboxProcessorConstruction.java b/okapi-core/src/test/java/com/softwaremill/okapi/core/JavaOutboxProcessorConstruction.java new file mode 100644 index 0000000..17234de --- /dev/null +++ b/okapi-core/src/test/java/com/softwaremill/okapi/core/JavaOutboxProcessorConstruction.java @@ -0,0 +1,26 @@ +package com.softwaremill.okapi.core; + +/** + * Java-side guard for {@code @JvmOverloads} on {@link OutboxProcessor}'s constructor. + * + *
These call sites compile only if {@code OutboxProcessor} exposes the shorter,
+ * default-omitting constructors to Java. Drop {@code @JvmOverloads} and okapi-core's test
+ * compilation fails right here — which is the point: a Kotlin-only test keeps compiling
+ * (Kotlin fills defaults at the call site) and would hide the regression. {@code
+ * OutboxProcessorJavaInteropTest} calls these so the guard also runs.
+ */
+public final class JavaOutboxProcessorConstruction {
+
+ private JavaOutboxProcessorConstruction() {}
+
+ /** {@code OutboxProcessor(store, entryProcessor)} — listener and clock default. */
+ public static OutboxProcessor withStoreAndProcessor(OutboxStore store, OutboxEntryProcessor entryProcessor) {
+ return new OutboxProcessor(store, entryProcessor);
+ }
+
+ /** {@code OutboxProcessor(store, entryProcessor, listener)} — clock defaults. */
+ public static OutboxProcessor withListener(
+ OutboxStore store, OutboxEntryProcessor entryProcessor, OutboxProcessorListener listener) {
+ return new OutboxProcessor(store, entryProcessor, listener);
+ }
+}
diff --git a/okapi-core/src/test/kotlin/com/softwaremill/okapi/core/OutboxProcessorJavaInteropTest.kt b/okapi-core/src/test/kotlin/com/softwaremill/okapi/core/OutboxProcessorJavaInteropTest.kt
new file mode 100644
index 0000000..64649b7
--- /dev/null
+++ b/okapi-core/src/test/kotlin/com/softwaremill/okapi/core/OutboxProcessorJavaInteropTest.kt
@@ -0,0 +1,46 @@
+package com.softwaremill.okapi.core
+
+import io.kotest.core.spec.style.FunSpec
+import io.kotest.matchers.nulls.shouldNotBeNull
+import java.time.Clock
+import java.time.Instant
+
+/**
+ * Runs the Java call sites in [JavaOutboxProcessorConstruction], which compile only when
+ * [OutboxProcessor]'s constructor carries `@JvmOverloads`. The real guard is that Java source
+ * compiling — okapi-core has no other Java interop test, which is why the missing annotation
+ * regressed unnoticed. The stubs are inert: the constructor only stores its arguments.
+ */
+class OutboxProcessorJavaInteropTest :
+ FunSpec({
+ val store =
+ object : OutboxStore {
+ override fun persist(entry: OutboxEntry) = entry
+
+ override fun claimPending(limit: Int) = emptyList