A method and device for declarative interoperability for multi-lingual modular application system

CN123011370APending Publication Date: 2026-10-30卜昕宇
View PDF 0 Cites 0 Cited by

Patent Information

Application Number
CN202611201809.X
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2026-08-10
Publication Date
2026-10-30

AI Technical Summary

Technical Problem

[0009]本申请的目的在于提供一种面向多语言模块化应用系统的声明式互操作方法及装置,以解决现有多语言模块化系统中模块间互操作耦合度高、交互模式单一、跨语言支持不充分及生命周期管理不完整的问题

Benefits of technology

第一,提供了Hook(拦截处理)、Slot(贡献组装)和Pipeline(链式处理)三种互补的互操作模式,覆盖了模块间"调用者主导"、"框架主导"和"管道定义者主导"的全部协作场景,解决了现有技术仅支持单一交互模式的局限。

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN123011370A_ABST
    Figure CN123011370A_ABST
Patent Text Reader

Abstract

The application discloses a kind of declarative interoperability method and device for multi-language modular application system, belong to computer software architecture technical field.The method includes: three kinds of extension point declaration of hook, slot and flow pipeline are parsed in module manifest file when module is loaded, and registration;Hook scheduling executes in descending order of priority, and continue or terminate is decided according to return result and blocking indication;Slot collection merges result set in ascending order of priority;Pipeline construction arranges complete execution chain according to insertion instruction;Module unloading automatically traverses each registration center and clears interoperability record.The device includes module manifest analysis module, three registration centers and life cycle cleaning module.The application supports double-track registration, cross-language interoperability and life cycle binding automatic cleaning, solves the problem of high interoperability coupling and single interaction mode in multi-language modular system.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This application relates to the field of computer software architecture technology, specifically to a declarative interoperability method and apparatus for multilingual modular application systems, applicable to inter-module communication and collaboration in enterprise-level modular platforms. Background Technology

[0002] As enterprise applications continue to grow in scale and complexity, modular architecture has become the mainstream software design paradigm. In a typical modular application system, the system is broken down into multiple functionally independent modules, each implemented by different development teams using different programming languages, and their lifecycles are managed uniformly through a platform. In such multi-language modular systems, interoperability between modules is a core challenge.

[0003] In existing technologies, inter-module interoperability mainly adopts the following schemes: (1) Direct dependency scheme: Modules establish direct dependencies through class references (import) or object injection mechanisms. The drawback of this scheme is that it creates strong coupling between modules, makes independent deployment and upgrade of modules difficult, and makes it impossible to establish dependencies between cross-language modules through class references.

[0004] (2) Event Bus Scheme: Modules communicate loosely using a publish-subscribe pattern. Publishers send events to the bus, and subscribers receive events from the bus. The drawback of this scheme is that the event bus only supports the publisher-led notification pattern—that is, after an event occurs, interested subscribers are notified to handle it themselves. It cannot support the caller-led interception pattern (allowing other modules to perform additional processing before the operation is executed) or the framework-led assembly pattern (allowing other modules to provide content to fill in predefined positions). The interaction direction is singular and cannot meet the needs of complex module collaboration scenarios.

[0005] (3) Plugin architecture scheme: Define fixed extension point interfaces, and plugins extend the functionality of the host application by implementing the interfaces. The drawbacks of this scheme are: the extension point definition is usually hard-coded at compile time and is difficult to change dynamically at runtime; plugins implemented in different programming languages ​​need to uniformly follow the interface constraints, and cross-language implementation is complex; the life cycle of the extension point is not tightly bound to the plugin, and hanging references may remain after the plugin is uninstalled, leading to runtime errors.

[0006] (4) Inter-process communication scheme: Each module runs as an independent process and interoperates through communication protocols such as Hypertext Transfer Protocol (HTTP), Remote Procedure Call Protocol (gRPC), and message queues. The drawbacks of this scheme are: the communication overhead is large, which is not suitable for interactive scenarios that are sensitive to response time; each module needs to implement its own communication layer, which increases the complexity of development and operation and maintenance; and it is not possible to perform fine-grained process interception and content assembly for modules running in the same process.

[0007] In summary, existing technologies for achieving inter-module interoperability in multilingual modular systems suffer from problems such as high coupling, limited interaction modes, insufficient cross-language support, and incomplete lifecycle management.

[0008] In modular application systems, the complete lifecycle management of modules typically involves three levels of technical issues: module loading and scheduling, interoperability and collaboration between modules, and disassembly and recovery of module data assets. In the prior art, each of these three levels—module loading and scheduling, interoperability between modules, and disassembly and recovery—has its own independent technical solutions, but a complete technical solution that organically integrates them into a unified lifecycle management closed loop has not yet been found. This application focuses on the interoperability and collaboration between modules, providing a declarative, cross-language interoperability method and apparatus that supports multiple interaction modes. The above statements are only used to provide background information related to this application and do not necessarily constitute prior art. Summary of the Invention

[0009] The purpose of this application is to provide a declarative interoperability method and apparatus for multilingual modular application systems, so as to solve the problems of high interoperability coupling between modules, single interaction mode, insufficient cross-language support and incomplete lifecycle management in existing multilingual modular systems.

[0010] The core innovation of this application lies in providing a "three-mode coexistence" inter-module interoperability device, including three parallel registry centers—HookRegistry, SlotRegistry, and PipelineRegistry—and a cross-cutting lifecycle cleanup unit. The three registry centers are associated with each module through a unified module identifier (moduleKey), and the lifecycle cleanup unit operates on each of the three registry centers sequentially when a module is unloaded. The scheduling logic of the three registry centers differs: Hooks are executed in descending priority order and support interception; Slots are merged in ascending priority order; and Pipelines are constructed according to the insertBefore priority rule. These three modes are not simply a patchwork of existing technologies, but rather work collaboratively under a unified InteropTypes type system, a unified moduleKey association index, and a unified lifecycle cleanup mechanism. This enables inter-module interoperability to cover all three types of collaborative scenarios: "caller-driven" (Hook), "framework-driven" (Slot), and "pipeline-driven" (Pipeline). While each mode is architecturally independent, they are highly coupled in lifecycle management, forming an organic interoperability whole. No existing technology has yet found a solution that integrates these three modes into a single system.

[0011] To achieve the above objectives, this application adopts the following technical solution: Firstly, this application provides a declarative interoperability method for multilingual modular application systems, comprising: Step S1, when a module is loaded, scanning the module manifest file (module.json) of the module, parsing the declarations of three types of extension points—hooks, slots, and pipelines—and registering them to the corresponding registry center; Step S2, responding to hook scheduling requests, obtaining all hook processors from the hook registry center, executing them in descending order of priority, with each processor returning one of three results: Pass, Continue, or Intercept; where Pass indicates that the current processor actively confirms the pass, terminating the execution of subsequent processors and allowing the original operation; Intercept indicates interception, terminating the execution of subsequent processors and blocking the original operation, and includes a blocking indication field; Continue indicates continuing to execute the next processor. When any processor returns Intercept and its blocking indication field indicates blocking subsequent execution, execution is terminated and interception information is returned to the upper layer; Step S3: Respond to the slot collection request, obtain all content contributing modules from the slot registry, sort them in ascending order of priority, and merge them into a unified result set for return; Step S4: Respond to the pipeline construction request, obtain the basic stage sequence and extended stage sequence from the process pipeline registry, and insert the extended stage into the basic stage sequence according to the insertAfter / insertBefore instructions, with insertBefore taking precedence over insertAfter; Step S5: When the target module is unloaded or deactivated, automatically traverse each registry and clear all interoperability registration records of the module to ensure that no dangling references remain.

[0012] Furthermore, the hook registry maintains a priority-sorted list of processors using the hook name as the key; during scheduling, the processing functions are called sequentially in descending order of priority until all are completed or an Intercept is encountered; the higher the priority integer value, the higher the priority, with a default of 100; when multiple processors have the same priority, they are executed in the order of their registration time, with the processor that was registered earlier being executed first.

[0013] Furthermore, the slot registry maintains a list of contribution entries using the slot name as the key; during collection, they are sorted in ascending order of priority, with lower priority values ​​appearing earlier, and the contributions from each module are merged into a unified result set for return; when multiple entries have the same priority, they are sorted in order of registration time, with the content of the module registered earlier appearing first.

[0014] Furthermore, the process pipeline consists of a basic stage sequence and an extended stage sequence. When constructing the pipeline, the basic stage is first expanded, and then the extended stage is inserted according to the insertAfter / insertBefore instructions of the extended stage. When the same extended stage specifies both insertAfter and insertBefore and the target pointed to by insertBefore exists in the basic stage sequence, the insertBefore instruction takes effect and the insertAfter instruction is ignored. The above priority rule only applies to the case where the same extended stage specifies both, and the insertion instructions between different extended stages do not overlap.

[0015] Furthermore, the module manifest file (module.json) declares extension points in top-level fields using JavaScript Object Notation (JSON) format. The hooks field contains arrays of provides and consumes, the slots field contains arrays of provides and consumes, and the pipelines field contains an array of provides. Modules establish interoperability relationships through declarations in the module manifest file, rather than through direct code dependencies between modules.

[0016] Furthermore, the module manifest file (module.json) follows the following JSON Schema definition: The top-level object contains the required fields key (string, unique identifier of the module), name (string, module name), version (string, semantic version number), and language (string, programming language type, which can be one of Kotlin / Java / Groovy / Python / C); extension point declarations are located under the three optional fields hooks, slots, and pipelines at the top level. If not declared, they will not participate in the interoperability of the corresponding mode. The `hooks` field is an object that can contain a `provides` field (an array of strings declaring the names of hooks provided by this module, each element being a fully qualified hook name prefixed with "hook:") and a `consumes` field (an array of objects, each element containing a `hook` field (a string, the name of the hook to be consumed), a `priority` field (an integer, the priority), and a `handler` field (a string, the reference path of the handler function in the module code, using a dot-separated chained path format, such as "com.example.handler.MyHookHandler"; the platform resolves this path and calls the corresponding function during scheduling using the programming language corresponding to the module; for non-JVM modules, the `handler` field is only used as a declaration identifier, and the actual call address is determined by the `callbackUrl` provided during imperative registration)). The `slots` field is an object that can contain a `provides` field (an array of strings declaring the names of slots provided by this module) and a `consumes` field (an array of objects, each element containing a `slot` field (a string, the name of the slot to be consumed), a `priority` field (an integer, the priority), and a `content` field (an object containing the front-end resource path and display metadata)). The `pipelines` field is an object containing an `provides` field (an array of objects, each element containing a `pipelineName` field (a string representing the pipeline name) and an `stages` field (an array of objects, each containing an `id` and a `handler` field)). This schema definition allows the platform to perform structured validation on `module.json` during module loading, ensuring the completeness and consistency of extension point declarations.

[0017] Furthermore, the registry manages providers and consumers separately: the `provides` field of `modules` declares the extension points provided by this module, and the `consumes` field declares the extension points consumed by this module from other modules. The registry allows consumers to register before the corresponding provider has registered; in this case, the consumer's processor entry is marked as "pending activation" and stored in the registry. When the corresponding provider subsequently completes registration, the registry automatically converts the consumer entry to an "activated" state, ensuring that the module loading order does not affect the final establishment of interoperability. If, when a module is unloaded, the extension points it consumes are still provided by other modules, the cleanup unit only removes the module's own entry; the data integrity of other modules within the registry remains unaffected.

[0018] Furthermore, modules support both declarative and imperative registration methods: declarative registration is statically declared through the `provides / consumes` field of `module.json`; imperative registration is achieved by calling the registration method at runtime through the plugin interface object. Entries registered in both methods are managed uniformly in the registry center and distinguished by the registration method. During registration, the uniqueness is determined by "module identifier (moduleKey) + extension point name (hook name, slot name, or pipe name)". When declarative and imperative registrations conflict within the same module and for the same extension point name, the imperative registration entry will override the declarative registration entry. "Override" means that the registry center deletes the declarative entry for that module under the target extension point name and replaces it with the imperative registration entry. All attributes of the imperative entry (including priority and processing functions) replace the corresponding attributes of the declarative entry, and the declarative entry is no longer retained to ensure the priority of runtime dynamic behavior.

[0019] Furthermore, the registry center uses a unified InteropTypes definition as the cross-language data exchange format. The complete field definitions of the three data structures are as follows: (1) The HookResult type includes a type field (enumeration, with values ​​of Pass, Continue, or Intercept), a reason field (string, optional, describing the reason for interception when type is Intercept), a source field (string, optional, describing the source path of the Pass result, with values ​​of NO_HANDLER / HANDLER_PASS / CHAIN_COMPLETED), and an interrupt field (boolean value, indicating whether to block subsequent execution, only valid when type is Intercept, with a default value of true). (2) The SlotContent type includes a priority field (integer, priority), a content field (object, containing a path field (string, front-end resource access path), a meta field (object, rendering metadata), and a title field (string, display title)) and a moduleKey field (string, contributing module identifier). (3) The PipelineStage type includes an id field (string, unique identifier of the stage), a handler field (string, processor reference path), an insertAfter field (string, optional, identifier of the target stage to be inserted after the target stage), and an insertBefore field (string, optional, identifier of the target stage to be inserted after the target stage). The above three data structures support interoperability between modules of multiple programming languages ​​such as Kotlin, Java, Groovy, Python, and C through a unified serialization / deserialization mechanism; the interoperability between modules is carried out through the standard interface of the registry center (register / dispatch / collect / build / unregisterByModule) and the unified InteropTypes data structure for data exchange. The programming language implementation details of each module are encapsulated inside the module, and the module only exposes extension points and interoperability behaviors to the outside world through the module manifest file and the registry center interface. Specifically, for JVM modules (Kotlin / Java / Groovy), the handler field of declarative registration is resolved and functions are called by the runtime of the corresponding programming language of the module; for non-JVM modules (Python / C), imperative registration must be used to call back through the callbackUrl of InteropAgent. In this case, the handler field in module.json is only used as a declaration identifier, and the actual scheduling is based on the callbackUrl provided during imperative registration.Inter-module interoperability does not rely on runtime dynamic class loading or reflection invocation, unlike the way modules in traditional modular systems such as OSGi often interact through standard Java interfaces and dynamic class loading mechanisms.

[0020] Secondly, this application provides a declarative interoperability device for multilingual modular application systems, comprising: a module manifest parsing unit for scanning module.json and parsing extension point declarations; a hook registry unit for managing hook processors and performing priority descending scheduling; a slot registry unit for managing content contribution entries and performing priority ascending merging; a pipeline registry unit for managing pipeline definition and extension stages and performing insertBefore-first construction algorithms; and a lifecycle cleanup unit for automatically traversing each registry and clearing interoperability registration records when a module is unloaded.

[0021] Compared with the prior art, the embodiments of this application have the following beneficial effects: First, it provides three complementary interoperability modes: Hook (interception processing), Slot (contribution assembly), and Pipeline (chain processing), covering all collaboration scenarios between modules, including "caller-led", "framework-led", and "pipeline-defined-led", thus solving the limitation of existing technologies that only support a single interaction mode.

[0022] Second, through unified InteropTypes type definitions and module manifest file declarations, the interoperability relationship is completely decoupled from the specific programming language, supporting interoperability between modules of multiple programming languages, and there is no direct language-level dependency between modules.

[0023] Third, a complete binding mechanism between interoperability and module lifecycle has been established: all extension entries registered by a module are associated with the module identifier (moduleKey), and when a module is uninstalled, all registry centers are automatically traversed for batch cleanup, eliminating the risk of runtime errors caused by dangling references.

[0024] Fourth, it supports both declarative and imperative registration methods in parallel, balancing the simplicity of configuration during development with the flexibility of dynamic expansion at runtime.

[0025] Fifth, a priority interception chain is introduced into the Hook mechanism, where the intercept result of a high-priority module can block the execution of a low-priority module, supporting third-party repair modules to cover the defective behavior of the basic module. A conflict resolution rule is introduced into the Pipeline mechanism, prioritizing insertBefore over insertAfter, to ensure the determinism of pipeline construction. Attached Figure Description

[0026] Figure 1 A schematic diagram of the overall architecture of the declarative interoperability device provided in the embodiments of this application.

[0027] Figure 2 The scheduling flowchart for the hook interception mode (Hook) provided in the embodiments of this application is shown.

[0028] Figure 3 A flowchart illustrating the collection process of slot contribution assembly patterns provided in this application embodiment.

[0029] Figure 4 A flowchart illustrating the construction process of the pipeline pattern provided in this application embodiment.

[0030] Figure 5 This is a schematic diagram of the cross-language module interoperability and lifecycle cleanup architecture provided for embodiments of this application. Detailed Implementation

[0031] To make the objectives, technical solutions, and advantages of this application clearer, the application will now be described in further detail with reference to the accompanying drawings.

[0032] It should be noted that, in the embodiments of this application, the term "module" refers to an independent business functional unit organized in the form of a folder. Each module contains a module description file (module.json), a backend code directory (backend / ), and an optional frontend code directory. The module description file declares the module's unique identifier (key), name, version, programming language type, and extension point declaration information.

[0033] In the context of this application, "module loading" refers to the platform scanning the module.json file in the module directory during startup or runtime, reading module metadata, and incorporating the module into the management scope of the module manager. This process includes parsing the extension point declarations in the module manifest file and completing the registration operations of various registries. "Module unloading" refers to the platform removing the target module from the management scope of the module manager. This process includes calling the unregisterByModule method of each registry to clear all interop registration records of the module, releasing system resources occupied by the module (such as the Groovy class loader or Maven dependency isolation class loader), and completing the state transition from ACTIVE to INACTIVE to CLEARED in the module state machine. In the RESTORABLE state, the module's interop registration records are still retained in the registry but marked as invalid. When the module is restored to the ACTIVE state, the above registration records are reactivated; in the CLEARED state, the registration records are physically deleted. Both of the above cleanup strategies fall within the scope of the lifecycle cleanup mechanism of this application.

[0034] Example 1: Hook Interception Mode This embodiment takes hook interception in the user authentication process as an example, combined with... Figure 2 This section explains the working principle of the HookRegistry. In the modular platform of this application embodiment, the core user authentication module (user-center) calls the login pre-hook (hook:user.login.before) during the user login process, allowing other modules to intercept or enhance the login operation before execution. An example of the declarative configuration of hooks in the module manifest file (module.json) is as follows: "hooks": {"provides": ["user.login.before", "user.logout"]}, "hooks": {"consumes": [{"hook": "user.login.before", "priority": 200, "handler": "com.example.handler.LoginInterceptor"}]}.

[0035] The core data structures of the Hook Registry class include: hookMap—a mapping table with hook names as keys and a list of handler entries sorted by priority as values; and moduleHookKeys—a mapping table with module identifiers as keys and a set of hook names registered by that module as values, used for batch cleanup during module uninstallation. Each handler entry (HookEntry) contains three fields: moduleKey (module identifier string), priority (priority integer value, default 100, higher values ​​indicate higher priority), and handler (processor function, which receives a context Map and returns a HookResult object).

[0036] The `HookResult` type definition includes three values: `HookResult.Pass()` indicates that the current processor actively indicates pass, immediately terminating the execution of the hook chain. This means the current processor has completed verification and determined that no further checks on subsequent processors are needed. The original operation triggered by the hook continues execution, and subsequent processors no longer execute. In this case, the `source` field of `HookResult` is "HANDLER_PASS". `HookResult.Continue()` indicates that the current processor has completed execution and has not made a pass / fail judgment, continuing to execute the next processor in the hook chain. `HookResult.Intercept(reason)` indicates interception, immediately terminating the hook chain and the original operation, and returning the interception reason. Furthermore, when the hook scheduling method is called without any processor registered, it directly returns a `Pass` result with the `source="NO_HANDLER"` flag, indicating that the hook has not been consumed by any module and can pass without processing. When all processors in the chain return `Continue`, it finally returns a `Pass` result with the `source="CHAIN_COMPLETED"` flag, indicating that none of the processors intercepted or actively passed, and the entire chain is considered passed. The aforementioned source field has no impact on the hook scheduling logic itself; it is only used by the upper-level caller for logging or behavior auditing.

[0037] The execution flow of the hook scheduling method dispatch(hookName, context) is as follows: (1) Get the list of processor entries from hookMap with hookName as the key. If the list is empty, return the Pass result with the source identifier "NO_HANDLER" directly, indicating that the hook has not been consumed by any module and can pass without processing; (2) Sort the list of processor entries in descending order of priority to ensure that the processors of high-priority modules are executed first; if multiple entries have the same priority, arrange them in order of registration time, and the ones registered first are executed first; (3) Call the processing function (handler) of each processor in the sorted order, passing in the context; (4) Check the return value of each call: if it returns Intercept and its interrupt indicator field (interrupt) indicates that subsequent execution is blocked (the default value is true), immediately terminate the loop and Return the Intercept result and the reason for interception to the upper-level caller. The original operation that triggered the hook is blocked. If Intercept is returned but the interruption field (interrupt) indicates that subsequent execution is not blocked, only the interception information is recorded and the subsequent processor continues to be executed. If Pass is returned, the loop is terminated immediately and a Pass result with the source identifier "HANDLER_PASS" is returned to the upper-level caller. This indicates that a certain processor actively confirms that it has passed. The original operation of the hook continues to be executed and the subsequent processors are no longer executed. If Continue is returned, the next processor is processed. (5) If all processors return Continue, a Pass result with the source identifier "CHAIN_COMPLETED" is finally returned. This indicates that none of the processors in the hook chain have been intercepted or actively passed. The whole chain is considered to have passed.

[0038] The aforementioned priority mechanism supports typical application scenarios for third-party remediation modules: a third-party security enhancement module registers with a high priority (e.g., priority=999) to the user.login.before hook. When a login request from a blacklisted IP is detected, it returns Intercept, thus achieving login interception without modifying any code in the user-center module. When multiple modules register with the same priority to the same hook, they are executed in the order of registration. For example, if both the security audit module and the security enhancement module register with the default priority of 100, the module that registers first will execute first.

[0039] Example 2: Slot Contribution Assembly Mode This embodiment takes the slot assembly of the management backend dashboard page as an example, combined with... Figure 3This section explains the working principle of the Slot Registry. In the management backend of this embodiment, the dashboard page defines a slot area named "dashboard.widgets," to which each business module can contribute its own data statistics card components. An example of a declarative configuration for a slot in the module manifest file is as follows: "slots": {"provides": ["dashboard.widgets"]}, "slots": {"consumes": [{"slot": "dashboard.widgets", "content": {"title": "Sales Statistics", "path": "sales-widget.js"}, "priority":50}]}.

[0040] The core data structures of the Slot Registry class include: slotMap—a mapping table with slot names as keys and a list of content contribution entries as values; and moduleSlotKeys—a mapping table with module identifiers as keys and a set of slot names registered by that module as values. Each content contribution entry (SlotEntry) contains three fields: moduleKey, priority, and content. Content can include the access path of the front-end resource, rendering metadata, and display title.

[0041] The execution flow of the slot collection method collect(slotName) is as follows: (1) Get the list of content contribution items from slotMap with slotName as the key. If the list is empty, return an empty list; (2) Sort the list of content contribution items in ascending order of priority, with smaller values ​​first. If multiple items have the same priority, they are sorted in order of registration time; (3) Extract the content field of each item in turn and merge them into an ordered result list and return it. For example, when the three modules sales-module (priority=50), inventory-module (priority=60) and order-module (priority=40) all contribute content to the "dashboard.widgets" slot, the collect method returns a result list sorted in ascending order of priority. The front-end rendering engine renders the data statistics cards of each module in the corresponding area of ​​the dashboard in this order.

[0042] Example 3: Pipeline Pattern This embodiment takes the order processing flow as an example, combined with Figure 4This section explains the working principle of the Pipeline Registry. In the modular platform of this application embodiment, the order module (order-service) defines an order processing pipeline named "order.pipeline," which includes three basic stages: A (order verification), B (inventory deduction), and C (notification sending). Other modules can insert custom processing stages at specific locations in the pipeline through extended declarations.

[0043] The core data structures of the PipelineRegistry class include: pipelines—a mapping table with pipeline names as keys and a list of basic stages as values; extensions—a mapping table with pipeline names as keys and a list of extended stage entries as values; and moduleExtensionKeys—a mapping table with module identifiers as keys and a set of pipeline names for which the module has registered extensions as values.

[0044] The `define(pipelineName, stages)` method defines a pipeline and accepts the pipeline name and a sequence of base stages. Each base stage contains an `id` (a stage identifier string) and a `handler` (a processing function). The `insert(pipelineName, moduleKey, stage)` method inserts an extended stage and accepts the pipeline name, module identifier, and an extended stage object. The extended stage object contains an `id`, a `handler`, `insertAfter` (optional, the identifier of the target stage to be inserted before, indicating that the current stage will be inserted after the target stage), and `insertBefore` (optional, the identifier of the target stage to be inserted after, indicating that the current stage will be inserted before the target stage).

[0045] The execution flow of the pipeline construction method build(pipelineName) is as follows: (1) Get the basic stage sequence definition from pipelines. If the pipeline is not defined, throw an exception; (2) Get the list of extended stage entries from extensions. If the list is empty, return the basic stage sequence directly; (3) Collect the basic stage identifiers into a set baseIds; (4) Build the beforeMap (grouped by insertBefore) and afterMap (grouped by insertAfter) respectively. When building afterMap, filter out entries whose insertBefore field points to valid basic stage identifiers to ensure that insertBefore takes precedence over insertAfter; (5) Traverse each basic stage: first check whether there is an extended stage with the current stage as the insertBefore target in beforeMap and insert it, then add the current basic stage to the construction list, and finally check whether there is an extended stage with the current stage as the insertAfter target in afterMap and insert it; (6) Append the remaining extended stages that have not been inserted to the end and return the merged complete stage sequence.

[0046] Here's a concrete example: The base phases are [A, B, C]. Module X registers extension phase X1 (insertAfter="A"), module Y registers extension phase Y1 (insertBefore="B"), and module Z registers extension phase Z1 (specifying both insertAfter="A" and insertBefore="B"). According to the insertBefore priority rule, although Z1 also specifies insertAfter="A", its insertBefore="B" instruction is prioritized because it points to a valid base phase identifier. Z1's insertAfter instruction is ignored, and Z1 therefore only appears in the beforeMap. The final build result is [A, X1, Z1, Y1, B, C], where after A are X1 matched by afterMap, Z1 and Y1 matched by beforeMap, and then the base phases B and C. This result demonstrates the role of the insertBefore priority rule in resolving conflicts and ensuring deterministic pipeline construction.

[0047] Example 4: Lifecycle Binding and Automatic Cleanup This embodiment takes the module uninstallation operation as an example, combined with Figure 5 Explain the working principle of lifecycle binding and automatic cleanup mechanism.

[0048] When an administrator triggers a module uninstallation operation through the management backend or API interface, the platform's module state machine sequentially transitions the target module from the enabled state to the disabled state. During the state transition process, the platform performs interoperability record cleanup according to the state machine rules: when a module is in the disabled (INACTIVE) or restoreable (RESTORABLE) state, its interoperability registration record is retained in the registry center but marked as invalid; when a module enters the cleared (CLEARED) state, the unregisterByModule(moduleKey) method of each registry center is called to perform physical batch cleanup of interoperability relationships.

[0049] The specific cleanup process is as follows: For the hook registry, iterate through the `moduleHookKeys` mapping table to obtain all hook names registered by the target module. For each hook name, remove all processor entries for that module from the corresponding list in `hookMap`. After completion, delete the module's entry in `moduleHookKeys`. For the slot registry, iterate through the `moduleSlotKeys` mapping table to obtain all slot names registered by the target module. For each slot name, remove all content contribution entries for that module from the corresponding list in `slotMap`. After completion, delete the module's entry in `moduleSlotKeys`. For the pipeline registry, iterate through the `moduleExtensionKeys` mapping table to obtain all pipeline names for which the target module has registered extensions. For each pipeline name, remove all extension stage entries for that module from the corresponding extension list. After completion, clean up the module's entry in `moduleExtensionKeys` and the pipeline entries that become empty. Furthermore, when calling `removePipeline(pipelineName)` to delete the entire pipeline definition, in addition to cleaning up the pipeline entries in `pipelines` and `extensions`, it is also necessary to iterate through the pipeline sets of all modules in `moduleExtensionKeys` and remove references to the deleted pipeline. It's important to note that the cleanup operation distinguishes between two roles of modules in the registry: the provider role—the extension entries (such as hook handlers, slot contents, and pipeline stages) declared by this module through the `provides` field or actively registered via the imperative `register` method; and the consumer role—the content entries declared by this module through the `consumes` field and contributed to the extension points of other modules. Registration entries for both roles are cleared during uninstallation. Through this lifecycle binding mechanism, interoperability relationships after module uninstallation are thoroughly cleaned up, preventing runtime exceptions caused by dangling handler references left by uninstalled modules during subsequent hook scheduling or pipeline construction.

[0050] Example 5: Overall Architecture This embodiment combines Figure 1 This paper explains the composition of the declarative interoperability device provided in the embodiments of this application and the collaborative working mechanism of each component from the perspective of the overall system architecture. Figure 1 The overall process is as follows: When the system starts, the module manifest parsing unit scans the module.json file of each module and registers the parsed extension point declarations (including hooks, slots, and pipelines) to the corresponding three registry centers. Subsequently, when an interoperability request is triggered during system operation, the hook request is scheduled by the hook registry center in descending order of priority and the process continues or terminates based on the return value. The slot request is merged by the slot registry center in ascending order of priority. The pipeline request is constructed by the process pipeline registry center according to the insertBefore priority rule to build a complete stage sequence. Finally, when the target module is unloaded, the lifecycle cleanup unit automatically traverses the three registry centers to perform batch cleanup.

[0051] The device comprises five core units: (1) a module manifest parsing unit, which is responsible for reading and parsing the module.json file of each module when the platform starts and the module is dynamically loaded, extracting the hooks, slots and pipelines extension point declarations and converting them into ModuleManifest data objects in memory, and also has the functions of declaration format verification and duplicate registration deduplication; (2) a hook registration center unit (HookRegistry), a container-level singleton component, which maintains the hookMap and moduleHookKeys data structures, provides register, dispatch and unregisterByModule methods, and implements the priority descending execution chain and Intercept early termination mechanism during the scheduling process; (3) a slot registration center unit (SlotRegistry), a container-level singleton component, which maintains the slotMap and moduleSlotKeys data structures. The eys data structure provides register, collect and unregisterByModule methods, and implements priority ascending sorting and content merging mechanism during the collection process; (4) Pipeline Registry, a container-level singleton component, maintains pipelines, extensions and moduleExtensionKeys data structures, and provides define, insert, build, unregisterByModule and removePipeline methods, and implements the extension stage insertion algorithm based on the insertBefore priority rule during the construction process; (5) Lifecycle Cleanup Unit, integrated in the module state machine, when the module state changes, the unregisterByModule method of each registry center is called in sequence to perform batch cleanup, ensuring the atomicity of state transition.

[0052] The five units work collaboratively: the module manifest parsing unit is responsible for discovering interoperability relationships; the three registry units are responsible for executing interoperability scheduling and managing the state of interoperability relationships; and the lifecycle cleanup unit is responsible for cleaning up interoperability relationships. These five units exchange data through a unified `InteropTypes` definition and use a unified `moduleKey` for association indexing, together forming a complete declarative interoperability mechanism. It is important to emphasize that there is deep technical coupling between the components of this scheme: the descending priority execution of Hooks and the early termination mechanism of Intercepts determine the completeness and predictability of the interoperability behavior of multiple modules; the ascending priority merging mechanism of Slots determines the assembly order of front-end UI components; the `insertBefore` priority rule of Pipelines ensures the deterministic construction of the pipeline; and the lifecycle cleanup mechanism synchronizes module unloading behavior with the state of the three registry units. The three registry units are architecturally independent but work collaboratively through a unified module identifier and lifecycle management mechanism, together forming the declarative interoperability mechanism of this application.

[0053] Example 6: Cross-language module interoperability This example illustrates the implementation mechanism of cross-language extension point consumption using the interoperability between Groovy and Kotlin modules. Assume the system has two modules: Module A is implemented in Groovy, and Module B is implemented in Kotlin. Module B declares the hook "order.payment.process" in its module.json file. Module A declares its consumption of this hook using the `consumes` array and registers its processing function with the hook registry at runtime using Groovy code. Module A's processing function is written in Groovy syntax, but the hook registry does not care about the language origin of the processing function during scheduling; it only receives the return value through a unified `HookResult` type. When the order module triggers the "order.payment.process" hook, the hook registry schedules Module A's processor according to priority. This processor executes the business logic in the form of a Groovy closure and encapsulates the execution result as a `HookResult`, which includes the type (Pass / Continue / Intercept) and a blocking indication field.

[0054] The aforementioned cross-language interoperability does not require establishing any direct language-level dependencies between module A and module B. Groovy closures and Kotlin functions exchange data through a unified InteropTypes type definition. Specifically, InteropTypes defines three data structures: HookResult (containing Pass / Continue / Intercept values), SlotContent (containing priority and content fields), and PipelineStage (containing stage identifier id, handler function, and insertAfter / insertBefore insertion positioning instruction fields). All interoperability data between modules is transmitted through these three data structures, achieving complete transparency between programming languages.

[0055] The cross-language interoperability mechanism of this embodiment is also applicable to modules implemented in other programming languages ​​such as Java, Python, and C. The following uses a Python module as an example to further illustrate the specific implementation of cross-language interoperability: In this embodiment, each non-JVM language module provides a lightweight interop agent (InteropAgent). When a Python module is loaded, its InteropAgent starts a local HTTP service within the module. This service listens on a predefined port (e.g., an idle port number assigned by the platform) and provides standardized REST API endpoints (e.g., / interop / hook / dispatch, / interop / slot / collect, and / interop / pipeline / build). After InteropAgent starts, it sends a registration request to the Java-side registry center via an HTTP POST request. The request body, in JSON format, includes the following fields: moduleKey (module identifier string), registrationType (registration type, which can be hook, slot, or pipeline), registrationName (registration name, such as hook name or slot name), and callbackUrl (callback endpoint URL, in the format http: / / 127.0.0.1:{port} / interop / {type} / dispatch). When a hook dispatch request from the Java side triggers a handler registered by a Python module, the hook registry center sends the context data (containing hookName and key-value context parameters) serialized in JSON format to the callbackUrl provided during the handler's registration via HTTP POST. Upon receiving the request, the Python module's InteropAgent executes the corresponding hook processing logic within the module and returns the processing result in JSON format. The response body includes a resultType field (which can be "Pass", "Continue", or "Intercept") and an optional reason field. After receiving the JSON response, the hook registry deserializes it into a HookResult object and continues processing it according to the hook scheduling logic specified in step S2 of this embodiment.The interoperability implementation of C modules is similar to that of Python modules. The difference is that C modules embed an InteropAgent based on the External Function Interface (FFI). This agent is loaded into the Java process as a dynamic link library (.dll or .so) when the module is loaded. It performs function calls and data exchange with the Java-side registry center through the JNI bridging layer (which defines a unified C function signature, such as JNIEXPORTjstring JNICALL Java_cn_zephyro_HookRegistry_dispatch(JNIEnv*, jobject,jstring, jstring)). The interactive data is also serialized and deserialized using the unified InteropTypes JSON format.

[0056] It should be noted that, to ensure the reliability of cross-language interoperability, this application provides a fault tolerance strategy for non-JVM modules in network anomaly or timeout scenarios. Specifically, when sending an HTTP request to the InteropAgent of a non-JVM module, the registry center sets two time parameters: connection timeout (default 5 seconds) and read timeout (default 30 seconds). When a connection timeout occurs, the registry center determines that the InteropAgent of the target module is unreachable, treats the current hook scheduling request as an unregistered processor for that module, skips the processor, continues execution of subsequent processors in the hook chain, and records an alarm log for administrators to check the module's running status. When a read timeout occurs, the registry center determines that the processor response of the target module has timed out, treats the processor's execution result as Continue (i.e., the processor did not make an interception decision), continues execution of subsequent processors in the hook chain, and records the timeout event in the audit log for administrators to analyze module performance later. When the HTTP request returns a non-200 status code, the registry center also skips the processor and records an error log. In addition, when the InteropAgent of a non-JVM module experiences an unreachable or timeout error a specified number of times (e.g., 3 times), the platform can automatically mark the module as abnormal and issue an alarm notification to avoid the entire hook chain being blocked due to a single point of failure, thus ensuring the availability of the overall system.

[0057] It should be noted that interoperability between modules does not rely on runtime dynamic class loading or reflection invocation. The programming language implementation details of each module are encapsulated within the module itself; modules expose extension points and interoperability behaviors externally only through module manifest files and registry interfaces. Modules exchange data through a unified InteropTypes data structure, without needing to know each other's programming language, class structure, or internal implementation details. Unlike traditional modular systems such as OSGi, where modules often interact through standard Java interfaces and dynamic class loading mechanisms, the method and apparatus of this application achieve complete transparency of programming languages ​​and communication protocols at the interoperability level.

[0058] The embodiments described above are merely illustrative of several implementation methods of this application, and while the descriptions are specific and detailed, they should not be construed as limiting the scope of this patent application. For those skilled in the art, various modifications and improvements can be made without departing from the concept of this application, and these all fall within the protection scope of this application. The protection scope of this patent application shall be determined by the appended claims.

Claims

1. A declarative interoperability method for multilingual modular application systems, characterized in that, include: Step S1: When a module is loaded, scan the module manifest file (module.json) of that module, parse the extension point declarations from the module manifest file, which include hook extension declarations, slot extension declarations, and pipeline extension declarations, and register them to the corresponding registry center; Step S2: In response to a hook scheduling request, retrieve all hook processors corresponding to the target hook name from the hook registry center, sort them in descending order of priority, and execute them sequentially; each hook processor returns one of three interoperability results: Pass, Continue, or Intercept. One of the results is that the interception result includes an indication field indicating whether to block subsequent execution; when any processor returns an interception result and the indication field indicates that subsequent execution is blocked, the execution of the subsequent processor is terminated and the interception information is returned to the upper-layer caller; Step S3: In response to the slot collection request, all content contribution modules corresponding to the target slot name are obtained from the slot registration center, sorted in ascending order of priority and merged into a unified result set, which is returned as the slot filling content; Step S4: In response to the process pipeline construction request, the basic stage sequence and extended stage sequence corresponding to the target pipeline name are obtained from the process pipeline registration center, and the extended stage is inserted into the basic stage sequence according to the insertion positioning instruction (insertAfter or insertBefore) of the extended stage to form a complete pipeline execution chain; when the same extended stage contains both insertAfter and insertBefore instructions, insertBefore takes precedence over insertAfter.

2. The method according to claim 1, characterized in that, Step S2 further includes: the hook registry maintains a mapping table (hookMap) with hook names as keys and a list of processors sorted by priority as values. Each processor entry contains a module identifier (moduleKey), priority, and a handler function. When scheduling a hook, the hook registry receives the hook name and context data as input, retrieves the corresponding processor list, sorts it in descending order of priority, and calls the handler function of each processor in sequence, passing in the context data. Each handler function returns a HookResult object, which contains a type field (Pass, Continue, or Intercept), an indicator field (interrupt) indicating whether to block subsequent execution, and an optional reason field (reason). When any handler function returns of type Intercept and the indicator field indicates blocking subsequent execution, hook scheduling is immediately terminated, subsequent processors are no longer executed, and the Intercept result and its reason are returned to the upper layer. When the return type is Continue, the execution of subsequent processors continues. When the return type is Pass, the execution of the hook chain is immediately terminated, subsequent processors are no longer executed, and the Pass result is returned to the upper layer. When all processors return Continue, the Pass result is finally returned.

3. The method according to claim 2, characterized in that, The priority is an integer value, with a larger value indicating a higher priority. The default priority is 100. When multiple modules register processors for the same hook, the system calls each processing function in descending order of priority, with higher-priority module processors executing before lower-priority module processors. If the processing function of a higher-priority module returns an Intercept result and the indication field indicates that subsequent execution is blocked, the processing function of a lower-priority module will not be executed. This enables the higher-priority module to cover or intercept the behavior of the lower-priority module, supporting scenarios where third-party repair modules cover the defective behavior of the basic module.

4. The method according to claim 1, characterized in that, Step S3 further includes: the slot registry maintains a mapping table (slotMap) with slot name as key and contribution entry list as value. Each contribution entry contains module identifier (moduleKey), priority, and content data. When collecting slots, the slot registry receives the slot name as input, retrieves the corresponding contribution entry list, sorts it in ascending order of priority (the smaller the priority value, the earlier it appears), and merges the contribution content of each module in order into a unified result set and returns it. The content data includes the access path of the module's front-end resources, rendering metadata, and display title, so that UI components contributed by different modules can be assembled into corresponding positions in the same page area.

5. The method according to claim 1, characterized in that, Step S4 further includes: the process pipeline definition consists of basic stages, each with a stage identifier (id) and a processor reference (handler), and the basic stages are executed sequentially in the order they are defined; extended stages are registered by modules through extended declarations, and each extended stage entry includes a module identifier (moduleKey), a stage name (stageName), a handler function (handler), and an insertion positioning instruction, which includes a pre-insert instruction (insertBefore) and a post-insert instruction (insertAfter); when constructing the pipeline, the basic stages are expanded sequentially into an initial list, and then the extended stages are processed one by one: if the basic stage pointed to by the insertBefore of an extended stage exists in the sequence of basic stages, the extended stage is inserted before the basic stage; otherwise, if the basic stage pointed to by insertAfter exists, it is inserted after it; if both insertAfter and insertBefore are specified and the target of insertBefore exists, insertBefore takes precedence and insertAfter is ignored; finally, a merged stage execution chain is formed.

6. The method according to claim 1, characterized in that, The module manifest file (module.json) in step S1 is stored in JSON format. The extension point declaration is located in the top-level fields of the module manifest file, including: the hooks field, which contains an array of provides, declaring the names of hooks provided by this module; and an array of consumes, declaring the names of hooks that this module needs to consume, with the specific processing logic provided by the module at runtime through an imperative registration interface; the slots field, which contains arrays of provides and consumes, declaring the names of slots provided by this module and the names of slots for content contributed by this module, respectively; and the pipelines field, which contains an array of provides, declaring the names of the process pipelines exposed by this module. Interoperability between modules is established through the extension point declarations in the module manifest file, rather than through direct code dependencies between modules.

7. The method according to claim 1, characterized in that, The system also includes step S5: When the target module is uninstalled or deactivated, the system automatically traverses the hook registry, slot registry, and process pipeline registry to clear all extension entries registered as a provider and all content contribution entries registered as a consumer for the target module. The clearing operation is implemented by calling the module identifier uninstallation method (unregisterByModule) of each registry. This method traverses all mapping table entries and removes all records matching the module identifier to ensure that no interoperability-related dangling references remain after the module is uninstalled.

8. A declarative interoperability device for multilingual modular application systems, characterized in that, include: The module manifest parsing module scans the module manifest file (module.json) of each module during module loading, parsing extension point declarations, including hook extension declarations, slot extension declarations, and pipeline extension declarations. The hook registry module receives and manages the hook handlers registered by each module, responds to hook scheduling requests, and sequentially calls and executes handlers according to their descending priority, based on the HookResult returned by each handler. The type (Pass / Continue / Intercept) and the blocking indication field in the interception result determine whether to continue execution of the subsequent processor or terminate execution; the Slot Registry module is used to receive and manage the content contribution entries registered by each module, respond to slot collection requests, sort them in ascending order of priority, and merge them into a unified result set for return; the Pipeline Registry module is used to receive the registration of pipeline definitions and extension stages, respond to build requests, and insert the extension stage into the basic stage sequence according to the insertion positioning instructions (insertAfter / insertBefore) of the extension stage to form a complete pipeline execution chain; the lifecycle cleanup module is used to automatically traverse each registry center and clear all extension registration records of the target module when the target module is unloaded or deactivated.

9. The method according to claim 1, characterized in that, The modules interoperate through the hook registry, slot registry, and pipeline registry. There is no dynamic class loading or reflection invocation relationship between modules at runtime. The programming language implementation details of each module are encapsulated within the module itself. Modules only expose extension points and interoperability behaviors to the outside world through module manifest files and registry interfaces. The multi-language modular application system supports modules implemented in multiple programming languages, including Kotlin, Java, Groovy, Python, and C. The registry uses a unified type definition (InteropTypes) as the data exchange format, including HookResult, SlotContent, and PipelineStage types. Modules in different programming languages ​​interoperate across languages ​​through the unified type definition and registry interface without establishing any direct language-level dependencies between modules.

10. The method according to claim 1, characterized in that, Modules can establish interoperability relationships in two ways: (1) Declarative method: The module declares the provides and consumes fields in the module manifest file (module.json). When the module is activated, the platform automatically parses the declaration and completes the registration operation of each registry center; (2) Imperative method: When the module is running, it calls the registration method of each registry center through the plugin interface object, directly registers the hook processor with the hook registry center, registers the content contribution item with the slot registry center, and registers the pipeline extension stage with the process pipeline registry center; The items registered in both ways are uniformly managed in the registry center and distinguished by the registration method mark; When the declarative registration and the imperative registration generate duplicate registration for the same hook name, the imperative registration shall prevail.