This is an automated email from the ASF dual-hosted git repository.

leginee pushed a commit to branch bazel-migration
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit 1ca09b6d760989eee2987d8ea352faba824f901b
Author: Peter Kovacs <[email protected]>
AuthorDate: Sat Jun 27 02:21:45 2026 +0200

    java bridge migrated
---
 CLAUDE.md                                    |   8 +-
 build/rules/gtest_test.bzl                   |   7 +
 main/bridges/BUILD.bazel                     | 212 +++++++++++++++++++++++++++
 main/bridges/readme.md                       |  74 ++++++++++
 main/bridges/test/inter_libs_exc/starter.def |   3 +
 main/bridges/test/inter_libs_exc/thrower.def |   3 +
 main/bridges/util/java_uno.def               |  16 ++
 main/staging/BUILD.bazel                     |   5 +
 8 files changed, 327 insertions(+), 1 deletion(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index f56f7a43cb..918bf22176 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -28,7 +28,13 @@ testtools     ⬜  (bridgetest — pure-C++ UNO bridge 
round-trip; cli/pyuno/jav
 qadevOOo      ⬜  (Java-based QA test framework; needs rules_java — see Java 
bucket)
 testgraphical ⬜  (graphical/visual regression tests; needs instsetoo_native + 
qadevOOo)
 
-── Remaining: Java-based (gated on rules_java / UNO-Java component rules) ─
+── Remaining: Java-based ────────────────────────────────────────────────
+NOTE: rules_java 8.11.0 IS now wired (MODULE.bazel) and the core Java UNO
+runtime is migrated & green — ridljar/jurt/jvmaccess/javaunohelper/jvmfwk/
+bridges (incl. the java_uno JNI bridge: java_uno.dll + java_uno.jar, done
+2026-06-26)/stoc/io/remotebridges/unotools/unoil/pyuno.  The items below are
+the higher-level Java apps/extensions still to do (no longer gated on 
rules_java
+itself; per-module UNO-Java component/packaging rules may still be needed).
 reportbuilder ⬜  (pure Java .oxt extension; blockers: JFreeReport suite not on 
Maven, SourceForge ZIPs have token-based URLs; wizards dep also deferred)
 bean          ⬜  (Java bean component)
 saxon         ⬜  (XSLT 2.0 processor — IN SCOPE for full migration.  Feeds the
diff --git a/build/rules/gtest_test.bzl b/build/rules/gtest_test.bzl
index a2d913d2d2..15577a9ccf 100644
--- a/build/rules/gtest_test.bzl
+++ b/build/rules/gtest_test.bzl
@@ -84,6 +84,13 @@ _staged_gtest_test = rule(
     },
 )
 
+# The staging rule above is NOT gtest-specific: it stages an arbitrary /MD exe 
+
+# runtime DLLs + VC90 CRT + external manifest into one flat dir and runs it as 
a
+# test (pass/fail = process exit code).  Exposed for non-gtest runnable tests,
+# e.g. bridges' inter_libs_exc (a cross-DLL C++ exception smoke test whose exe
+# loads two sibling DLLs and exits 0 iff exception propagation works).
+staged_run_test = _staged_gtest_test
+
 def gtest_test(
         name,
         srcs,
diff --git a/main/bridges/BUILD.bazel b/main/bridges/BUILD.bazel
index f7c4ddaa58..d1cb669c7d 100644
--- a/main/bridges/BUILD.bazel
+++ b/main/bridges/BUILD.bazel
@@ -1,6 +1,8 @@
 package(default_visibility = ["//visibility:public"])
 
 load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
+load("@rules_java//java:defs.bzl", "java_library")
+load("//build/rules:gtest_test.bzl", "staged_run_test")
 
 _COPTS = [
     "/Zm500", "/Zc:forScope", "/GR", "/nologo", "/Gs",
@@ -90,3 +92,213 @@ filegroup(
     output_group = "interface_library",
     visibility = ["//visibility:public"],
 )
+
+# ── java_uno bridge (Java↔C++ UNO bridge) ────────────────────────────────
+# Two cooperating artifacts:
+#   • java_uno.dll  — native JNI bridge (this cc_binary)
+#   • java_uno.jar  — the Java side (java_library below), loaded reflectively
+# jurt's NativeThreadPool does System.loadLibrary("java_uno") at runtime, so 
the
+# .jar and .dll are linked only at runtime, not at build time.
+
+# Local copts for the jni_uno layer: quote-includes resolve same-dir, but the
+# explicit -I keeps cross-file jni_*.h includes robust.  inc/pch (for
+# precompiled_bridges_java_uno.hxx) and the UNO/sal/cppu/udkapi -I paths come 
in
+# via :bridges_headers and the header deps below.
+_JNI_COPTS = [
+    "/Zm500", "/Zc:forScope", "/GR", "/nologo", "/Gs",
+    "/EHsc",
+    # sal_Unicode must equal jchar (unsigned short). With native wchar_t it's a
+    # distinct type, so JNI calls like GetStringRegion(...,jchar*) reject
+    # sal_Unicode*. /Zc:wchar_t- makes wchar_t == unsigned short == 
sal_Unicode.
+    "/Zc:wchar_t-",
+    "/Dsnprintf=_snprintf",
+    "/Imain/bridges/source/jni_uno",
+    "/Imain/bridges/inc/pch",
+    "/wd4061", "/wd4127",
+]
+
+# ── java_uno.dll ─────────────────────────────────────────────────────────
+# JNICALL is __stdcall on Win32, so the Java_* methods would otherwise be
+# decorated _Java_...@N which the JVM cannot resolve; util/java_uno.def exports
+# the undecorated names (same pattern as jurt's jpipe.def).  The DEF also 
exports
+# the three UNO C entry points (uno_initEnvironment / uno_ext_getMapping /
+# component_canUnload) for the c++_uno↔java_uno mapping bridge.
+cc_binary(
+    name = "java_uno",
+    srcs = [
+        "source/jni_uno/jni_base.h",
+        "source/jni_uno/jni_bridge.cxx",
+        "source/jni_uno/jni_bridge.h",
+        "source/jni_uno/jni_data.cxx",
+        "source/jni_uno/jni_helper.h",
+        "source/jni_uno/jni_info.cxx",
+        "source/jni_uno/jni_info.h",
+        "source/jni_uno/jni_java2uno.cxx",
+        "source/jni_uno/jni_uno2java.cxx",
+        "source/jni_uno/nativethreadpool.cxx",
+    ],
+    copts = _JNI_COPTS,
+    # SOLAR_JAVA makes jvmaccess/virtualmachine.hxx #include the real <jni.h>
+    # instead of its stub typedefs (jint=int, jobject=void*); without it the 
stubs
+    # clash with the real jni.h pulled in by these sources → jint/JNIEnv 
redefinition.
+    defines = _SLO_DEFINES + ["SOLAR_JAVA"],
+    deps = [
+        ":bridges_headers",
+        "//main/sal:sal_headers",
+        "//main/cppu:cppu_headers",
+        "//main/udkapi:udkapi_idl_headers",
+        "//main/jvmaccess:jvmaccess_headers",
+        # jvmaccess/unovirtualmachine.hxx includes 
salhelper/simplereferenceobject.hxx
+        # but jvmaccess_headers doesn't propagate salhelper_headers (see its 
deps),
+        # so consumers must add it explicitly — same as jvmaccess3MSC does.
+        "//main/salhelper:salhelper_headers",
+        # jni_info.h uses ::std::hash_map, which only lives in std:: under 
stlport
+        # (VS2008 native puts hash_map in stdext::). Upstream relies on the 
global
+        # SOLAR stlport; here it's an explicit dep.
+        "//main/stlport:stlport",
+        "@rules_java//toolchains:jni",
+    ],
+    additional_linker_inputs = [
+        "//main/sal:sal_implib",
+        "//main/salhelper:salhelper_implib",
+        "//main/cppu:cppu3_implib",
+        "//main/jvmaccess:jvmaccess3MSC_implib",
+    ],
+    linkshared = True,
+    win_def_file = "util/java_uno.def",
+    linkopts = [
+        "$(execpath //main/sal:sal_implib)",
+        "$(execpath //main/salhelper:salhelper_implib)",
+        "$(execpath //main/cppu:cppu3_implib)",
+        "$(execpath //main/jvmaccess:jvmaccess3MSC_implib)",
+    ],
+    visibility = ["//visibility:public"],
+)
+
+# ── java_uno.jar ─────────────────────────────────────────────────────────
+# JNI_proxy + JNI_info_holder.  Helper classes (AsynchronousFinalizer,
+# NativeLibraryLoader) live in jurt; the UNO types come from ridl.  Sealed
+# manifest is a deployment detail (handled at staging), not a build concern.
+java_library(
+    name = "java_uno_jar",
+    srcs = glob(["java/java_uno/src/main/java/**/*.java"]),
+    javacopts = ["--release", "8", "-XepDisableAllChecks"],
+    deps = [
+        "//main/jurt:jurt",
+        "//main/ridljar:ridl",
+    ],
+    visibility = ["//visibility:public"],
+)
+
+# ═══════════════════════════════════════════════════════════════════════════
+# Tests
+# ═══════════════════════════════════════════════════════════════════════════
+# inter_libs_exc — verifies a UNO/C++ exception thrown in one shared library is
+# caught across the boundary in another (an MSVC RTTI/ABI sanity check for the
+# bridge's exception handling).  inter.exe loads thrower.dll + starter.dll by
+# bare name (osl::Module), thrower throws lang::IllegalArgumentException,
+# starter catches it.  Single process, no UNO connection, no Java — the only
+# bridges/test that runs without a qadevOOo/running-soffice fixture.
+
+_TEST_COPTS = [
+    "/EHsc", "/GR", "/nologo",
+    "/Dsnprintf=_snprintf",
+    "/Imain/bridges/inc/pch",  # precompiled_bridges.hxx (plain #include, not 
/Yu)
+]
+
+_TEST_DLL_DEFINES = _DEFINES + ["SHAREDLIB", "_DLL_"]
+
+# thrower.dll / starter.dll — target names MUST be the bare dll basenames 
because
+# inter.exe loads them via osl::Module("thrower"/"starter") (Windows 
LoadLibrary
+# resolves them from the staged exe's own directory).
+
+# thrower.dll — exports get_thrower(); throws a UNO exception.
+cc_binary(
+    name = "thrower",
+    srcs = [
+        "test/inter_libs_exc/thrower.cxx",
+        "test/inter_libs_exc/share.h",
+    ],
+    copts = _TEST_COPTS,
+    defines = _TEST_DLL_DEFINES,
+    testonly = True,
+    linkshared = True,
+    win_def_file = "test/inter_libs_exc/thrower.def",
+    deps = [
+        "//main/sal:sal_headers",
+        "//main/cppu:cppu_headers",
+        "//main/udkapi:udkapi_idl_headers",
+    ],
+    additional_linker_inputs = [
+        "//main/sal:sal_implib",
+        "//main/cppu:cppu3_implib",
+    ],
+    linkopts = [
+        "$(execpath //main/sal:sal_implib)",
+        "$(execpath //main/cppu:cppu3_implib)",
+        "/MANIFEST:NO",
+    ],
+)
+
+# starter.dll — exports start(p); calls p() and catches the exception.
+cc_binary(
+    name = "starter",
+    srcs = [
+        "test/inter_libs_exc/starter.cxx",
+        "test/inter_libs_exc/share.h",
+    ],
+    copts = _TEST_COPTS,
+    defines = _TEST_DLL_DEFINES,
+    testonly = True,
+    linkshared = True,
+    win_def_file = "test/inter_libs_exc/starter.def",
+    deps = [
+        "//main/sal:sal_headers",
+        "//main/cppu:cppu_headers",
+        "//main/udkapi:udkapi_idl_headers",
+    ],
+    additional_linker_inputs = [
+        "//main/sal:sal_implib",
+        "//main/cppu:cppu3_implib",
+    ],
+    linkopts = [
+        "$(execpath //main/sal:sal_implib)",
+        "$(execpath //main/cppu:cppu3_implib)",
+        "/MANIFEST:NO",
+    ],
+)
+
+# inter.exe — the driver; loads the two DLLs and invokes the throw/catch path.
+cc_binary(
+    name = "test_inter",
+    srcs = [
+        "test/inter_libs_exc/inter.cxx",
+        "test/inter_libs_exc/share.h",
+    ],
+    copts = _TEST_COPTS,
+    defines = _DEFINES,
+    testonly = True,
+    deps = [
+        "//main/sal:sal_headers",
+        "//main/cppu:cppu_headers",
+        "//main/udkapi:udkapi_idl_headers",
+    ],
+    additional_linker_inputs = ["//main/sal:sal_implib"],
+    linkopts = [
+        "$(execpath //main/sal:sal_implib)",
+        "/MANIFEST:NO",
+    ],
+)
+
+# Stage inter.exe + starter.dll + thrower.dll + sal3/cppu3 + CRT into one dir 
and
+# run it; passes iff it exits 0 (exception caught, no crash).
+staged_run_test(
+    name = "inter_libs_exc_test",
+    binary = ":test_inter",
+    runtime = [
+        ":starter",
+        ":thrower",
+        "//main/sal:sal3",
+        "//main/cppu:cppu3",
+    ],
+)
diff --git a/main/bridges/readme.md b/main/bridges/readme.md
index 949528d215..2510c902a4 100644
--- a/main/bridges/readme.md
+++ b/main/bridges/readme.md
@@ -1,5 +1,7 @@
 # Notes for bridges (done)
 
+## cpp_uno (C++↔UNO bridge) → `msci_uno.dll`
+
 - DLL name: `msci_uno` (from COMNAME=msci on WNT-INTEL-msci)
 - jurt/jvmaccess are Java bridge deps — skipped (not needed for C++ bridge)
 - Sources: `source/cpp_uno/shared/*.cxx` + 
`source/cpp_uno/msvc_win32_intel/*.cxx`
@@ -11,3 +13,75 @@
   — no RTTI symbols (bridge_exports.map symbols are GCC-mangled, don't apply 
to MSVC)
 - Links: cppu3.if.lib + sal.if.lib only (matches SHL1STDLIBS in makefile.mk)
 - VS2008 native STL provides `<hash_map>` without stlport (harmless warning 
only)
+
+## jni_uno (Java↔UNO bridge) → `java_uno.dll` + `java_uno.jar`
+
+The java_uno bridge is what makes Java UNO components talk to the C++ runtime.
+Two cooperating artifacts, linked only at runtime (jurt's `NativeThreadPool`
+calls `System.loadLibrary("java_uno")`), so there is no build-time cycle.
+
+- **`//main/bridges:java_uno` → `java_uno.dll`** — native JNI bridge.
+  Staged into `program/` via `//main/staging` (`collect_outputs`).
+  - 6 SLOFILES: `jni_info`, `jni_data`, `jni_uno2java`, `jni_java2uno`,
+    `jni_bridge`, `nativethreadpool` (from `makefile.mk` SLOFILES).
+  - Links (SHL1STDLIBS): jvmaccess + cppu3 + sal + salhelper implibs.
+  - `jni.h` via `@rules_java//toolchains:jni`; 
`precompiled_bridges_java_uno.hxx`
+    resolved by `/Imain/bridges/inc/pch`.
+  - **Three build landmines** (none hit by the sibling `msci_uno`, which 
doesn't
+    touch Java/JNI):
+    1. **`SOLAR_JAVA` define is mandatory.** `jvmaccess/virtualmachine.hxx` 
gates
+       `#include <jni.h>` behind `#ifdef SOLAR_JAVA`; in the `#else` it emits 
STUB
+       typedefs (`jint=int`, `jobject=void*`). Without the define those stubs 
clash
+       with the real jni.h these sources include → `jint/JNIEnv/JavaVM`
+       "redefinition; different basic types". (Also why 
`jvmaccess`/`javaunohelper`
+       set `SOLAR_JAVA`.)
+    2. **`/Zc:wchar_t-`** — `jni_info.h`/`jni_bridge.cxx` pass `sal_Unicode*` 
to JNI
+       `jchar*` params (e.g. `GetStringRegion`). `jchar` is `unsigned short`; 
native
+       `wchar_t` makes `sal_Unicode` a distinct type → C2664. The flag makes
+       `wchar_t == unsigned short == sal_Unicode == jchar`.
+    3. **stlport** — `jni_info.h` uses `::std::hash_map`, which only lives in 
`std::`
+       under stlport (VS2008 native is `stdext::hash_map`).
+  - **`salhelper_headers`** must be an explicit dep: `jvmaccess_headers` 
doesn't
+    propagate it even though `unovirtualmachine.hxx` includes
+    `salhelper/simplereferenceobject.hxx` (same workaround as `jvmaccess3MSC`).
+  - **Exports** (`util/java_uno.def`, converted from `java_uno.map`): the 3 UNO
+    C entry points (`uno_initEnvironment`, `uno_ext_getMapping`,
+    `component_canUnload`) **plus** the JNI natives. JNICALL is `__stdcall` on
+    Win32, so the linker would decorate `Java_*` as `_Java_...@N`, which the 
JVM
+    cannot resolve — the DEF lists the undecorated names (same trick as jurt's
+    `jpipe.def`). The `_1` in names like
+    `..._JNI_1proxy_dispatch_1call` is JNI's encoding of `_` in the
+    `com.sun.star.bridges.jni_uno` package / `JNI_proxy` class.
+- **`//main/bridges:java_uno_jar` → `java_uno.jar`** — the Java side:
+  `JNI_proxy` + `JNI_info_holder`. Deps: jurt (`AsynchronousFinalizer`,
+  `NativeLibraryLoader`) + ridl (`com.sun.star.uno.*`); `--release 8`.
+  Sealed manifest is a staging concern, not handled here.
+
+## Tests (`bridges/test/`)
+
+| Test | Kind | Bazel status |
+|------|------|--------------|
+| `inter_libs_exc` | single C++ process | ✅ 
`//main/bridges:inter_libs_exc_test` — runs & passes |
+| `java_uno/any`, `…/equals`, `…/nativethreadpool` | 2-process socket URP 
bridge (native `uno` ↔ java) | ⬜ deferred — multi-process orchestration fixture 
|
+| `java_uno/acquire` | same + `OOoRunner.jar` | ⬜ blocked on qadevOOo |
+| `com/sun/star/lib/uno/bridges/java_remote/*` | pure-Java JUnit-via-OOoRunner 
| ⬜ blocked on qadevOOo |
+| `performance` | UNO perf harness | ⬜ deferred (needs running UNO env) |
+| `testserver`/`testclient`/`testcomp`/`testsameprocess` | legacy CORBA-era 
(`com.sun.star.corba.giop`) | ⬜ likely obsolete |
+
+- **`inter_libs_exc_test`** — proves a 
`com.sun.star.lang.IllegalArgumentException`
+  thrown in `thrower.dll` is caught across the shared-library boundary in
+  `starter.dll` (an MSVC RTTI/ABI check).  `inter.exe` loads both via
+  `osl::Module("thrower"/"starter")`, so the cc_binary target names MUST be the
+  bare `thrower`/`starter` (the dll basenames it hard-codes).  Run via the 
generic
+  `staged_run_test` (the non-gtest form of `gtest_test`'s staging rule): 
inter.exe
+  + both dlls + sal3/cppu3 + VC90 CRT are staged into one dir; the test passes 
iff
+  the exe exits 0.  No UNO connection, no Java — the only test here that runs
+  without a qadevOOo / running-soffice fixture.
+- **Why the rest are deferred**: the `java_uno/*` tests were *manual* harnesses
+  upstream (each `readme.txt`: "run `…-server &`, sleep 3, run `…-client`") — 
the
+  makefile only builds the components + emits run-scripts.  The native `uno`
+  runner exists (`//main/cpputools:uno`), but automating them under `bazel 
test`
+  needs a 2-process socket fixture (port allocation, server-ready wait).
+  `acquire` + `java_remote` additionally need `OOoRunner.jar` from 
**qadevOOo**,
+  which is not migrated (frontier).  These belong with the deferred
+  OfficeConnection/subsequent-test bucket.
diff --git a/main/bridges/test/inter_libs_exc/starter.def 
b/main/bridges/test/inter_libs_exc/starter.def
new file mode 100644
index 0000000000..2382b2ebde
--- /dev/null
+++ b/main/bridges/test/inter_libs_exc/starter.def
@@ -0,0 +1,3 @@
+LIBRARY starter
+EXPORTS
+    start
diff --git a/main/bridges/test/inter_libs_exc/thrower.def 
b/main/bridges/test/inter_libs_exc/thrower.def
new file mode 100644
index 0000000000..f70d40eef7
--- /dev/null
+++ b/main/bridges/test/inter_libs_exc/thrower.def
@@ -0,0 +1,3 @@
+LIBRARY thrower
+EXPORTS
+    get_thrower
diff --git a/main/bridges/util/java_uno.def b/main/bridges/util/java_uno.def
new file mode 100644
index 0000000000..0996b9b0b6
--- /dev/null
+++ b/main/bridges/util/java_uno.def
@@ -0,0 +1,16 @@
+LIBRARY java_uno
+EXPORTS
+    uno_initEnvironment
+    uno_ext_getMapping
+    component_canUnload
+    Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J
+    Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call
+    Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J
+    Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_attach
+    Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_create
+    Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_destroy
+    Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_detach
+    Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_dispose
+    Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_enter
+    Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_threadId
+    Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_putJob
diff --git a/main/staging/BUILD.bazel b/main/staging/BUILD.bazel
index e7f2c1d6c8..5cd65a96bd 100644
--- a/main/staging/BUILD.bazel
+++ b/main/staging/BUILD.bazel
@@ -72,6 +72,11 @@ collect_outputs(
         "//main/stoc:proxyfac.uno",
         "//main/binaryurp:binaryurp",
         "//main/bridges:msci_uno",
+        # Native JNI bridge (java_uno.dll). Loaded by jurt's NativeThreadPool 
via
+        # System.loadLibrary("java_uno") once Java is enabled. The Java side
+        # (java_uno.jar) needs the program/classes/ classpath staging, which 
does
+        # not exist yet — see readme.md "jni_uno" notes.
+        "//main/bridges:java_uno",
         "//main/io:streams",
         "//main/io:acceptor",
         "//main/io:connector",

Reply via email to