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",
