OSGi (Open Service Gateway Initiative) framework-oriented cross-module call graph construction method
By processing the target program and configuration files of the OSGi framework, an intermediate representation (IR) is generated. Combined with the semantics of the inter-module interaction API, a complete cross-module call graph is constructed, which solves the problem that existing tools cannot analyze the loading and interaction of OSGi framework modules and realizes the connectivity of inter-module call relationships.
Patent Information
- Application Number
- CN202511021819.0
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2025-07-24
- Publication Date
- 2025-12-09
AI Technical Summary
Existing static analysis tools are ineffective at analyzing module loading and inter-module interactions in the OSGi framework, resulting in fragmented and incomplete call graphs that fail to depict the key call relationships between modules.
By processing the target program and configuration files, an intermediate representation (IR) is generated, pointer analysis is performed, a pointer flow graph and a preliminary call graph within a single module are constructed, and the call edges between modules are constructed by combining the inter-module interaction API semantics of the OSGi framework, ultimately constructing a complete cross-module call graph.
It enables effective analysis of module loading and inter-module interaction in the OSGi framework, and constructs a connected cross-module call graph that can depict the complete call relationship between modules.
Smart Images

Figure CN121092126A_ABST
Abstract
Description
Technical Field
[0001] This invention relates to a method for constructing cross-module call graphs for the OSGi framework, belonging to the field of static analysis technology for modular software frameworks. Background Technology
[0002] As software systems become increasingly complex, modular development has become the mainstream approach. The OSGi (OpenService Gateway initiative) framework, a mature, Java-oriented dynamic modular system specification, is widely used in complex software systems such as enterprise applications, IoT gateways, embedded systems, and integrated development environments. The OSGi framework allows a large system to be broken down into multiple functionally cohesive and independent modules. Each module can be installed, started, stopped, updated, and uninstalled independently without restarting the entire application. This high cohesion and low coupling significantly improves software maintainability, scalability, and reusability.
[0003] However, the modular nature of the OSGi framework, especially its core module loading and service interaction mechanisms, poses a significant challenge to traditional static program analysis. The lifecycle behaviors of OSGi application modules, such as loading, starting, and stopping, can be specified through configuration files, or, in more modern declarative services, through annotations to mark lifecycle callback methods. Regarding inter-module interaction, OSGi applications employ an indirect communication model based on service registration and discovery. One module can publish service objects to the framework's global service registry, while another module, at runtime, dynamically retrieves a reference to that service object from the registry by querying a specific service interface name before calling its methods.
[0004] This module loading and service interaction mechanism makes traditional static analysis tools ineffective. Traditional tools cannot analyze OSGi project configuration files and annotations, nor can they statically parse the OSGi framework's dynamic service calls based on string name matching. Therefore, when existing analysis tools are applied to OSGi programs, the call graphs they generate are often fragmented and incomplete, typically only depicting the call chain within a single module, while the crucial call relationships between modules are completely lost. Therefore, there is an urgent need for a static program analysis technique that can automatically identify module loading and inter-module interactions within the OSGi framework. Summary of the Invention
[0005] Purpose of the invention: To address the problems and shortcomings of existing technologies, this invention provides a method for constructing cross-module call graphs for the OSGi framework. By modeling the OSGi framework module loading and inter-module interaction mechanisms, and analyzing the registration and acquisition relationships of service objects between modules, the invention aims to construct cross-module call graphs.
[0006] Technical solution: A method for constructing a cross-module call graph for the OSGi framework, the method comprising the following steps: S1. Process the target program and related configuration files to be detected to obtain the result IR for static analysis; S2. Perform pointer analysis on the IR generated in step S1 to generate a pointer flow graph (PFG) and a preliminary call graph (CG) within a single software module. S3. Combining the intermediate code (IR) related to module interaction in the target program, construct the call edges between modules by modeling the API semantics of inter-module interaction provided by the OSGi framework; S4. Based on the analysis results of steps S2 and S3, construct a complete cross-module call graph.
[0007] Preferably, step S1, which processes the target program and related configuration files to be detected, specifically includes: S11. Process the Java source code or bytecode of the target program and obtain the three-address code IR using the open-source framework Tai-e; S12. Process the application configuration file corresponding to each module and obtain the Java class name marked with the Bundle-Activator and Service-Component tags in the configuration file; S13. Process OSGi framework-related annotation information, including module startup annotations, module unregistration annotations, and dependency injection annotations. Use IR to read and parse the annotations to obtain the program entry point method within the module.
[0008] Preferably, the analysis in step S2 specifically includes: S21. For the user code-related parts of IR, adopt the statement-oriented pointer analysis method to construct the pointer flow graph and preliminary call graph within a single module; S22. Analyze the module startup, module deregistration, and dependency injection annotations in IR in conjunction with relevant configuration files to improve the internal pointer flow graph and call graph of the module. S23. For the parts of IR that are related to other framework code, use existing modeling methods or traditional pointer analysis methods to further improve the pointer flow graph and call graph.
[0009] Preferably, step S22, which involves analysis of module startup, module deregistration, and dependency injection annotations, specifically includes: S221. In the scanning program, obtain the Java methods annotated by the above annotations: @Activate method for marking module startup, @Deactivate method for marking module deactivation, and @Reference method for marking dependency injection. S222. Obtain the class containing the Java methods marked in S221, and create an object of the corresponding type for each class; S223. For the Java methods annotated in S221, match the objects created in S222 with the class where the annotated method is located, and establish the pointer relationship between the receiver pointer of the annotated method and the matched object; S224. Add the annotation method obtained in S221 to the analysis entry list of the traditional pointing analysis method.
[0010] Preferably, the modeling of the API semantics for inter-module interactions provided by the OSGi framework in step S3 specifically includes: S31. Registration of service objects in the modeling module: Based on the semantic description of the BundleContext.registerService interface in the OSGi framework specification, identify the correspondence between the service container where the service object is located and the registration name, and store the correspondence in the relationship container for management. S32. Obtaining the service container in the modeling module: Based on the semantic description of the BundleContext.getServiceReference interface in the OSGi framework specification, obtain the registration name in the interface parameters, match the service container corresponding to the registration name in the relation container, and construct the pointing relationship between the interface lvalue and the matched service container. S33. Obtaining service objects in the modeling module: Based on the semantic description of the BundleContext.getService interface in the OSGi framework specification, obtain the service container from the interface parameters, retrieve the service object from the service container, and establish the pointing relationship between the interface lvalue and the service object.
[0011] Preferably, step S4, which constructs a cross-module call graph, specifically includes: S41. Merge the method call graphs within each module to build a basic call structure; S42. Based on the analysis results of inter-module interactions, add call edges between modules; S43. Build and optimize the complete call chain between modules.
[0012] A computer device includes a memory, a processor, and a computer program stored in the memory and executable on the processor, wherein when the processor executes the computer program, it implements the steps of the cross-module call graph construction method for the OSGi framework as described above.
[0013] A computer-readable storage medium storing a computer program that executes the cross-module call graph construction method for the OSGi framework as described above.
[0014] Beneficial effects: Compared with existing technical solutions, the present invention has the following advantages: 1) This invention provides a pointer analysis method for the OSGi framework. This method, by modeling the module loading and inter-module interaction mechanisms in the OSGi framework, can construct a pointer flow graph connecting multiple modules.
[0015] 2) This invention provides a method for constructing cross-module call graphs. This method is based on pointer analysis and can analyze the call dependencies between modules, thereby constructing a complete cross-module call graph.
[0016] 3) The pointing analysis and call graph construction method proposed in this invention are also applicable to analyzing the features of other frameworks similar to OSGi. Attached Figure Description
[0017] Figure 1 This is a flowchart of a method according to an embodiment of the present invention. Detailed Implementation
[0018] The present invention will be further illustrated below with reference to specific embodiments. It should be understood that these embodiments are for illustrative purposes only and are not intended to limit the scope of the invention. After reading the present invention, any modifications of the present invention in various equivalent forms by those skilled in the art will fall within the scope defined by the appended claims.
[0019] like Figure 1 As shown, the method for constructing a cross-module call graph for the OSGi framework includes the following steps: S1. Process the target program and configuration file to be detected to obtain the result IR for static analysis; In processing the target program code to be detected, the open-source framework Tai-e is used to process the target program code to obtain the three-address code (IR) for static analysis. Simultaneously, the application configuration file corresponding to each module is processed to obtain the Java class names marked with the Bundle-Activator and Service-Component tags in the configuration file, as well as OSGi framework-related annotation information, including module startup annotations, module unregistration annotations, dependency injection annotations, etc. IR is used for reading and parsing to obtain the program entry method within the module.
[0020] S2. Perform pointer analysis on the IR generated in step S1 to generate a pointer flow graph (PFG) and a preliminary call graph (CG) within a single software module. S21. For the user code-related parts of IR, the traditional Statement-oriented pointer analysis method is adopted to construct the pointer flow graph and preliminary call graph within a single module. S22. Analyze the module startup, module deregistration, and dependency injection annotations in IR in conjunction with relevant configuration files to improve the internal pointer flow graph and call graph of the module. S23. For the parts of IR that are related to other framework code, use existing modeling methods or traditional pointer analysis methods to further improve the pointer flow graph and call graph.
[0021] S3. Combining the intermediate code (IR) related to module interaction in the target program, construct call edges between modules by modeling the API semantics of inter-module interaction provided by the OSGi framework.
[0022] Since this invention pertains to a static analysis method for the OSGi framework, the specific implementation method is described below with reference to Java code examples. The example code demonstrates the calling relationship between two OSGi modules. Module1 binds the service container containing the service object 's' to the registered name 'Service' through the OSGi inter-module interaction interface `BundleContext.registerService`. Module2 calls the OSGi inter-module interaction interface `BundleContext.getServiceReference` to obtain the service container 'sr' based on the registered name 'Service', then obtains the service object 's' through the OSGi inter-module interaction interface `BundleContext.getService`, and finally calls the method 'foo' of the service object 's' in Module1.
[0023] Line 1, / / module.name: Module1 Line 2, @Component class Module1 { Line 3, @Activate void start1(BundleContext context) { Line 4, Service s = new Service(); / / Create a service instance Line 5, context.registerService("Service", s); / / Register the service in the OSGi framework Line 6, Line 7, @Deactivate void stop1(BundleContext context) { Line 8, System.out.println("Module1 closed"); / / Outputs a closing message when the module is deactivated. Line 9, Line 10, Line 11, / / service.name: Service Line 12, class Service { Line 13, void foo() { Line 14, his.bar(); / / Call the internal bar method Line 15, Line 16, void bar() {} / / bar method implementation Line 17, Line 18, / / module.name: Module2 Line 19, @Component class Module2 { Line 20, @Activate void start2(BundleContext context) { Line 21, callService(context); / / Call the service retrieval method upon activation Line 22, Line 23, void callService(BundleContext context){ Line 24, ServiceReference sr; / / Declare service container variable Line 25, sr = context.getServiceReference("Service"); / / Get the service container Line 26, `Service temp = (Service) context.getService(sr);` / / Get the service instance Line 27, temp.foo() / / Calls the service's foo method; Line 28, Line 29, Regarding the example code above, step S22 involves the analysis of annotations related to module startup, module deregistration, and dependency injection: S221. The analyzer identifies the @Component annotation class Module1 in Module1 and the @Component annotation class Module2 in Module2. This indicates that both Module1 and Module2 are Java class names annotated with the Service-Component tag in the configuration file in step S12. At the same time, the analyzer identifies the @Activate annotation method start1 and the @Deactivate annotation method stop1 in Module1, and the @Activate annotation method start2 in Module2. S222. Obtain the class where the annotated methods in S221 are located. For each class, create an object of the corresponding type. The class where the annotated methods start1 and stop1 are located is Module1, so the analyzer creates an object of type Module1; the class where the annotated method start2 is located is Module2, so the analyzer creates an object of type Module2. S223. For the annotated methods obtained in S221, the parser establishes a pointer relationship between the receiver pointer of the annotated method and the matched object based on the class of the annotated method and the object created in S222. The class of the annotated methods start1 and stop1 is Module1, so the parser establishes a pointer relationship between the receiver pointer of start1 and stop1 and the Module1 type object created in S222. The class of the annotated method start2 is Module2, so the parser establishes a pointer relationship between the receiver pointer of start2 and the Module2 type object created in S222. At the same time, the parser creates a globally unique BundleContext type object and establishes a pointer relationship between the BundleContext type parameter pointer context of start1, stop1, and start2 and the global BundleContext object. S224. Add the annotation methods obtained in S221 to the analysis entry list of the traditional pointing analysis method. The analyzer will add the annotation methods start1, stop1 and start2 to the analysis entry list, indicating that these three annotation methods will be analyzed.
[0024] For the example code, step S3 involves modeling the API semantics of inter-module interactions provided by the OSGi framework: S31. In the modeling module, the service object is registered. According to the semantic description of the registerService interface in the OSGi framework specification, the analyzer identifies the correspondence between the service container where the service object s is located and the registered name Service in the code on line 5, and stores the correspondence in the relation container inside the analyzer. S32. In the modeling module, the service container is obtained. According to the semantic description of the getServiceReference interface in the OSGi framework specification, the analyzer identifies the service container corresponding to the registered name Service in the code on line 25 and establishes the pointing relationship between the lvalue sr in the code on line 25 and the service container. S33. Obtaining the service object in the modeling module: Based on the semantic description of the getService interface in the OSGi framework specification, the analyzer identifies in line 26 that the service container sr stores the service object s from Module1, and establishes the pointer relationship between the lvalue temp and the service object s. The analyzer can then analyze in subsequent analysis that the code on line 27 is calling the Module1.s.foo() method. At this point, the analyzer has completed the cross-module call between Module1 and Module2 through the service object.
[0025] For the example code, step S4 constructs a cross-module call graph: S41. The analyzer first constructs the method call graph within each module, including the call from the s.foo() method to the s.bar() method in Module1, and the call from the start2 method to the callService method in Module2. S42. Based on the analysis results of the inter-module interaction API, add a cross-module call edge from the callService method of Module2 to the s.foo() method of Module1; S43. Finally, a complete call chain is constructed: Module2.start2() → Module2.callService() → Module1.s.foo() → Module1.s.bar().
[0026] It is obvious to those skilled in the art that the steps of the methods described in the embodiments of the present invention can be implemented using general-purpose computing devices. They can be centralized on a single computing device or distributed across a network of multiple computing devices. Optionally, they can be implemented using device-executable program code, which can then be stored in a storage device for execution by a computing device. Furthermore, in some cases, the steps shown or described can be performed in a different order than those presented herein, or they can be fabricated as separate integrated circuit modules, or multiple modules or steps can be fabricated as a single integrated circuit module. Thus, the embodiments of the present invention are not limited to any particular hardware and software combination.
Claims
1. A method for constructing a cross-module call graph for the OSGi framework, characterized in that, Includes the following steps: S1. Process the target program and related configuration files to be detected to obtain the result IR for static analysis; S2. Perform pointer analysis on the IR generated in step S1 to generate a pointer flow graph and a preliminary call graph within a single software module. S3. Combining the intermediate code (IR) related to module interaction in the target program, construct the call edges between modules by modeling the API semantics of inter-module interaction provided by the OSGi framework; S4. Based on the analysis results of steps S2 and S3, construct a complete cross-module call graph.
2. The method for constructing a cross-module call graph for the OSGi framework according to claim 1, characterized in that, Step S1, which processes the target program and related configuration files to be detected, specifically includes: S11. Process the Java source code or bytecode of the target program and obtain the three-address code IR using the open-source framework Tai-e; S12. Process the application configuration file corresponding to each module and obtain the Java class name marked with the Bundle-Activator and Service-Component tags in the configuration file; S13. Process OSGi framework-related annotation information, including module startup annotations, module unregistration annotations, and dependency injection annotations. Use IR to read and parse the annotations to obtain the program entry point method within the module.
3. The method for constructing a cross-module call graph for the OSGi framework according to claim 1, characterized in that, The analysis in step S2 specifically includes: S21. For the user code-related parts of IR, adopt the statement-oriented pointer analysis method to construct the pointer flow graph and preliminary call graph within a single module; S22. Analyze the module startup, module deregistration, and dependency injection annotations in IR in conjunction with relevant configuration files to improve the internal pointer flow graph and call graph of the module. S23. For the parts of IR that are related to other framework code, use modeling methods or pointer analysis methods to further improve the pointer flow graph and call graph.
4. The method for constructing a cross-module call graph for the OSGi framework according to claim 3, characterized in that, Step S22, which involves analysis of module startup, module deregistration, and dependency injection annotations, specifically includes: S221. In the scanning program, obtain the Java methods annotated by the @Activate method used to annotate module startup, the @Deactivate method used to annotate module deactivation, and the @Reference method used to annotate dependency injection. S222. Obtain the class containing the Java methods marked in S221, and create an object of the corresponding type for each class; S223. For the Java methods annotated in S221, match the objects created in S222 with the class where the annotated method is located, and establish the pointer relationship between the receiver pointer of the annotated method and the matched object; S224. Add the annotation method obtained in S221 to the analysis entry list of the traditional pointing analysis method.
5. The method for constructing a cross-module call graph for the OSGi framework according to claim 1, characterized in that, The modeling of the API semantics for inter-module interactions provided by the OSGi framework in step S3 specifically includes: S31. Registration of service objects in the modeling module: Based on the semantic description of the BundleContext.registerService interface in the OSGi framework specification, identify the correspondence between the service container where the service object is located and the registration name, and store the correspondence in the relationship container for management. S32. Obtaining the service container in the modeling module: Based on the semantic description of the BundleContext.getServiceReference interface in the OSGi framework specification, obtain the registration name in the interface parameters, match the service container corresponding to the registration name in the relation container, and construct the pointing relationship between the interface lvalue and the matched service container. S33. Obtaining service objects in the modeling module: Based on the semantic description of the BundleContext.getService interface in the OSGi framework specification, obtain the service container from the interface parameters, retrieve the service object from the service container, and establish the pointing relationship between the interface lvalue and the service object.
6. The method for constructing a cross-module call graph for the OSGi framework according to claim 1, characterized in that, Step S4, which constructs the cross-module call graph, specifically includes: S41. Merge the method call graphs within each module to build a basic call structure; S42. Based on the analysis results of inter-module interactions, add call edges between modules; S43. Build and optimize the complete call chain between modules.
7. A computer device, characterized in that: The computer device includes a memory, a processor, and a computer program stored in the memory and executable on the processor. When the processor executes the computer program, it implements the steps of the cross-module call graph construction method for the OSGi framework as described in any one of claims 1-6.
8. A computer-readable storage medium, characterized in that: The computer-readable storage medium stores a computer program that executes the cross-module call graph construction method for the OSGi framework as described in any one of claims 1-6.