diff --git a/build-logic/PUBLISHING.md b/build-logic/PUBLISHING.md
index ae80240571e1e..0fbfb655a5179 100644
--- a/build-logic/PUBLISHING.md
+++ b/build-logic/PUBLISHING.md
@@ -30,6 +30,13 @@ By default (`publishApiAndSpiOnly` unset or `false`), Gradle publishes the modul
publishing conventions, including the root `pulsar` parent POM and the full `pulsar-bom`. The
repository's `gradle.properties` supplies the default group (`org.apache.pulsar`) and version.
+As in the `branch-4.2` Maven build, publications for `managed-ledger`, `pulsar-broker`,
+`pulsar-broker-common`, `pulsar-metadata`, and `pulsar-package-core` include a `tests` classifier
+JAR. These test JARs are published in both ordinary and API/SPI mode. In Maven,
+`test-jar` and `tests` refer to the same test JAR; declare
+only one dependency per module. Test JARs share their module's POM and do not expose its test
+dependencies transitively, so consumers must declare any additional test dependencies they need.
+
Choose the task for the intended destination:
| Task | Destination | Version requirement |
@@ -222,6 +229,9 @@ client, Pulsar Functions, and Pulsar plugins such as interceptors and additional
includes the client implementations (including v5), API and service provider interface (SPI)
libraries, and their transitive Pulsar dependencies.
+The selection also includes the `buildtools` JAR and all five test JAR publications described
+above to support external tests.
+
A typical use case is distributing a custom Pulsar Java client build to your own Maven repository
so applications can quickly adopt a bug fix or security fix in Pulsar itself. Publishing this subset
avoids performing a full Pulsar dependency release to that repository. For deploying a custom server
diff --git a/build-logic/conventions/src/main/kotlin/pulsar.publish-conventions.gradle.kts b/build-logic/conventions/src/main/kotlin/pulsar.publish-conventions.gradle.kts
index 253fd5b6ee338..ab6475bb716cd 100644
--- a/build-logic/conventions/src/main/kotlin/pulsar.publish-conventions.gradle.kts
+++ b/build-logic/conventions/src/main/kotlin/pulsar.publish-conventions.gradle.kts
@@ -63,6 +63,16 @@ pluginManager.withPlugin("java-library") {
val mavenPublication = publishing.publications.create("maven") {
artifact(sourcesJar)
artifact(javadocJar)
+ // Preserve the test JAR publications from the branch-4.2 Maven build in both modes.
+ if (project.path in setOf(
+ ":managed-ledger",
+ ":pulsar-broker",
+ ":pulsar-broker-common",
+ ":pulsar-metadata",
+ ":pulsar-package-management:pulsar-package-core",
+ )) {
+ artifact(tasks.named("testJar"))
+ }
}
// Shaded modules: the shadow plugin registers components["shadow"] in its own afterEvaluate, so
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 71fc0d55ab033..daccf02721774 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -172,7 +172,7 @@ felix-http-wrappers = "1.1.10"
oxia = "0.9.5"
oxia-testcontainers = "0.7.4"
# Build plugins
-lightproto = "0.8.1"
+lightproto = "0.8.2"
graalvm-buildtools = "1.1.9"
errorprone = "2.50.0"
spotbugs = "4.10.3"