Towards Anticipation of Architectural Smells using Link Prediction Techniques

08/20/2018 ∙ by J. Andrés Díaz-Pace, et al. ∙ UNICEN 0

Software systems naturally evolve, and this evolution often brings design problems that cause system degradation. Architectural smells are typical symptoms of such problems, and several of these smells are related to undesired dependencies among modules. The early detection of these smells is important for developers, because they can plan ahead for maintenance or refactoring efforts, thus preventing system degradation. Existing tools for identifying architectural smells can detect the smells once they exist in the source code. This means that their undesired dependencies are already created. In this work, we explore a forward-looking approach that is able to infer groups of likely module dependencies that can anticipate architectural smells in a future system version. Our approach considers the current module structure as a network, along with information from previous versions, and applies link prediction techniques (from the field of social network analysis). In particular, we focus on dependency-related smells, such as Cyclic Dependency and Hublike Dependency, which fit well with the link prediction model. An initial evaluation with two open-source projects shows that, under certain considerations, the predictions of our approach are satisfactory. Furthermore, the approach can be extended to other types of dependency-based smells or metrics.



There are no comments yet.


page 14

page 15

page 16

This week in AI

Get the week's most popular data science and artificial intelligence research sent straight to your inbox every Saturday.

I Introduction

Software systems naturally evolve due to changes in their requirements and operating environment. Along this evolution, the amount and complexity of the interactions among the software elements of a system are likely to increase, with a consequent effect on the system design structure, which tends to erode over time [1, 2]. For instance, modules might become dependent on each other because of a new functionality being implemented. Design erosion symptoms are often related to high coupling and undesired dependencies in the module structure. The so-called architectural smells [3] are (poor) design decisions that contribute to system erosion. Several of these smells, such as cycles [4], involve particular patterns of undesired dependencies. The early detection of such smells is important for developers, so that they can plan ahead for maintenance or refactoring efforts, and preserve the quality and integrity of the system.

In this context, several tools exist for helping developers to manage system dependencies and also detect some types of smells, including: LattixDSM, SonarQube, Sonargraph, HotspotDetector, or Arcan, to name a few [1, 5, 6]. These tools normally extract dependency graphs from source code and might compute metrics, which altogether serve to identify candidate architectural smells in the code. However, a limitation of this kind of tools is that they are only able to detect the smells once their underlying dependencies actually exist in the source code. Although identifying smells is important, we argue that being able to anticipate them (before they appear) is more helpful, because developers can take actions early to prevent the smells. Furthermore, once introduced in the code, violations to design rules (like those caused by smells) can be difficult to fix by developers [1].

In this article, we propose a proactive approach that leverages on link prediction (LP) techniques for inferring likely configurations of architectural smells. In prior work [7], we investigated whether LP techniques can rely on structural features from previous system versions to predict module dependencies for the next version, by means of Machine Learning (ML) techniques. That work was concerned with individual dependencies only. Here, we further develop those ideas by looking at groups of dependencies (both actual and predicted ones), which enable us to spot architectural smells from the literature [3, 8]. These smells are considered at the package level. The approach makes two contributions: i) it defines strategies for identifying specific types of smells based on the outputs of a ML classification model (which only predicts individual dependencies); and ii) it incorporates content-based features in the classification model for boosting its predictions. Thus, these contributions improve the capabilities of our prediction approach.

We provide an instantiation of the approach for two well-known architectural smells: Cyclic Dependency and Hub-like Dependency [9, 10], and evaluate its performance in two open-source Java systems. We consider different system versions for training the classification model and testing the quality of the predictions (both dependencies and smells). The results so far show that the approach is able to identify most smell instances (i.e., good recall), at the expenses of also identifying some mistaken smells to be analyzed (and eventually discarded) by a developer (i.e., affecting precision).

The rest of the article is organized into 7 sections. Section 2 gives background information about architectural smells, and motivates the prediction of dependencies for smell configurations. Section 3 discusses how the prediction of package dependencies is cast as a link prediction problem, and further, to a classification problem. We also explain the notion of topological and content-based features. Section 4 presents the main building blocks of our prediction approach. Section 5 describes the performed experimental study with two Java open-source systems. The main results and lessons learned of the study are discussed in Section 6. Section 7 covers related work. Finally, Section 8 presents the conclusions and outlines future work.

Ii From Dependencies to Architectural Smells

Software systems often exhibit design problems, which can be either introduced during development or along their evolution. These problems, also known as architectural smells [3], have a negative impact on the quality of the system, as they degrade its design structure. A smell usually comes from a poorly-understood or sub-optimal design decision. Different architectural smells have been catalogued in the literature [3, 10, 9, 11]. Of particular relevance to this work are the so-called dependency-based smells [3], which involve interactions among system components. These smells occur when one or more components violate design principles or rules, and often manifest themselves as undesired dependencies in the source code [1]. Two examples of such smells are: Cyclic Dependency (CD) [9] and Hub-like Dependency (HLD) [10]. CD and HLD smells can be identified at the class or at the package level [5]. In this work, we focus on their characteristics and detection strategies for packages.

Cyclic Dependency

In this smell, various components directly or indirectly depend on each other to function properly. For example, Figure 1 depicts a cycle among three packages of the Apache Derby project (excerpt). The packages are connected by means of usage relations (dependencies). The cycle (denoted by green and red arrows) did not exist in version but was introduced in version due to the addition of a dependency between org.apache.derby.impl.sql.catalog and org.apache.derby.impl.sql.execute.rts (in red in the figure). This relation is a case of an undesired dependency, from the perspective of the CD smell. In general, the chain of relations among packages breaks the desirable acyclic nature of a subsystem’s dependency structure. Thus, the components involved in a cycle can be hard to maintain, test or reuse in isolation. Cycles might have different shapes [4, 12], and some cycles might be more harmful for the system health than others. The strategies for detecting cycles in the package structure are based on the DFS graph algorithm [5].

Hub-like Dependency

This smell arises when a component has outgoing and ingoing dependencies with a large number of other components. For example, Figure 2 shows that package org.apache.derby.catalog.types uses 4 packages (right side) and is used by 6 other packages in version of Apache Derby (excerpt). Then, in version, the central package requires two additional outgoing dependencies (in red in the figure), which altogether transform the package into a hub. These two relations are undesired dependencies, from the perspective of the HLD smell. The strategy for detecting potential hubs in a package network follows from [10]. It first computes the median of the number of incoming and outgoing dependencies of all packages. Then, for each package, it checks if both its incoming and outgoing dependencies are greater than the incoming and outgoing medians respectively, and finally checks whether the difference between the incoming and outgoing dependencies is less than a fraction of the total dependencies of that package. According to this detection strategy, org.apache.derby.catalog.types at version is not a hub, but when the package structure changes in version (because of the two dependencies added), then the detection strategy marks org.apache.derby.catalog.types as a hub.

Figure 1: Example of Cyclic Dependency (Apache Derby)
Figure 2: Example of Hub-like Dependency (Apache Derby)

In the two examples above, the dependencies judged as ”undesirable” are due to new functionality allocated to existing classes or new classes being created under existing packages. These dependencies inadvertently appear (in the source code) from one system version to another. We assume here an architecture compliance process that periodically checks whether the current version of the system implementation satisfies a set of design rules, such as avoiding architectural smells, and reports any issues to developers.

Particular dependency-based smells can be detected (and also refactored) by means of several tools, such as: HotspotDetector [6], Arcan [5], Sonargraph, or Structure101, among others. Although useful, these tools are mostly reactive, in the sense that they are intended for scenarios in which the smells are realized in the code. Along this line, removing a smell is not always straightforward for developers, due to the additional efforts for refactoring undesired dependencies while ensuring that the system continues to function properly. Our work is motivated by the vision of a proactive tool able to spot patterns of dependencies in the code, or ”quasi-smells”, in which a (future) insertion of a few dependencies would precipitate the smells. If the most likely dependencies can be predicted, developers could benefit from early ”warnings” on potential architectural smells in the system.

Iii Link Prediction Techniques

A key observation about the appearance of dependencies contributing to architectural smells, like CD and HLD, is that, despite changes occurring at the class level, the package structure (or module level) remains more or less stable across system versions while dependencies among packages keep being added. There are, of course, a few exceptions such as: the initial versions of the system, in which the main structure and functionality is fleshed out, or when a refactoring takes place in a given version. Overall, by analyzing the package structure and its evolution over time, it is possible to predict which dependencies are likely to appear between pairs of packages. In this context, we resort to link prediction (LP) techniques from the field of social network analysis (SNA).

LP adapts SNA techniques for studying to what extent the evolution of a network can be modeled by using its intrinsic features  [13]. This involves inferring ”missing” links between pairs of nodes in a network (traditionally represented as a graph) based on the observable interactions (or links) among nodes and node attributes  [13]. An assumption here is that a software system can be seen as a network of software elements (e.g., modules, classes, methods) that behaves similarly to a social network, at a given level of abstraction (e.g., at the package level in Java systems).

A prerequisite for applying LP is to transform the system under analysis into a dependency graph. More formally, a dependency graph is a graph , where each node represents a module, and each edge (or link) represents a dependency from node to (). Since we deal with Java systems, nodes correspond to packages while edges represent relations between those packages. For this work, we limit dependencies to usage relations and assume that the dependency graph is extracted from the Java source code via static analysis techniques. For simplicity, we also consider each package as an individual module, although in practice some low-level packages are intended for code organization purposes and might not define module boundaries. More formally, our LP task takes a at time , and then infers the edges that will be added to at time . Let be the set of all possible edges among nodes in . The LP task generates a list of all possible edges in , and indicates whether each edge (in ) is present in at time .

LP in social networks is based on the principle of homophily [14], which states that interactions between similar individuals occur at a higher rate than those among dissimilar ones. In our context, this would mean that similar packages (according to some criteria) have a higher chance to establish dependencies than dissimilar packages. Most techniques for the LP problem are based on graph topological features that assess similarity between pairs of nodes [13]. Nonetheless, other types of features are also possible. In the following, we discuss topological and content-based features.

Topological features

These features are related to the graph structure and the role that the nodes (and their edges) play in that structure [13]. For instance, Common Neighbors is defined as the number of common adjacent nodes (i.e. neighbors) that two nodes have in common, aiming at capturing the notion that two disconnected elements who share neighbors would be ”introduced” to each other. This feature has been computed in the context of collaboration networks, allowing to verify a positive correlation between the number of shared neighbors of two given nodes and at time

, and the probability that

and will collaborate at a posterior time [15]. As an example, Figure 3 presents the formula for Common Neighbors along with an example for packages of Apache Derby (version The feature is computed for packages org.apache.derby.impl.sql.execute.rts and org.apache.derby.impl.sql.catalog (marked in bold in the figure). According to the corresponding dependency graph, both packages have the one and same neighbor. As a result, the Common Neighbors score for the analyzed packages is . Along this line, some researchers have also studied structural similarity metrics for source code entities [18], such as: Kulczynski, and Russell-Rao, among others.

Figure 3: Computing a Topological Feature for two Packages

Content-based features

These features are an alternative (and complementary) similarity criterion to topological features. Given two texts, the goal of content-based similarity is to determine how close or similar they are. For example, one of the simplest strategies is to compute the lexical overlap between texts. Natural language processing routines are used to transform texts into their bag-of-words representations 

[16], which can be built by considering different aspects of the original texts. For instance, representations could be restricted to only the appearing nouns, adjective or verbs, or could choose to remove all punctuation. In our domain, we can think of each Java class as a bag-of-words containing the most representative tokens that characterize its source code. In this regard, Figure 4 shows an example of three possible bag-of-words representations of two Apache Derby classes, either considering the name of the field attributes of the classes, the name of the declared methods, or the class comments and documentation. The bag-of-words class representations can be used to assess the similarity among the classes. A common similarity metric for two texts is the Cosine Similarity, whose formula is shown in the figure, and computes a score between and . It is worth noting that each bag-of-words representation could lead to different similarity scores, as the example shows. Although the presented bag-of-word representation is defined for classes, it can easily be extended to packages. In such a case, the bag-of-words representation of a package is defined as the (recursive) union of the bag-of-word representations of all the classes (and nested sub-packages) contained by .

Figure 4: Content-based Representation of Classes and Computation of Cosine Similarity Scores

Although intuitive, the homophily principle does not always hold for complex networks, such as those based on software-related dependencies [17]. For instance, two similar packages can intentionally be designed to not become dependent on each other, based on business logic or modularity reasons. On the contrary, dependencies might still appear between dissimilar packages. Thus, approaches being able to learn ”exceptions” to homophily are necessary. An interesting approach is to cast the LP task as a classification problem in which a prediction model is built based on graph information. In this setting, the classification model learns about both the existence and absence of relations between the different pairs of nodes in the dependency graph. Furthermore, this approach allows to take the history of the dependency graph into account (i.e. the graphs corresponding to previous system versions).

In order to train a classification model, the dependency graph is converted into a set of instances, called dataset

, which serves as the input of the classifier. Each instance consists of a given pair of nodes, a list of features characterizing the pair, and a label that indicates whether a dependency exists between the nodes or not. Those pairs of connected nodes are said to belong to the positive class, while those pairs of unconnected nodes are said to belong to the negative class. Table 

I presents the instance-based representation for some of the pairs of packages depicted in Figure 3. As it can be observed, instances are represented by two features: the Common Neighbors score and the Cosine Similarity of the comment bag-of-words representation of packages.

Target Source depends on target Common Neighbors Cosine Similarity Comments
org.apache.derby.catalog true 0.353 0.835
org.apache.derby.impl.sql.catalog false 0.618 0.877
org.apache.derby.impl.sql.execute true 0.389 0.870
org.apache.derby.catalog true 0.385 0.877
org.apache.derby.impl.sql.catalog false 0.605 0.939
org.apache.derby.impl.sql.execute.rts true 0.171 0.487
Table I: Example of Dataset (Apache Derby, version

In [7], we assessed the predictive power of LP techniques for inferring (individual) package dependencies using topological information from system versions. The results showed that classification models can provide reasonable predictions, assuming certain conditions in the pairs of versions used for the predictions (e.g., the consecutive versions have almost the same number of packages, a certain percentage of dependencies is added in the next version). Nonetheless, opportunities for improving the classification were identified. In particular, we hypothesize that content-based features can boost the performance of the trained classification models. To this end, instances in this work are characterized by means of both topological and content-based features. As regards topological features, we considered: Adamic-Adar, Common Neighbours, Resource Allocation and Sørensen, as well as the best performing metrics in [18], namely: Kulczynski, RelativeMatching and RusselRao. For content-based features, we included the Cosine Similarity

scores for the different bag-of-words representations previously defined, as well as representations considering method usage and variable definitions. In practice, a dataset of instances can initially include many different features (both topological and content-based ones), and then feature selection techniques  

[19] can be applied for (automatically) determining the subset of features being most relevant (or providing more information) for the classification task.

Iv Approach

Our approach works in two phases: first, it seeks to predict the appearance of new dependencies in the next system version, and then it filters them according to the characteristics of specific types of smells. Figure 5 depicts an overview of the main building blocks of the approach. Although the approach supports different architectural smells, in this work we customize the second phase for the CD and HLD smells.

Initially, there is a prediction phase in which individual dependencies are inferred based on training a binary classification model. To do so, the dependency graphs corresponding to the current and previous versions (noted as and , respectively) are required as inputs. The output of this phase is the set of dependencies that are likely to appear in the next system version . This phase is smell-independent, in the sense that only identifies dependencies that might prefigure smells in the second phase.

Figure 5: Two-phase Approach for Predicting Architectural Smells

The prediction phase internally involves 3 steps. In step , an instance-based representation of system versions (as presented in Section III) is constructed, based on both topological and content-based features. The goal of the classifier is to predict which new dependencies are likely to appear; hence, those pairs of nodes already connected in the graph are considered as the positive class, while those pairs without dependencies are considered as the negative class. In step , the classification model is built. As the figure shows, the training set comprises instances belonging to two system versions: i) existing dependencies in (as instances of the positive class), ii) missing dependencies in (as instances of the negative class), and iii) existing dependencies in . It is worth noting that the information from the system versions serves to train the classifier for properly learning instances of both the positive and negative classes. This mechanism allows us to include information of dependencies in that are guaranteed not to appear in the next version (). If we would only consider one system, no information regarding the negative class could be included in the model training, as it would not possible to guarantee that those dependencies are not going to appear in the next version.

Once the model is trained, step predicts which dependencies could appear in . Note also that the prediction might face the case of dependencies in appearing between packages that did not originally exist in (e.g., due to the creation of new packages). Although it is possible to predict that an existing package will depend on an unobserved package, we cannot determine what that unobserved package will be. In this regard, the trained classifier predicts whether the pairs of nodes that are not dependent on each other (i.e. they are unconnected) in might become dependent in . This means that only potential dependencies considering the packages already existing in are considered.

The fact that the classifier predicts if an individual dependency is likely to appear is not enough to actually predict the appearance of an architectural smell, since not every predicted dependency might cause a smell to emerge. Usually, an emerging smell is the result of a group of predicted and existing dependencies. To this end, in the second phase, predicted dependencies undergo a filtering process according to the type of smell at hand. As shown in the figure, this filtering phase requires the creation of filters for each smell type. The current filters for CD and HLD are described below.

Cycle Filter

It considers only predicted dependencies that lead to the closure of new cycles in (those cycles must not exist in previous versions). The predicted dependencies are considered all altogether, and simultaneously added to graph at , before checking for cycles.

Hub Filter

It considers only the nodes incidental to the predicted dependencies that fit with the hub definition of Section II. This process is exemplified in Figure 6. The default strategy111Other variants are possible, which are not covered due to space reasons works as following: for each node that is incidental to at least one predicted dependency, all its actual and predicted dependencies are analyzed together to compute the hub score of the node. For example, for computing the hub score of package E, both dependencies between E and D, and C and E are jointly considered in the analysis. Note that this strategy allows the detection of those nodes becoming hubs due to the addition of new dependencies, but disregards nodes that might become hubs due to changes in the overall structure of the dependency graph (i.e. nodes for which no new dependencies are added).

Figure 6: Hub Variants Example

V Study Settings

In order to assess the performance of the proposed approach for predicting architectural smells, we exercised it with two Java open-source systems: Apache Derby222 (40.30 KLOC) and Apache Ant333 (59.79 KLOC), which have been also used by others in the literature [8]. We selected systems with more than 10 major releases, and more than 10 contributors each. Derby versions correspond to the period 2008-2014, while Ant versions correspond to 2003-2018.

Table II summarizes the main characteristics of the two systems. Note that the number of changes with respect to the previous version might not match the absolute difference between the two versions. This is due to the fact that the noted differences correspond to changes/smells that could be predicted. Instead, changes caused by the addition of new packages are disregarded. The dependency graphs for the versions were extracted with the CDA tool444 that performs a static analysis of binary code. For the purpose of this work, class dependencies were ignored. To obtain meaningful predictions with our approach, the pairs of consecutive versions to analyze (, ) need to present changes regarding the existence of cycles or hubs, which implies the addition of packages dependencies from one version to the next one. As a result of this criterion, the subset of versions for which we made predictions are highlighted in bold (for new cycles) and italic (for new hubs) in the table. Cycles were detected by means of the Arcan555 tool. Finally, content information of classes and packages was extracted by parsing the source code with Java Parser666 and then computing the metrics with the Java String Similarity777 library. All the content-based features presented in Section III were computed, and then the information gain method [19] for feature selection was applied.

#c #p #deps #cycles cycle length #hubs hub degree
derby 1261 81 698 192 10.80 22 28.68
derby 1321 94 757, +61, -2 196, +4 10.55 26 - +4 28.34
derby 1322 94 757 196 10.55 26 28.34
derby 1344 96 767, +10 234, +4 11.59 28, +2 27.67
derby 1344 96 768+1 234 11.59 28 27.71
derby 1387 98 804 , +36 254, +6 12.99 29, +3 28.34
derby 1387 98 805+1 255+1 13.02 29 28.34
derby 1389 98 807+4, -2 257+2 12.98 29 28.44
derby 1395 97 837, +31, -1 305, +22 15.17 30, +1 30.03
derby 1395 96 838, +2, -1 305 15.17 30 30.03
derby 1395 96 841+3 306+1 15.13 30 30.06
derby 1406 96 851, +20, -10 280, +5 13.43 29, +1 30.62
derby 1453 100 938, +89, -2 291, +10 13.32 29, -1 32.89
derby 1454 100 938 291 13.32 29 32.89
ant 1.5.2 297 21 71 21 3.57 7 13.71
ant 1.5.3-1 297 21 71 21 3.57 7 13.71
ant 1.6.0 352 24 90, +20, -1 30, +1 3.73 9, +2 14.22
ant 1.6.1 353 24 90 30 3.73 9 14.22
ant 1.6.2 369 24 92+2 43+2 4.12 9 14.67
ant 1.6.3 380 25 97+5 43+1 4.70 9 15.33
ant 1.6.4 380 25 97 43 4.70 9 15.33
ant 1.6.5 380 25 97 43 4.70 9 15.33
ant 1.7.1 502 29 137, +46, -6 63, +5 5.10 12, +1 17.42
ant 1.8.0 557 30 148, +12, -1 69, +4 5.91 12 18.58
ant 1.9.3 772 61 282, +134 101, +3 6.25 12, +5 17.38
ant 1.9.4 774 61 283, +1 101 6.25 24 17.42
ant 1.9.5 776 61 283 101 6.25 24 17.42
ant 1.9.9 780 61 282, -1 100, -1 6.29 24 17.38
ant 1.10.0 782 61 284, +2 100 6.29 24 17.46
ant 1.10.1 782 61 284 100 6.29 24 17.46
ant 1.10.2 784 61 283, +1, -2 100 6.29 24 17.42
ant 1.10.3 784 61 283 100 6.29 24 17.42
where #c indicates number of classes, #p number of packages, #deps number of dependencies, and + and - indicate the number of changes regarding the previous version
Table II: General Characteristics of the Selected Systems

As previously mentioned, those dependencies that do not yet exist in are used as the input of the approach and thus constitute the test set. To assess the performance, is used to determine whether a dependency should be predicted. As a result, the test set follows the real class distribution of the system versions, i.e. negative instances are not under-sampled. Classification was performed using the Weka888

implementation of the SVM algorithm (Support Vector Machine), parametrized with a RBF kernel, which is useful for datasets with few instances of one of the classes. Performance was assessed by considering the traditional precision (i.e., the ratio between the number of actual discovered dependencies and the total number of predictions) and recall (i.e., the ratio between the actual discovered dependencies and the total number of actual dependencies) metrics. In principle, both recall and precision are relevant performance metrics for the predictions; however, we are more interested in recall than in precision, because this would indicate that all the smells are effectively identified (for the next version). Eventually, some smells can be mistakenly predicted and negatively impact on precision. If those smells are a small fraction, they could be discarded with a manual analysis of the outputs (of the approach) by developers.

Vi Evaluation

In this section, we discuss the predictions of the first phase of the approach, and how they influenced the results of the second phase. The cases of CD and HLD are presented separately. In the reported results, for each pair ( axis), the versions represent the span for the predictions, e.g., -- means that and served to train the model for predicting new architectural smells in . We refer to a quasi-cycle (or a quasi-hub) as a configuration of dependencies in the current system version that does not form a cycle (or a hub) yet, but upon the inclusion of predicted dependencies, it might become a cycle (or a hub) in the next version.

Dependency Prediction Phase

Figure 9

presents the results of the first phase for the two systems, when considering: i) topological features only, and ii) a combination of topological and content-based features. We computed precision and recall for the positive class (i.e., existing dependencies) and also a weighted F-Measure considering both classes (i.e., existing and non-existing dependencies). In practice, the positive class is the most relevant indicator, but we believe the weighted indicator provides a context for the former. Results are presented for those sets of versions in which new dependencies between already existing packages were added. As it can be observed, adding content-based features to the classification model increased the quality of the predicted dependencies. In particular, the improvement was most noticeable in precision for the positive class. The usage of (only) topological features achieved an average precision value of 0.5 and 0.6 in average for the positive class, while the combination of content-based features reached values of 0.75 and 0.85 in average for the same class for Apache Derby and Apache Ant, respectively. The average improvements were

and when analyzing Apache Derby and Apache Ant, respectively. This boosting in the classification also outperforms the initial results (without content-based features) reported in [7]. It is worth noting that the highest improvements for Apache Ant were observed for the pair of versions that yielded the lowest topology results (ant-1.10.1 - ant-1.10.2). This fact highlights the importance of considering additional features for characterizing the dependencies between packages, and hence, having better predictions of their evolution over time.

When considering only topological features, both systems reported good results in cases of a high recall and a moderate precision, which means that the trained model is capable of finding most future dependencies, but it also predicts false dependencies, i.e. dependencies that will not appear in the next version. Interestingly, for some of the Apache Ant versions, recall was perfect. When adding content-based features, we noticed that precision improved (i.e. the false dependencies decreased) while recall improved or remained the same.

In summary, including content-based features in the classification model helped to reduce the number of: i) missed dependencies that should have been predicted, and ii) dependencies that should not have been predicted. Having few mistaken predictions has consequences on the next phase of the approach, as it contributes to the reduction of mistakes in the (final) smell prediction. The average computation time for building the classifiers was around 10-15 seconds for Apache Derby and 1-2 seconds for Apache Ant (both cycles and hubs), on a PC i7-4500U 1.8 GHz. with 8GB RAM - Windows 10 and Java 1.8. The response time of the filters was negligible in the whole pipeline. In general, the computation time is affected by factors such as: number of features, size of the dependency graphs, and distribution of smells in the system versions.

(a) Apache Derby
(b) Apache Ant
Figure 9: Results for the Dependency Prediction Phase

Cycle Prediction

The values of precision and recall for predicting CD smells are presented in Figure 12. As it can be observed, recall is almost perfect, meaning that almost every new dependency leading to the closure of a quasi-cycle was found. On the other hand, precision results indicate that, in addition to predicting the correct dependencies, some other mistaken dependencies were also predicted. Nonetheless, even when precision might seem low (reaching minimum values of and for Apache Derby and Apache Ant, respectively), at most mistaken predictions were made. This amount represents at most a or of the total number of dependencies in the corresponding software versions. Therefore, the incidence of that fraction of mistaken dependencies is low in relation to the size of the system graphs. The mistaken dependencies correspond to cases in which a dependency predicted by the first phase of the approach would potentially close a quasi-cycle, but such a dependency did not actually appear on the next system version. Consequently, solving this problem would require mechanisms to diminish the influence of mistaken dependencies from the first phase.

(a) Apache Derby
(b) Apache Ant
Figure 12: Cycle Prediction Results

Hub Prediction

The values of precision and recall for predicting HLD smells are depicted in Figure 15. The filter allowed us to find all the correct hubs in every triple of analyzed versions. However, this result came at the cost of increasing the number of nodes mistakenly predicted, which manifested as a drop in precision.

(a) Apache Derby
(b) Apache Ant
Figure 15: Hub Prediction Results

From the observed results, we can say that that even though hubs could appear not only due to the addition of new edges to the specific nodes, but also due to changes in the overall graph structure, our analysis of the full set of predicted edges misguided the smell predictions, thus resulting in inaccurate results. The implications of these results are two-fold. First, for predicting new hubs, the analysis of nodes’ neighborhood seems more informative than the overall graph structure Only one dependency might not be sufficient to predict that a given node might become a hub. Second, hub predictions might not only depend on the known structure of the graph, but also on the additional packages and dependencies that are sub-sequentially added (as the result of the prediction).

The results for Apache Ant reinforced the observations drawn from Apache Derby. Note that the worst prediction results were in those system versions obtaining the worst dependency prediction results (in the first phase).

Threats to Validity

The study and predictions analyzed for the systems had some threats to validity. First, the characteristics of the two systems (all from the Apache ecosystem), their selected versions, as well as the particular smell instances appearing in those versions, might have influenced the performance of the classification model. Although we acknowledge that not all triples of versions are suitable for having good predictions, the relations between the selected triples and the features used in the classification model need further analysis. Second, the features might have also favored predictions for some smell types (e.g., cycles) but not for others (e.g., hubs). Thus, extending the approach to support new types of dependency-based smells requires the implementation of new filter strategies, but also might involve adjustments in the classification model. Third, we considered each package of the system as being a different module. However, this assumption might not hold in all systems, because of code organization aspects. For example, different sub-packages might belong to the same conceptual module. The criterion for identifying modules (from the code) or the granularity at which they are considered changes the graph structure, and consequently it might affect the link prediction task.

Vii Related Work

Regarding architectural smells, several characterizations and catalogs of smells have been reported in the literature [11, 6, 3, 20]. Most of these works categorize certain smells as related to undesired dependencies. Although several academic and commercial tools provide capabilities for automated detection of smells, only a few of them support the detection of architectural smells. Cycles are a common type of smell in existing catalogs, and its detection is supported by most tools.

In [6], the authors formalize the definition of five architectural smells, called hotspot patterns, including a type of package cycle. A tool called HotspotDetector, based on design structure matrices, is able to automatically detect instances of such hotspot patterns. A qualitative analysis with an industrial study demonstrated that the approach helps developers not only to find the important structural problems, but also guides them in conducting refactorings for those problems. Arcan [5] is a static analysis tool targeted to the detection of three architectural smells, including cycles and hubs. Arcan creates a graph database containing the structural dependencies of a Java system, and then runs several detection algorithms (one per smell) on this graph. At last, there are some commercial tools for detecting architectural smells, such as Designite999, which identifies seven architecture smells, including cycles and other dependency-based smell. As far as we are aware of, all the previous tools have no predictive capabilities.

When it comes to SNA techniques, a number of applications to Software Engineering problems have been reported [21, 22, 23]. For example, SNA has been used to predict software evolution [18, 22], the appearance of defects and bugs [21, 22], and the existence of vulnerable components [23]. In all cases, the authors agreed that the topological analysis of dependency graphs can reveal (or even predict) interesting properties of the software system under analysis. Another example is [24] that proposes an approach for extracting domain information from user manuals and predict logical coupling among software artifacts. However, with the exception of [17], LP techniques have not been exploited yet in Software Engineering. The closest LP approach for the first phase of our approach is the one proposed by Zhou et al. [17], which used LP techniques for predicting missing dependencies in build configuration files. Unlike our approach, ML techniques were not employed. Instead, the authors applied traditional LP algorithms derived from the homophily principle, with uneven results. A custom algorithm was later developed for the problem.

Viii Conclusions and Outlook

In this work, we develop an approach based on LP techniques and a classification model for predicting instances of architectural smells that are likely to appear in a system. This predictive capability is the main contribution of the work. The smells fall in the category of dependency-related smells. The predictions are informed by the current and previous versions of the system. The classification model relies on topological features of the package dependency graphs and also on context-based features from the system source code. The classification model works in tandem with a set of filters, according to the smell types being detected.

An initial evaluation with two types of smells in two open-source system showed a good performance for the positive class, when inferring individual dependencies, and also showed a high recall regarding the identification of the actual smells (in the next system version). This first aspect is attributed to the inclusion of content-based features in the classification model. As for the second aspect, we found evidence that the choice of the filter variant (for a given smell type) can affect both recall and precision, although we preferred good recall over precision in the analyzed cases. Furthermore, we observed that the smell predictions depended on the overall system structure (i.e., the package graph) as well as on the version history of the particular systems.

Despite the promising results, the approach has still some drawbacks and open issues. First, we need to perform a systematic study with more systems (both commercial and open-source) and with other types of dependency-based smells, in order to corroborate our findings. Second, the prediction capabilities are sensitive to the outputs of the classifier model (first phase of the approach), and are affected to a lesser extent by the subsequent filtering phase. Therefore, we still need to analyze and possibly extend the set of features used in the classification model. Along this line, we will continue investigating content-based criteria, and also consider software-specific metrics for source code entities. Some works have suggested that previous occurrences of a smell (within a given package) can increase the chance of the smell re-appearing in future versions. This information could be added as features to the classifier. There are also reported cases in which some smells are not harmful or might correspond to good design decisions (e.g., a Visitor pattern might generate a cycle among the participating elements) [25]. We would like to analyze if these examples can be learned by the classifier and distinguished in the predictions.

As well as new dependencies are added, existing dependencies could disappear in future versions, providing another opportunity for prediction. In this case, we are interested in predicting whether the previous graph structure (i.e. when a potentially disappearing dependency did not exist) will occur again [26]. Finally, the integration of the approach with existing tools or research prototypes, such as SonarQube or Arcan [5], is another subject for future work.


  • [1] L. Hochstein and M. Lindvall. Combating architectural degeneration: A survey. Inf. Softw. Technol., 47(10):643–656, July 2005.
  • [2] L. de Silva and D. Balasubramaniam. Controlling software architecture erosion: A survey. Journal of Syst. and Softw., 85(1):132–151, 2012.
  • [3] J. Garcia, D. Popescu, G. Edwards, and N. Medvidovic. Toward a catalogue of architectural bad smells. In QoSA, volume 5581 of LNCS, pages 146–162. Springer, 2009.
  • [4] H. Melton and E. Tempero. An empirical study of cycles among classes in java. Empirical Software Engineering, 12(4):389–415, Aug 2007.
  • [5] F. Arcelli Fontana, I. Pigazzini, R. Roveda, D.A. Tamburri, M. Zanoni, and E. Di Nitto. Arcan: A tool for architectural smells detection. In 2017 IEEE ICSA Workshops 2017, Gothenburg, Sweden, April 5-7, 2017, pages 282–285, 2017.
  • [6] R. Mo, Y. Cai, R. Kazman, and L. Xiao. Hotspot patterns: The formal definition and automatic detection of architecture smells. 2015 12th Working IEEE/IFIP Conf. on Software Architecture, pages 51–60, 2015.
  • [7] J. Andrés Diaz-Pace, A. Tommasel, and D. Godoy. Can network analysis techniques help to predict design dependencies? an initial study. In Proc. 2018 IEEE ICSA - to appear, pages 609–613. IEEE Computer Society., 2018.
  • [8] F. Arcelli Fontana, I. Pigazzini, R. Roveda, and M. Zanoni. Automatic detection of instability architectural smells. In ICSME, pages 433–437. IEEE Computer Society, 2016.
  • [9] R. Marinescu. Assessing technical debt by identifying design flaws in software systems. IBM Journal of Research and Dev., 56(5):9, 2012.
  • [10] W. Tracz. Refactoring for software design smells: Managing technical debt by girish suryanarayana, ganesh samarthyam, and tushar sharma. ACM SIGSOFT Software Engineering Notes, 40(6):36, 2015.
  • [11] M. Lippert and S. Roock. Refactoring in Large Software Projects: Performing Complex Restructurings Successfully. Wiley, 2006.
  • [12] H. A. Al-Mutawa, J. Dietrich, S. Marsland, and C. McCartin. On the shape of circular dependencies in java programs. In Australian Software Engineering Conference, pages 48–57. IEEE Computer Society, 2014.
  • [13] D. Liben-Nowell and J. Kleinberg. The link-prediction problem for social networks. J. Am. Soc. Inf. Sci. Technol., 58(7):1019–1031, 2007.
  • [14] M. McPherson, L. Smith-Lovin, and J.M. Cook. Birds of a feather: Homophily in social networks. Annu. Rev. Sociol, 27(1):415–444, 2001.
  • [15] M. Newman. Clustering and preferential attachment in growing networks. Physical review E, 64(2):025102, 2001.
  • [16] G. Salton and M. J. McGill. Introduction to Modern Information Retrieval. McGraw-Hill, Inc., New York, NY, USA, 1986.
  • [17] B. Zhou, X. Xia, D. Lo, and X. Wang. Build predictor: More accurate missed dependency prediction in build configuration files. In Proc. 2014 IEEE 38th Annual COMPSAC, pages 53–58, Washington, DC, USA, 2014. IEEE.
  • [18] R. Terra, J. Brunet, L. Miranda, M.T. Valente, D. Serey, D. Castilho, and R. Bigonha. Measuring the structural similarity between source code entities. In 25th International SEKE, pages 753–758, 2013.
  • [19] G. Forman. An extensive empirical study of feature selection metrics for text classification. J. Mach. Learn. Res., 3:1289–1305, March 2003.
  • [20] D. Le and N. Medvidovic. Architectural-based speculative analysis to predict bugs in a software system. In Proceedings of the 38th International Conference on Software Engineering Companion (ICSE ’16), pages 807–810, Austin, TX, USA, 2016.
  • [21] T. Zimmermann and N. Nagappan. Predicting defects using network analysis on dependency graphs. In Proceedings of the 30th ICSE, pages 531–540, New York, NY, USA, 2008. ACM.
  • [22] P. Bhattacharya, M. Iliofotou, I. Neamtiu, and M. Faloutsos. Graph-based analysis and prediction for software evolution. In Proceedings of the 34th ICSE, pages 419–429, Piscataway, NJ, USA, 2012. IEEE Press.
  • [23] V.H. Nguyen and L.M.S. Tran. Predicting vulnerable software components with dependency graphs. In Proceedings of the 6th MetriSec, pages 3:1–3:8, New York, NY, USA, 2010. ACM.
  • [24] A. Aryani, F. Perin, M. Lungu, A. Naser Mahmood, and O. Nierstrasz. Predicting dependences using domain-based coupling. J. Softw.: Evol. Process, 26(1):50–76, 2014.
  • [25] F. Arcelli Fontana, J. Dietrich, B. Walter, A. Yamashita, and M. Zanoni. Antipattern and code smell false positives: Preliminary conceptualization and classification. In SANER, pages 609–613. IEEE, 2016.
  • [26] S. Nagrecha, N. V. Chawla, and H. Bunke. Recurrent subgraph prediction. In Proc. of the 2015 IEEE/ACM Int. Conf. on Advances in Social Networks Analysis and Mining 2015, ASONAM ’15, pages 416–423, New York, NY, USA, 2015. ACM.