Static program open source component analysis method
By constructing a hierarchical semantic call graph and performing topological sorting, we can identify and resolve deep-seated compatibility issues caused by component upgrades, provide detailed conflict reports and remediation suggestions, solve the problem that traditional tools cannot detect deep-seated compatibility issues, and achieve efficient component compatibility analysis and remediation.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2025-09-10
- Publication Date
- 2026-03-17
AI Technical Summary
In real-world development, upgrading a library (component) often leads to dependency hell, where a simple version update causes a chain of unpredictable compilation errors or runtime crashes. Traditional tools can usually only detect direct API call errors and cannot solve deeper, more hidden problems during compatibility testing.
This paper presents a static program open-source component analysis method. By constructing a hierarchical semantic call graph, performing topological sorting and software detection, it outputs a conflict report, identifies destructive changes and transitive conflicts, including API existence changes, API signature changes, API behavior changes, and transitive dependency conflicts, and generates a detailed conflict report to guide the remediation.
Effectively identify and prevent system crashes or logical errors caused by component upgrades. Through hierarchical semantic call graphs and topological sorting, ensure the orderliness and determinism of the analysis process, provide conflict priority, scope of impact and remediation suggestions, and reduce debugging and repair time.
Smart Images

Figure CN120950367B_ABST
Abstract
Description
Technical Field
[0001] This invention relates to the technical field of software analysis, and in particular to a method for analyzing open-source components of static programs. Background Technology
[0002] Modern software development heavily utilizes third-party open-source components. As these components iterate and evolve with feature upgrades and bug fixes, software maintainers face the challenge of upgrading them. A significant challenge during upgrades is ensuring compatibility between the software and the third-party open-source components it calls. Traditional methods employ semantic versioning, relying on the maintainers of the open-source components to standardize compatibility between different versions. This manual annotation approach is unreliable and neglects the connection between the caller of the open-source component and the component itself.
[0003] Currently, Chinese invention patent application number CN202411418998.7 discloses a compatibility testing method, device, electronic device, storage medium, and program product. The method includes: acquiring version change data of the software under test, and determining at least one changed function based on the version change data; performing static analysis on the current source code of the software under test to obtain corresponding call relationship data; constructing call chain data corresponding to each changed function based on the call relationship data; and determining at least one target component from multiple components in the software under test that is associated with the call chain data corresponding to each changed function. This disclosed embodiment does not require running code, achieving non-intrusive code testing for the software under test; it can effectively detect compatibility risks arising from changes to both entry and non-entry code, improving the effectiveness of compatibility testing. However, in real-world development, upgrading a library (component) often leads to dependency hell, where a simple version update causes a chain of unpredictable compilation errors or runtime crashes. Traditional tools typically only detect direct API call errors and cannot address deeper, more hidden problems during compatibility testing. Summary of the Invention
[0004] The technical problem solved by this invention is that in real-world development, upgrading a library (component) often leads to dependency hell, where a simple version update causes a chain of unpredictable compilation errors or runtime crashes. Traditional tools can usually only detect direct API call errors and cannot solve deeper and more hidden problems during compatibility testing.
[0005] To solve the above technical problems, the present invention provides the following technical solution: A method for analyzing open-source components based on static programs, comprising the following steps:
[0006] Step S1: Input the project source code, parse the project source code, obtain the semantic call graph, perform hierarchical management of the semantic call graph, and obtain the hierarchical semantic call graph;
[0007] Step S2: Perform topological sorting on the layered semantic call graph to obtain the component inspection sequence. When inspecting, check the components one by one according to the order of the final obtained component inspection sequence.
[0008] Step S3: Compare the layered semantic call graphs of the old and new versions of the component to be upgraded, perform software detection on the component to be upgraded, and output a conflict report.
[0009] Preferably, step S1 includes:
[0010] Input the project source code, build a description file for the project source code, the description file includes a project build configuration file and a package management manifest file, define the target component as the new version number and old version number of the component that needs to be compatibility analyzed, parse the description file, obtain the first-level dependent components, transitive dependent components and component version numbers, and obtain the semantic call graph based on the first-level dependent components, transitive dependent components and component version numbers;
[0011] The package management tool reads the build description file in the project root directory, extracts the region tags in the description file, and identifies all the third-party components that the project directly declares to use from the region tags. These third-party components are the first-level dependent components.
[0012] Components with transitive dependencies include those that recursively depend on first-level dependencies;
[0013] Extract the unique identifiers and version numbers declared by the developers in the files for each first-level dependent component using a package management tool.
[0014] Preferably, the intermediate representation of the project source code is traversed, and basic primitives are extracted as nodes and edges for constructing a semantic call graph. The nodes include components, packages, classes or structs, interfaces, functions, methods, fields and attributes, and the edges include call blocks, inherits blocks, implements blocks, accesses blocks and references blocks.
[0015] Preferably, each edge represented by a `calls` block is labeled with context information. The context information includes parameter source and type, function return value usage, exception handling, and implementation point context. Parameter source includes constants, variables, and function return values. Function return value usage includes direct return, assignment to variables, use as a condition, and passing as a parameter to functions and methods. Exception handling includes checking whether the call point during program execution is wrapped by a `try-catch` block. If the detection result is abnormal, an exception is marked. Implementation point context includes identifying whether the implementation class has added a new public method or changed the default behavior of the interface method for each edge represented by an `implements` block. If a new public method has been added or the default behavior of the interface method has been changed, the newly added public method and the changed behavior of the interface method are recorded.
[0016] Each edge in the semantic call graph is assigned a comprehensive weight, the mathematical expression of which is:
[0017] ;
[0018] in, For comprehensive weighting, ) is the preset weighted averaging function. The number of times the code block represented by the edge appears in the project's source code. Let the edge represent the average depth of the code block in the call stack. The business criticality indicates whether the module is in the preset configuration file and is a critical business module. If it is, the value is 1; otherwise, the value is 0.5.
[0019] By using heuristic rules to further subdivide the entity types of nodes, a semantic call graph is obtained.
[0020] Preferably, hierarchical management of the semantic call graph includes:
[0021] The semantic call graph is divided into top, middle and bottom layers;
[0022] The top layer includes component nodes, the middle layer includes class nodes and interface nodes, and the bottom layer includes method nodes and field nodes. The cross-layer relationships between each layer are as follows: the class nodes and interface nodes in the middle layer belong to the component nodes through the contains relationship, and the method nodes and field nodes in the bottom layer belong to the class nodes and interface nodes through the defines relationship. The cross-layer relationships also include connecting the class nodes and interface nodes in the middle layer with the method nodes and field nodes in the bottom layer through the calls block, inherits block, and implements block.
[0023] The hierarchical semantic call graph is stored using a graph database.
[0024] Preferably, step S2 includes:
[0025] The semantic call graph after layering is topologically sorted to obtain the component inspection sequence. The component inspection sequence is a linear acyclic sequence. When performing compatibility checks on the components, the components are traversed in reverse order to obtain incompatible components to be upgraded.
[0026] Topological sorting includes:
[0027] Calculate the in-degree of all nodes in the hierarchical semantic call graph;
[0028] Initialize the dependency queue and add all nodes with an in-degree of 0 to the dependency queue to form the lowest level of dependencies, which means that no other components depend on them;
[0029] Initialize the result list, which is used to store the topologically sorted sequence. Iterate through the dependency queue, and while the dependency queue is not empty, execute the following sub-steps:
[0030] Step S21: Randomly remove a dependency node from the dependency queue;
[0031] Step S22: Add the dependency node to the end of the result list;
[0032] Step S23: Identify all adjacent nodes of all the dependent nodes. An adjacent node is a dependent node that the dependent node points to, indicating that the pointed-to dependent node depends on the dependent node. When an adjacent node is identified, perform the following sub-steps:
[0033] Step S231: Decrement the in-degree of the adjacent node by 1;
[0034] Step S232: When the in-degree of the adjacent node becomes 0, add the adjacent node to the dependency queue;
[0035] If the number of nodes in the final result list is equal to the number of nodes in the hierarchical semantic call graph, then the topology sorting is successful, and the result list is the final component inspection sequence.
[0036] If the number of nodes in the final result list is less than the total number of nodes in the hierarchical semantic call graph, it indicates that there is a circular dependency in the hierarchical semantic call graph, and the circular dependency problem should be reported to the upper layer.
[0037] Preferably, step S3 includes:
[0038] Traverse the components to be upgraded in the result list, compare the layered semantic call graphs corresponding to the old and new versions of the components to be upgraded, and perform software detection operations on the components to be upgraded. The software detection operations include destructive change detection and transitive conflict detection.
[0039] The destructive change detection includes API existence change detection, API signature change detection, and API behavior or semantic change detection;
[0040] The API existence change detection includes:
[0041] Detect public class, interface, and method nodes that existed in the old version of the layered semantic call graph but do not exist in the new version of the layered semantic call graph;
[0042] Check if any abstract methods without default implementations have been added to the parent class or interface, causing all subclasses to fail to compile. If so, manually rewrite the code or delete them directly.
[0043] The API signature change detection includes:
[0044] Check for modifier changes, including: changing public to protected or private, removing static, and adding final to a class or method;
[0045] Detect whether the number, type, and order of the parameters have changed;
[0046] Check if the return value type has changed;
[0047] The API behavior or semantic change detection includes:
[0048] Detect changes to the throws declaration and analyze the changes between the original non-exception method and the current exception method by analyzing the call context;
[0049] Detect boundary value behavior changes by analyzing the call context;
[0050] Detect changes in the inheritance hierarchy, including changes to the parent class of a class that cause inconsistencies in the behavior of inherited methods in the subclass.
[0051] Preferably, the transitive conflict detection includes:
[0052] After a component is upgraded, checks are performed to identify dependency version conflicts, resource conflicts, and the impact of dependency eviction. The checks for dependency version conflicts include:
[0053] The upgraded component introduces new transitive dependencies and transitive dependency nodes. The transitive dependency nodes are the upgraded component itself. The new transitive dependencies include the updated edges of the hierarchical semantic call graph based on the upgraded component. In the updated hierarchical semantic call graph, it is checked whether there are other component nodes that are only compatible with the un-upgraded component.
[0054] Checking for resource conflicts includes completely different package paths and configuration file formats caused by switching from Log4j 1.x to 2.x;
[0055] Checking the impact of dependency eviction involves determining whether the dependency remediation mechanism of the Maven build tool has mistakenly evictioned a necessary older repository. If the check determines that eviction is necessary, then the older repository is evictioned.
[0056] Preferably, the conflict report includes a risk summary and a conflict list:
[0057] The risk summary includes a dashboard presentation of the results of disruptive change detection and transitive conflict detection;
[0058] The conflict list includes conflict priority, conflict description, scope of impact, and remediation recommendations;
[0059] Conflict priority is determined by sorting based on conflict type and the combined weight in the layered semantic call graph. The sorting logic based on conflict type is that destructive changes take precedence over transitive conflicts, and the sorting logic based on combined weight is that the larger the value, the higher the priority.
[0060] The conflict description includes an explanation of the software detection results, which include the type of destructive change detected, such as method deletion and parameter type mismatch.
[0061] The scope of impact is determined by using the reverse lookup capabilities of the layered semantic call graph to list all specific code locations in the project that call the changed API. These specific code locations include files, line numbers, and context code snippets.
[0062] The repair suggestions include using big data to search for code repair suggestions that show incompatibility in historical software test results, and generating a repair suggestion table for each software test result.
[0063] Preferably, the software detection operation is provided as an IDE plugin to offer real-time suggestions during the developer's coding process;
[0064] Integrate software testing operations into the CI / CD pipeline and execute them automatically during code submission or build phases.
[0065] The beneficial effects of this invention are as follows: It constructs a hierarchical semantic call graph containing rich contextual information, enabling analysis to go beyond the mere existence of method names and delve into whether the behavior and semantics of methods have changed. By topologically sorting component dependencies, this application proposes a component inspection sequence, which solves the real-world dilemma where fixing one conflict triggers another. It ensures that before inspecting any component, all its dependent components have been analyzed and confirmed, guaranteeing the orderliness and determinism of the analysis process. This draws inspiration from the deadlock-free concept in operating systems, clearly categorizing compatibility issues into two main types: destructive changes focus on changes to the component being upgraded itself, while transitive conflicts focus on changes to the entire dependency network caused by component upgrades. This classification greatly enhances the understanding of the problem's essence. The final conflict report is not merely a list of errors; it includes conflict priority, precise impact scope, and specific remediation suggestions. This provides developers with a complete workflow from problem discovery to problem localization and resolution. This method enables workers to discover and resolve deep-seated compatibility issues early, preventing them from evolving into difficult-to-track online bugs, thereby reducing debugging and repair time. By proactively identifying disruptive changes and transitive conflicts, it effectively prevents system crashes or logical errors caused by component upgrades. Attached Figure Description
[0066] Figure 1 This is a basic flowchart illustrating a static program open-source component analysis method according to an embodiment of the present invention. Detailed Implementation
[0067] To make the above-mentioned objects, features and advantages of the present invention more apparent and understandable, the specific embodiments of the present invention will be described in detail below with reference to the accompanying drawings. Obviously, the described embodiments are only some embodiments of the present invention, and not all embodiments.
[0068] Reference Figure 1 As an embodiment of the present invention, a method for analyzing open-source components based on static programs is provided, comprising the following steps:
[0069] Step S1: Input the project source code, parse the project source code, obtain the semantic call graph, perform hierarchical management of the semantic call graph, and obtain the hierarchical semantic call graph;
[0070] Step S2: Perform topological sorting on the layered semantic call graph to obtain the component inspection sequence. When inspecting, check the components one by one according to the order of the final obtained component inspection sequence.
[0071] Step S3: Compare the layered semantic call graphs of the old and new versions of the component to be upgraded, perform software detection on the component to be upgraded, and output a conflict report.
[0072] This application proposes a highly systematic and in-depth software component compatibility analysis method, aiming to deeply and accurately analyze the version compatibility of components. By constructing a semantic call graph and managing it in layers, the analysis goes beyond the API signature level and delves into the call context and semantic level. By cleverly using a conflict-free dependency cycle strategy, it can systematically detect two core issues at the same time: destructive changes and transitive dependency conflicts. This transforms the chaotic conflict remediation work into an orderly and followable process, significantly improving the efficiency and success rate of solving complex dependency problems.
[0073] Step S1 includes:
[0074] Input the project source code, build a description file for the project source code. The description file includes the project build configuration file and the package management manifest file. The project build configuration file and the package management manifest file specifically include Maven's pom.xml, Gradle's build.gradle, and NPM's package.json. Define the target component as the new version number and old version number of the component that needs to be analyzed for compatibility. Parse the description file to obtain the first-level dependent components, transitive dependent components and component version numbers. Obtain the semantic call graph based on the first-level dependent components, transitive dependent components and component version numbers.
[0075] The package management tool reads the build description file in the project root directory and extracts the region tags from the description file, such as Maven's. <dependencies>Tags identify all third-party components that the project directly declares as needing to use from the area tags; these third-party components are the first-level dependent components.
[0076] Components with transitive dependencies include those that recursively depend on first-level dependencies;
[0077] Extract the unique identifiers and version numbers declared by the developer in the file for each first-level dependency component using a package management tool. Unique identifiers include, for example, Maven's groupId / artifactId, and NPM's package name; version numbers include, for example, an exact version 1.2.3, or a version range 1.0.0, [1.0, 2.0].
[0078] This document defines how to initiate the analysis process from a real-world project. It specifies that the input source is a standard project description file and clarifies how to resolve direct dependencies (first-level dependencies) and indirect dependencies (transitive dependencies) from it. It concretizes the abstract input project source code, enabling its automated application to mainstream Java or JavaScript projects. This makes the method universal and operable, representing the first step in the tool's implementation.
[0079] Traverse the intermediate representation of the project's source code and extract basic primitives as nodes and edges to construct the semantic call graph. Nodes include components, packages, classes or structs, interfaces, functions, methods, fields, and properties. Edges include calls, inherits, implements, accesses, and references blocks. The calls block represents method call relationships, the inherits block represents inheritance relationships between classes, the implements block represents implementation relationships between classes and interfaces, the accesses block represents method access relationships to fields, and the references block represents reference relationships between classes.
[0080] This step aims to extract the most basic structure and relationships from the low-level representation of the code, forming a primitive call graph. It provides a structured data foundation for subsequent analysis. By extracting these basic graph primitives from the intermediate representation of the code, it transforms the unstructured source code into a graph capable of mathematical and algorithmic analysis—a prerequisite for all subsequent analysis.
[0081] For each edge represented by a `calls` block, context information is labeled. This context information includes parameter source and type, function return value usage, exception handling, and implementation point context. Parameter source includes constants, variables, and function return values. Function return value usage includes direct return, assignment to variables, use as a condition, and passing as a parameter to functions and methods. Conditions include `if(method()!=null)`. Exception handling includes checking whether the call point during program execution is wrapped by a `try-catch` block. If the check result is abnormal, an exception is marked. Implementation point context includes identifying whether the implementation class has added a new public method or changed the default behavior of the interface method for each edge represented by an `implements` block. If a new public method has been added or the default behavior of the interface method has been changed, the newly added public method and the changed behavior of the interface method are recorded.
[0082] Each edge in the semantic call graph is assigned a comprehensive weight, and the mathematical expression for the comprehensive weight is as follows:
[0083] ;
[0084] in, For comprehensive weighting, ) is the preset weighted averaging function. The edge represents the number of times the code block appears in the project's source code. The edge represents the average depth of the code block in the call stack. The shallower the depth, the closer it is to the business entry point and the more important it is. The business criticality indicates whether the module is in the preset configuration file and is a critical business module. If it is, the value is 1; otherwise, the value is 0.5.
[0085] In this embodiment, the weighted average function is a normalized weighted sum function. Based on the weighted sum function, each input parameter is first normalized to the range of [0, 1], and then a weighted sum is performed. This can effectively solve the problem of inconsistent dimensions of different parameters.
[0086] The overall weight is used to quantify the importance of each edge in the semantic call graph;
[0087] By using heuristic rules to further subdivide the entity types of nodes, a semantic call graph is obtained.
[0088] For example, further subdivide the entity types of nodes:
[0089] Methods include constructors, factory methods, getter / setter methods, and ordinary methods;
[0090] The classes include utility classes, model classes, service classes, and abstract base classes.
[0091] This step is crucial for constructing a semantic graph, as it injects rich contextual information and weights into the basic primitives.
[0092] Contextual information enables the analysis to identify implicit behavioral changes, weights allow for intelligent sorting of the final conflict reports, enabling developers to prioritize the most important conflicts, and node subdivision allows for more precise analysis rules. This transforms a simple call graph into an information-rich semantic graph.
[0093] Hierarchical management of semantic call graphs includes:
[0094] The semantic call graph is divided into top, middle and bottom layers;
[0095] The top layer includes component nodes, the middle layer includes class nodes and interface nodes, and the bottom layer includes method nodes and field nodes. The cross-layer relationships between each layer are as follows: the class nodes and interface nodes in the middle layer belong to the component nodes through the contains relationship, and the method nodes and field nodes in the bottom layer belong to the class nodes and interface nodes through the defines relationship. The cross-layer relationships also include connecting the class nodes and interface nodes in the middle layer with the method nodes and field nodes in the bottom layer through the calls block, inherits block, and implements block.
[0096] This application utilizes the graph database Neo4j to store the hierarchical semantic call graph. The inherent features of graph databases are well-suited for complex multi-hop dependency tracing and pattern matching, providing efficient query capabilities for the compatibility comparison in the second part.
[0097] The purpose of constructing a layered semantic call graph is to build an interface call graph that is rich in information, has a clear structure, and can reflect the call context.
[0098] A hierarchical structure allows analysis to be performed at different levels of abstraction; for example, one can view dependencies between components macroscopically or trace the call chain of a specific method microscopically. This greatly improves the flexibility and efficiency of the analysis. Using graph databases is best practice in engineering and is well-suited for handling such complex, multi-hop graph relationship queries, providing high performance assurance for subsequent impact analysis.
[0099] Step S2 includes:
[0100] The semantic call graph after layering is topologically sorted to obtain the component inspection sequence. The component inspection sequence is a linear acyclic sequence. When performing compatibility checks on components, the components are traversed in reverse order to obtain incompatible components to be upgraded. The inspection sequence ensures that all components that a component depends on have been checked before any component is checked.
[0101] Topological sorting includes:
[0102] Calculate the in-degree of all nodes in the hierarchical semantic call graph; in this method, the in-degree of a node represents how many components depend on it, for example:
[0103] D: 4.0 has an in-degree of 0, meaning no components depend on it;
[0104] C:3.0 has an in-degree of 1, meaning it is dependent on A:1.0;
[0105] B: 2.0 has an in-degree of 1, meaning it is dependent on A: 1.0;
[0106] A: The in-degree of 1.0 is 2, indicating that it is depended on by MyProject;
[0107] MyProject's in-degree = 0 indicates that it is a top-level application and is not depended on by other components;
[0108] Initialize the dependency queue by adding all nodes with an in-degree of 0 to the dependency queue to form the lowest-level dependencies, which means that no other components depend on them, i.e., [D: 4.0, MyProject] in the example above;
[0109] Initialize the result list, which stores the topologically sorted sequence. Iterate through the dependency queue, executing the following sub-steps while the dependency queue is not empty:
[0110] Step S21: Randomly remove a dependency node from the dependency queue;
[0111] Step S22: Add the dependency node to the end of the result list;
[0112] Step S23: Identify all adjacent nodes of all dependent nodes. An adjacent node is a dependent node that a dependent node points to, indicating that the pointed-to dependent node depends on the dependent node. When an adjacent node is identified, perform the following sub-steps:
[0113] Step S231: Decrement the in-degree of adjacent nodes by 1;
[0114] Step S232: When the in-degree of an adjacent node becomes 0, add the adjacent node to the dependency queue;
[0115] Execute according to the example above:
[0116] Example 1: When D:4.0 is retrieved from the dependency queue, the result list = [D:4.0];
[0117] D:4.0 points to B:2.0 and C:3.0;
[0118] B: 2.0 The in-degree becomes 0 (1-1=0), and it is added to the dependency queue;
[0119] C: 3.0 The in-degree becomes 0 (1-1=0), and it is added to the dependency queue;
[0120] Dependency queue = [MyProject, B: 2.0, C: 3.0], the order may vary.
[0121] Example 2: When MyProject is retrieved from the dependency queue, the result list = [D:4.0, MyProject];
[0122] MyProject has no outbound edges because MyProject does not depend on any components;
[0123] Dependency queue = [B: 2.0, C: 3.0];
[0124] Example 3: Retrieve A: 1.0 from the dependency queue, result list = [D: 4.0, MyProject, B: 2.0, C: 3.0, A: 1.0];
[0125] A: 1.0 points to MyProject;
[0126] MyProject's in-degree becomes -1 (0-1=-1), but it has already been processed, so we get the dependency queue = [].
[0127] If the number of nodes in the final result list is equal to the number of nodes in the hierarchical semantic call graph, then the topology sorting is successful, and the result list is the final component inspection sequence.
[0128] If the number of nodes in the final result list is less than the total number of nodes in the hierarchical semantic call graph, it indicates that there is a circular dependency in the hierarchical semantic call graph. That is, some nodes can never reach an in-degree of 0 because they are in a cycle and report the circular dependency problem to the upper layer.
[0129] This orderly checking process, analogous to the principle of synchronized transmission direction in deadlock-free strategies, avoids triggering another deeper conflict while fixing one conflict, thus avoiding a cycle of repair-destruction.
[0130] A linear acyclic sequence means that if component A depends on B, and B depends on C, then A cannot depend on C in turn (directly or indirectly), otherwise a circular dependency will be formed, and topological sorting cannot be performed. This is itself an issue that needs to be reported.
[0131] When we perform component compatibility checks according to this sequence, for any component in the sequence, we guarantee that all components it directly or indirectly depends on have completed compatibility checks (or their new versions have been determined). This avoids the predicament of checking component A and finding that its dependent component B has not yet determined which version it will use, thus making it impossible to determine whether A is compatible. This section treats component upgrades as a systematic project, applying the deadlock-free approach to systematically discover and resolve conflicts.
[0132] Step S3 includes:
[0133] Traverse the components to be upgraded in the result list, compare the layered semantic call graphs of the old and new versions of the components to be upgraded, and perform software detection operations on the components to be upgraded. The software detection operations include destructive change detection and transitive conflict detection.
[0134] Destructive change detection includes API existence change detection, API signature change detection, and API behavior or semantic change detection;
[0135] API existence change detection includes:
[0136] Detect public class, interface, and method nodes that existed in the old version of the layered semantic call graph but do not exist in the new version of the layered semantic call graph;
[0137] Check if any abstract methods without default implementations have been added to the parent class or interface, causing all subclasses to fail to compile. If so, manually rewrite the code or delete them directly.
[0138] API signature change detection includes:
[0139] Check for modifier changes, including: changing public to protected or private, removing static, and adding final to a class or method;
[0140] Detect whether the number, type, and order of the parameters have changed;
[0141] Check if the return value type has changed, for example, if the return value changes from String to Object;
[0142] API behavior or semantic change detection includes:
[0143] Detect changes to the throws declaration and analyze the changes between the original non-exception method and the current exception method by analyzing the call context;
[0144] By analyzing the call context, boundary value behavior changes are detected. For example, in this method, if (method()== null), if the new version of the method changes to return Optional.empty() or throws NPE, then it constitutes an implicit behavior change.
[0145] Detect changes in the inheritance hierarchy, including changes to the parent class of a class that cause inconsistencies in the behavior of inherited methods in the subclass.
[0146] In networking, protocol-level deadlocks typically occur between different message types or protocols, forming circular dependencies as they wait for responses from each other, leading to communication stagnation. If we analogize an API's name, parameter list, return value type, exception declaration, expected behavior, and semantics to protocols, and the caller's API calls and expected behavior to be analogous to message types, then the deadlock is analogous to the caller's code "waiting" for the behavior of the old protocol, which the new component can never provide, thus preventing further execution. When the caller's code (based on expectations of the old protocol) attempts to use a new version of the component (which provides the behavior of the new protocol), a fundamental mismatch occurs, leading to a "stagnation" or "crash" in the program logic.
[0147] Destructive change detection is a preventative method against "protocol-level compatibility deadlocks." Destructive change detection (API existence changes, API signature changes, API semantic changes) proactively identifies fundamental protocol changes between old and new component versions. For example, a method promised in the old version might be deprecated in the new version. When the calling code attempts to call it, it's as if it's trying to communicate with a no-longer-existing protocol endpoint. The caller passes parameters according to the old protocol, but the new protocol requires different types, leading to parameter mismatches. The old protocol promised to return null for failure, while the new protocol throws an exception. The calling code might handle this with `if(result==null)` logic, but it will never get null, resulting in logical errors or even null pointer exceptions. By detecting these analogous protocol mismatches during compilation or static analysis (rather than runtime), the system immediately issues warnings or errors. This forces developers to modify the calling code according to the new component's "protocol" before execution, thus eliminating the possibility of program logic stagnation or crashes caused by such "protocol mismatches." This is similar to informing both parties of a new protocol standard before a network communication begins, thus avoiding deadlocks caused by protocol incompatibility.
[0148] It provides a concrete and comprehensive approach to identify the most direct compatibility risks. By detecting removed APIs, modified parameters or return values, as well as more subtle exceptions and boundary value behavior changes, it can proactively prevent a large number of compilation errors and runtime logic errors. The analogy of protocol-level deadlock is very apt, helping developers understand the severity of such problems: a fundamental breach of convention has occurred between the calling code and the called library.
[0149] Transitive conflict detection includes:
[0150] After a component is upgraded, checks are performed to identify dependency version conflicts, resource conflicts, and the impact of dependency eviction. The checks for dependency version conflicts include:
[0151] The upgraded component introduces new transitive dependencies and transitive dependency nodes. The transitive dependency node is the upgraded component itself. The new transitive dependencies include the updated edges of the hierarchical semantic call graph based on the upgraded component. In the updated hierarchical semantic call graph, it is checked whether there are other component nodes that are only compatible with the un-upgraded component.
[0152] Checking for resource conflicts includes completely different package paths and configuration file formats caused by switching from Log4j 1.x to 2.x;
[0153] Checking the impact of dependency eviction involves determining whether the dependency remediation mechanism of the Maven build tool has mistakenly evictioned a necessary older repository. If the check determines that eviction is necessary, then the older repository is evictioned.
[0154] In networking, routing-level deadlocks typically occur when packets contend for shared resources (such as buffers within a router), forming a circular wait chain that prevents further forwarding. This relates to the path selection and resource allocation of packets within the network. Imagine the project's class loader environment and runtime library paths as router paths; these are shared resources used to provide the required component versions. Think of the different modules or components in the project's need for or reference to specific transitive dependency versions as packets. A routing deadlock occurs when different parts of the project request different and incompatible versions of the same transitive dependency component, and the build or runtime environment (router) can only provide one version or provides a conflicting version, causing loading failure. This prevents some components from obtaining the correctly routed dependency version, thus preventing them from loading or running correctly.
[0155] Transitive conflict detection is a method to prevent "route-level compatibility deadlocks." It identifies potential conflict paths by recognizing "routing requirement conflicts" between different parts of a project regarding shared component versions. For example:
[0156] Dependency version conflict detection indicates that component A requires CommonLib: 1.0, while component B requires CommonLib: 2.0. The project build tool (router) must select a version. If version 2.0 is selected, component A may fail to route (due to the inability to find version 1.0 at runtime).
[0157] Resource conflict detection revealed cases like Log4j 1.x and Log4j 2.x, which are completely different in package paths. Even if they both exist in the classpath, they may cause confusing or incompatible loading behaviors, as if the data packets were routed to two completely different and incompatible sub-networks with the same destination.
[0158] Dependency eviction can detect that the dependency mediation strategy of a build tool may silently evict a specific version required by a component, causing the incorrect version to be routed only at runtime.
[0159] The component inspection sequence generated by topology sorting plays a crucial role here. It provides a conflict-free routing strategy. Before a compatibility check is performed on a component in the sequence, the compatibility issues of all the component's dependencies (including version selection) have been handled or determined. This means that when it is ComponentA's turn, the final version of CommonLib it requires has been determined. If this determined version is incompatible with ComponentA, the system will report it immediately and suggest measures such as upgrading ComponentA or adjusting the CommonLib version.
[0160] By identifying and resolving these routing requirement conflicts during the static analysis phase, it is ensured that each component can reach the unique dependency version it expects and is compatible with when the application starts. This is like pre-planning the paths and resource allocations of all network packets, avoiding routing deadlocks caused by resource contention or path mismatches at runtime.
[0161] The conflict report includes a risk summary and a list of conflicts:
[0162] The risk summary includes a dashboard presentation of the results of disruptive change detection and transitive conflict detection;
[0163] The conflict list includes conflict priority, conflict description, scope of impact, and remediation recommendations;
[0164] Conflict priority is determined by sorting based on conflict type and the combined weight in the layered semantic call graph. The sorting logic based on conflict type is that destructive changes take precedence over transitive conflicts, and the sorting logic based on combined weight is that the larger the value, the higher the priority.
[0165] The conflict description includes an explanation of the software detection results, which include the type of destructive change detected, such as method deletion and parameter type mismatch.
[0166] The scope of impact is determined by using the reverse lookup capabilities of the layered semantic call graph to list all specific code locations in the project that call the changed API. These specific code locations include files, line numbers, and context code snippets.
[0167] The repair suggestions include using big data to search for code repair suggestions that show incompatibility in historical software test results, and generating a repair suggestion table for each software test result.
[0168] For example, if the API change detection result shows that OldClass.deprecatedMethod() has been deleted, the corresponding repair suggestion is to replace it with the new API NewClass.replacementMethod(String);
[0169] A transitive conflict was detected, indicating a dependency conflict. Component-A requires lib-http-v3, while Component-B requires lib-http-v4. The recommended solution is to use lib-http-v4 in pom.xml. <dependencymanagement>Set the unified version to v4, and check for software detection operations on Component-A, or exclude lib-http-v4 from the dependency node of Component-B.
[0170] It ensures that the ultimate value of the entire analysis method can be realized. A good tool should not only discover problems, but also help users solve them. Prioritization allows developers to grasp the key points, the scope of impact can be accurately located to all code points that need to be modified, and the fix suggestions greatly lower the threshold for fixing. This makes the entire method form a closed loop from analysis to solution.
[0171] The software detection process is implemented as an IDE plugin to provide real-time suggestions to developers while they are coding.
[0172] Integrating software testing into the CI / CD pipeline and executing it automatically during code submission or build phases serves as a quality gate before code merging, proactively preventing online risks arising from component upgrades.
[0173] This embodies the shift-left principle of modern software engineering, which emphasizes early problem detection. IDE plugins provide real-time feedback while developers are coding, enabling immediate correction of errors. CI / CD integration acts as the final quality gate, automatically blocking the merging of code with compatibility risks, ensuring the health and stability of the codebase from a process perspective. This allows the patented technology to be truly integrated into daily development and maximize its effectiveness.
[0174] This method proposes a systematic and automated framework for component compatibility analysis. It constructs a hierarchical semantic call graph containing rich contextual information, enabling analysis to go beyond the mere existence of method names and delve into whether the behavior and semantics of methods have changed. By topologically sorting component dependencies, this application proposes a component inspection sequence, which solves the real-world dilemma where fixing one conflict triggers another. It ensures that before inspecting any component, all its dependent components have been analyzed and confirmed, guaranteeing the orderliness and determinism of the analysis process. This borrows from the deadlock-free concept in operating systems, clearly categorizing compatibility issues into two main types: destructive changes focusing on changes to the component being upgraded itself, and transitive conflicts focusing on changes to the entire dependency network caused by component upgrades. This classification greatly enhances the understanding of the problem's essence. The final conflict report is not just a list of errors; it includes conflict priority, precise impact scope, and specific remediation suggestions. This provides developers with a complete workflow from problem discovery to problem localization and resolution. This method enables workers to discover and resolve deep-seated compatibility issues early, preventing them from evolving into hard-to-track online bugs, thereby reducing debugging and fixing time. By proactively identifying disruptive changes and transitive conflicts, it effectively prevents system crashes or logical errors caused by component upgrades.
[0175] Those skilled in the art will understand that embodiments of the present invention can be provided as methods, systems, or computer program products. Therefore, the present invention can take the form of a completely hardware embodiment, a completely software embodiment, or an embodiment combining software and hardware aspects. Furthermore, the present invention can take the form of a computer program product embodied on one or more computer-usable storage media containing computer-usable program code. The storage medium can be implemented by any type of volatile or non-volatile storage device or a combination thereof, such as Static Random Access Memory (SRAM), Electrically Erasable Programmable Read Only Memory (EEPROM), Erasable Programmable Read Only Memory (EPROM), Programmable Red Only Memory (PROM), Read Only Memory (ROM), magnetic storage, flash memory, magnetic disk, or optical disk. These computer program instructions can also be stored in a computer-readable storage medium capable of directing a computer or other programmable data processing device to function in a particular manner, such that the instructions stored in the computer-readable storage medium produce an article of manufacture including instruction means implemented in a flow... Figure 1 One or more processes and / or boxes Figure 1 The function specified in one or more boxes.
[0176] It should be noted that the above embodiments are only used to illustrate the technical solutions of the present invention and are not intended to limit it. Although the present invention has been described in detail with reference to preferred embodiments, those skilled in the art should understand that modifications or equivalent substitutions can be made to the technical solutions of the present invention without departing from the spirit and scope of the technical solutions of the present invention, and all such modifications or substitutions should be covered within the scope of the claims of the present invention.< / dependencymanagement> < / dependencies>
Claims
1. A static program open source component analysis method based on, characterized in that, The method comprises the following steps: Step S1: inputting project source code, parsing the project source code, obtaining a semantic call graph, and performing hierarchical management on the semantic call graph to obtain a hierarchical semantic call graph; Step S2: performing topological sorting on the hierarchical semantic call graph to obtain a component checking sequence, and checking components one by one in the order of the final component checking sequence when performing checking; Step S3: comparing the hierarchical semantic call graphs corresponding to the new and old versions of the component to be upgraded, performing a software detection operation on the component to be upgraded, and outputting a conflict report; Traversing the intermediate representation of the project source code, extracting basic graph elements as nodes and edges of the semantic call graph, the nodes including components, packages, classes or structures, interfaces, functions, methods, fields and attributes, and the edges including calls code blocks, inherits code blocks, implements code blocks, accesses code blocks and references code blocks; Labeling context information on each edge represented by a calls code block, the context information including parameter sources and types, use of function return values, exception handling and implementation point context, the parameter sources including constants, variables and function return values, the use of function return values including direct return, assignment to variables, use as a judgment condition and as a parameter passed to functions and methods, the exception handling including detection of whether a call point in program running is wrapped by a try-catch block, and if the detection result is abnormal, marking an exception, and the implementation point context including each edge represented by an implements code block, identifying whether an implementation class adds a new public method or changes the default behavior of an interface method, and if a new public method is added or the default behavior of an interface method is changed, recording the newly added public method and the changed behavior of the interface method; Assigning a comprehensive weight to each edge in the semantic call graph, and the mathematical expression of the comprehensive weight is: ; wherein, is a comprehensive weight, is a preset weight average function, is the number of times the code block represented by the edge appears in the project source code, is the average depth of the code block represented by the edge in the call stack, is a business criticality, indicating whether it is in a preset configuration file designated critical business module, if it is, the value is 1, if not, the value is 0.5; Subdividing the entity types of the nodes by using heuristic rules to obtain the semantic call graph; The hierarchical management of the semantic call graph comprises: Dividing the semantic call graph into a top layer, a middle layer and a bottom layer; The top layer includes component nodes, the middle layer includes class nodes and interface nodes, and the bottom layer includes method nodes and field nodes, the cross-layer relationship between the layers including that the class nodes and the interface nodes included in the middle layer are subordinate to the component nodes through a contains relationship, the method nodes and the field nodes included in the bottom layer are subordinate to the class nodes and the interface nodes through a defines relationship, and the cross-layer relationship further includes that the class nodes and the interface nodes in the middle layer are connected with the method nodes and the field nodes in the bottom layer through calls code blocks, inherits code blocks and implements code blocks; The hierarchical semantic call graph is stored through a graph database.
2. The static program open source component analysis based method of claim 1, wherein, The step S1 comprises: Input project source code, build a description file for the project source code, the description file including a project build configuration file and a package management list file, define target components as new and old version numbers of components requiring compatibility analysis, parse the description file to obtain first-level dependent components, transitive dependent components and component version numbers, and obtain a semantic call graph based on the first-level dependent components, the transitive dependent components and the component version numbers; Read the build description file under the project root directory through a package management tool, extract the area tags in the description file, and identify all third-party components directly declared by the project to be used from the area tags, the third-party components being the first-level dependent components; The transitive dependent components include components recursively dependent on the first-level dependent components; Extract the unique identifiers of each first-level dependent component and the version numbers declared by the developer in the file through the package management tool.
3. The static program open source component analysis based method of claim 2, wherein, The step S2 comprises: Topologically sort the layered semantic call graph to obtain a component inspection sequence, the component inspection sequence being a linear acyclic sequence, and traverse the components in reverse order to obtain non-compatible components to be upgraded during compatibility inspection of the components; The topological sorting comprises: Calculate the in-degree of all nodes of the layered semantic call graph; Initialize a dependency queue, add all nodes with an in-degree of 0 to the dependency queue to form the bottommost dependencies, i.e., indicate that no other components depend on them; Initialize a result list for storing the sequence after topological sorting, and cyclically process the dependency queue, when the dependency queue is not empty, cyclically execute the following sub-steps: Step S21: arbitrarily take out a dependency node in the queue from the dependency queue; Step S22: add the dependency node to the end of the result list; Step S23: identify all adjacent nodes of the dependency node, the adjacent nodes being dependency nodes pointed to by the dependency node, indicating that the pointed-to dependency nodes depend on the dependency node, when an adjacent node is identified, execute the following sub-step operations: Step S231: reduce the in-degree of the adjacent node by 1; Step S232: when the in-degree of the adjacent node becomes 0, add the adjacent node to the dependency queue; If the number of nodes included in the final result list is equal to the number of all nodes in the layered semantic call graph, the topological sorting is successful, and the result list is the finally obtained component inspection sequence; If the number of nodes included in the final result list is less than the number of all nodes in the layered semantic call graph, it indicates that there is a circular dependency in the layered semantic call graph, and the circular dependency problem is reported to the upper layer.
4. The static program open source component analysis based method of claim 3, wherein, The step S3 comprises: Traverse the components to be upgraded in the result list, compare the layered semantic call graphs corresponding to the new and old versions of the components to be upgraded, and perform a software detection operation on the components to be upgraded, the software detection operation including destructive change detection and transitive conflict detection: The destructive change detection includes API existence change detection, API signature change detection and API behavior or semantic change detection; The API existence change detection includes: detecting public classes, interfaces and method nodes that exist in the layered semantic call graph of the old version and do not exist in the layered semantic call graph of the new version; detecting whether an abstract method is newly added in the parent class or interface without providing a default implementation, which causes all child classes to fail to compile, and if so, manually rewriting the code or directly deleting it; The API signature change detection includes: detecting whether there is a modifier change, including: public to protected or private, removing static, adding final to the class or method; detecting whether the number, type and order of parameters are changed; detecting whether the return value type is changed; The API behavior or semantic change detection includes: detecting changes in throws declaration and comparing changes in original non-exception methods and current exception methods through analysis of the calling context; detecting boundary value behavior changes through analysis of the calling context; detecting inheritance system changes, including changes in the parent class of a class causing inconsistent method behaviors of child classes.
5. The static program open source component analysis based method of claim 4, wherein, The transitive conflict detection includes: When the component is upgraded, perform dependency version conflict, resource conflict and dependency eviction impact checks, the dependency version conflict check includes: The upgraded component introduces new transitive dependency relationships and transitive dependency nodes, the transitive dependency node is the upgraded component itself, the new transitive dependency relationship includes edges in the updated layered semantic call graph based on the upgraded component, and checks whether there are other component nodes that are only compatible with un-upgraded components in the updated layered semantic call graph. The resource conflict check includes the complete difference in package path and configuration file format between Log4j 1.x->2.x; The dependency eviction impact check includes judging whether the dependency mediation mechanism of the build tool Maven incorrectly evicts a certain old version library, if the check determines that it must be evicted, the old version library is evicted.
6. The static program open source component analysis based method of claim 5, wherein, The report content of the conflict report includes risk summary and conflict list: The risk summary includes displaying the results of destructive change detection and transitive conflict detection in the form of a dashboard; The conflict list includes conflict priority, conflict description, impact scope and repair suggestion; The conflict priority includes sorting according to conflict type and comprehensive weight in the layered semantic call graph, the sorting logic according to conflict type is that destructive change is superior to transitive conflict, and the sorting logic according to comprehensive weight is that the larger the value, the higher the priority; The conflict description includes explaining the software detection results, including outputting the destructive change detection type, including method deletion and parameter type mismatch; The impact scope lists all specific code locations in the project that call the changed API by using the reverse query capability of the layered semantic call graph, the specific code location includes file, line number and context code snippet; The repair suggestion includes searching for code repair suggestions for incompatible states in historical software detection results through big data, and generating a repair suggestion table corresponding to each software detection result.
7. The static program open source component analysis based method of claim 6, wherein, Detecting software operations as an IDE plugin to provide real-time hints while developers are coding; Integrating software operations into CI / CD pipelines to automatically execute at code commit or build stages.
Citation Information
Patent Citations
Compatibility detection method and device, electronic equipment, storage medium and program product
CN118939563A
Method, device and equipment for quickly identifying components of project open source component and medium
CN118377466A
Large model enhanced code security detection method
CN120372627A