MASARYK U N I V E R S I T Y FACULTY OF INFORMATICS Al-based Anti-patterns Detection in Java Software Enterprise Development Master's Thesis MARTIN PROCHÁZKA Brno, Spring 2026 MASARYK U N I V E R S I T Y FACULTY OF INFORMATICS Al-based Anti-patterns Detection in Java Software Enterprise Development Master's Thesis MARTIN PROCHÁZKA Advisor: doc. Bruno Rossi, PhD Department of Computer Systems and Communications Brno, Spring 2026 Declaration Hereby I declare that this paper is m y original authorial work, which I have w o r k e d out o n m y o w n . A l l sources, references, and literature used or excerpted d u r i n g elaboration of this work are properly cited and listed i n complete reference to the due source. D u r i n g the preparation of this thesis, I used the following A I tools: • Grammarly for grammar check and improving my writing style, • GitHub Copilot for faster code, test writing and documentation. I declare that I used these tools i n accordance w i t h the principles of academic integrity. I checked the content and took full responsibility for it. Martin Procházka Advisor: doc. Bruno Rossi, P h D iii Acknowledgements I w o u l d like to express m y sincere gratitude to my advisor, Bruno Rossi, for his time, guidance, and valuable insights, which greatly contributed to the completion of this thesis. I w o u l d also like to thank m y family for their continuous support, patience, a n d encouragement throughout m y studies. iv Abstract Software quality is often negatively affected by the presence of antipatterns i n codebases. They represent suboptimal solutions that often lead to maintainability scalability and performance problems. These issues are more important i n enterprise software development. This work aims to extend J E N A (Java Enterprise Analyzer), introduced i n previous theses. J E N A is a static analysis tool that detects anti-patterns i n Java Enterprise software using rule-based detectors. This w o r k adds the ability to detect enterprise anti-patterns using machine learning solutions. We also introduce a new, refactored version of the tool, better deployment and infrastructure for the machine learning evaluation. The new version of J E N A is called Java Enterprise Anti-patterns Detector ( J E A D ) . The machine learning detectors implemented i n J E A D were evaluated on open-source projects. The results show that they have great potential for the detection. In some cases, they generalise better across codebases without requiring m a n u a l threshold adjustments typical of rule-based detectors. But compared to them, they require greater effort for training and deployment, increasing the time needed for analysis. Keywords Static analysis, Java, Spring Boot, Machine Learning, Artificial Intelligence, Software Quality, Software Architecture v Contents 1 Introduction 1 1.1 Objectives of the Thesis 2 1.2 Thesis Structure 2 2 Software Quality, Patterns and Anti-Patterns 3 2.1 Software Quality 3 2.2 Software Quality Factors 4 2.3 Software Metrics 5 2.4 Patterns i n Software Development 6 2.5 Software Anti-patterns 7 2.6 Code Smells and Anti-patterns 9 2.7 Usage of A I / M L i n Software Quality 10 2.7.1 Automatic Code Refactoring 10 2.7.2 Explainable Software Defect Prediction 12 3 Related Works 14 3.1 Enterprise Anti-patterns Catalogue 14 3.2 State of the A r t i n Anti-pattern Detection 15 3.2.1 Rule-based Approaches 16 3.2.2 Machine Learning Approaches 18 4 JEAD: Java Enterprise Anti-patterns Detector 23 4.1 Previous Version - J E N A . V 2 23 4.1.1 Space for improvements 24 4.2 Machine Learning Detectors 25 4.2.1 Architecture 26 4.2.2 Code Extractors 26 4.2.3 Inference Queues 28 4.2.4 Communication w i t h Inference Server 29 4.2.5 Y A M L Configuration 30 4.3 Additional Work 31 4.3.1 L o m b o k Support 32 4.3.2 Dependency Updates & Migration to Java 25 . . 34 4.3.3 Improved Project Structure 35 4.3.4 Enhanced Deployment 36 vi 5 Inference Server 38 5.1 Existing Solutions 38 5.2 Architecture 39 5.3 Project Structure 41 5.4 Public g R P C Interface 41 5.5 Models Root Folder Structure 42 5.6 Models Loading and Communication 44 5.7 Dockerization and Deployment 45 5.8 Future Work 46 6 Detecting anti-patterns U s i n g M a c h i n e Learning M o d e l s 47 6.1 Anti-patterns Selection Motivation 47 6.2 (DI8) G o d Dependency Injection Detection 48 6.3 (SER1) Multi-service Detection 50 6.4 ( T E C H _ D E B T ) Technical Debt Detection 52 7 JEAD Evaluation on O p e n Source Projects 56 7.1 Project Selection Criteria 56 7.2 Evaluation Strategy 57 7.3 (DI8) G o d Dependency Injection Anti-pattern 58 7.4 (SER1) Multi-service Anti-pattern 59 7.5 ( T E C H _ D E B T ) Technical Debt Anti-patterns 61 7.6 Validity and Applicability of the Models 63 7.7 Threats to Validity 66 8 C o n c l u s i o n 67 Bibliography 69 A Java Enterprise Anti-pattern Catalogue 78 A . l Dependency Injection 78 A.2 Persistence Layer 80 A.3 Service Layer 81 A.4 M o c k i n g 82 A.5 Security 83 A.6 Technical Debt 84 B JEAD Project Structure 86 v i i C Running the Evaluation D Architecture Diagrams E Electronic Attachment List of Tables 2.1 Examples of code metrics used for code smell detection [9] 6 2.2 Examples of Artificial Intelligence (AI) usage i n Software quality 13 3.1 O v e r v i e w of anti-patterns used i n this thesis, based on M i c k a [4] and extended w i t h Technical Debt 15 3.2 Related rule-based anti-pattern detection tools 19 3.3 Related machine learning anti-pattern detection approaches 22 4.1 J E A D architecture concerns description 27 4.2 List of selected updated dependencies 35 5.1 Existing Inference Server solutions 39 6.1 Overview of Machine Learning ( M L ) anti-patterns detectors w i t h technologies used 48 6.2 Projects used for technical debt model fine-tuning . . . . 54 7.1 Confusion matrix of DI8 anti-pattern detection per project 59 7.2 DI8 anti-pattern detectors performance measures comparison (project K l a w ) 59 7.3 DI8 anti-pattern detectors performance measures comparison (project Apollo) 60 7.4 Confusion matrix of SER1 anti-pattern detection per project 61 7.5 SER1 anti-pattern detectors performance measures comparison (project K l a w ) 61 7.6 SER1 anti-pattern detectors performance measures comparison (project Apollo) 62 7.7 True and False positives statistics of T E C H _ D E B T model . 63 7.8 T E C H _ D E B T m o d e l performance on test dataset during training 64 ix List of Figures 4.1 J E A D Machine Learning Detection Flow 25 4.2 Structure of the J E A D zip package 37 5.1 Structure of the Inference Server project 41 5.2 Example of models root folder structure 43 5.3 Simplified architecture of Inference Server w i t h models root folder 44 6.1 Multi-service detector machine learning pipeline 52 D . l System-level diagram of J E A D architecture 89 D.2 Component-level diagram of J E A D architecture 90 D.3 Component-level diagram of Inference Server modular architecture 91 x 1 Introduction Every codebase ever written contains many patterns. Patterns clarify h o w components interact, m a k i n g it easier for developers to collaborate and understand the system better. They also facilitate easier system refactoring while aiming to minimise the necessity for such changes. [1]. These patterns are considered good practice. However, many developers work on a codebase over its lifetime, so it might be touched by developers w i t h different areas of expertise and seniority. Lack of codebase overview, knowledge, or experience may result in the creation of patterns that might be considered poor design decisions or bad practices. Such decisions might lead to reduced maintainability, scalability, and extendibility of the system and also have a significant impact on software quality. They can be easier to implement and use in the short term, but harder to maintain i n the long term - we can consider such patterns anti-patterns [2]. Such patterns can be used i n high-level architectural decisions as well as i n smaller-scale decisions, for example, at the class level. Enterprise development primarily includes large-scale applications used by large companies, so the anti-patterns may appear at all levels of system design. To mitigate the risk of introducing anti-patterns in enterprise applications, it is necessary to use an analysis tool that helps software engineers discover them. This tool, called J E N A (Java Enterprise Analyzer), was introduced i n the thesis Catalogue of AntiPatterns in Java Enterprise Development [3] and then improved i n the following work Anti-patterns Detection in Java Software Enterprise Development [4]. Those theses also introduced a catalogue of Java enterprise anti-patterns describing 28 bad practices divided into 5 groups. J E N A is a static analysis tool that takes source code as input, parses it into an Abstract Syntax Tree, and extracts code metrics or patterns. They are then evaluated against statically defined thresholds in the configuration file. If a value exceeds defined thresholds or does not meet the condition, it is presented to the end user as an issue (detected anti-pattern). Such a rule-based approach might lead to many false positives and cannot dynamically adapt to the specific codebase. 1 i . I N T R O D U C T I O N 1.1 Objectives of the Thesis This thesis aims to analyse the feasibility of using machine learning to detect Java Enterprise anti-patterns. The machine learning models could potentially help mitigate the problems mentioned i n the previous paragraph. They c o u l d improve detection by learning dynamic thresholds for code-metric-based anti-patterns, understanding the semantics of the text to detect anti-patterns based on method names, or finding semantic patterns i n the code, for example, TODO-like com- ments. The primary goal is to identify multiple anti-patterns and develop a prototype of M L models to detect them. The thesis introduces a refactored version of J E N A . V 2 that adds compatibility w i t h M L detectors. With that, we present a simple and lightweight solution for deploying models. In the end, the thesis presents an evaluation of M L models on open-source projects, comparing them w i t h rule-based detectors. 1.2 Thesis Structure Firstly, Chapter 2 discusses topics i n software quality, anti-patterns, and the use of A I i n software quality. Then, Chapter 3 briefly summarises the Enterprise Anti-pattern Catalogue, the current state of the art, and solutions for utilising machine learning models for detection. Chapter 4 introduces a new version of J E N A , called J E A D , that allows sending code snippets to machine learning models for evaluation. It also introduces new features, such as Project L o m b o k support [5], and improved deployment to enhance the user experience. Chapter 5 presents a lightweight service for deploying machine learning models for inference with a modular and plugin-based architecture. Chapter 6 shows three prototype models trained to detect three anti-patterns. Each anti-pattern is detected using a different type of model and approach. Last but not least, Chapter 7 presents the evaluation results for the M L models on two open-source projects, with a clear overview and comparison w i t h rule-based detectors. 2 2 Software Quality, Patterns and Anti-Patterns This chapter summarises basic terms i n software quality. First, it discusses h o w software quality is defined, the quality models, software metrics, design patterns, and how to recognise anti-patterns. The last section discusses the use of A I i n software quality w i t h multiple examples of state-of-the-art work i n this area. 2.1 Software Quality There is no single definition of the term software quality. Gaffney [6], one of the first researchers to discuss software quality, defines it as a reproducible mathematical measure composed of various software characteristics. The "goodness" or "badness" of the measure is defined by pre-established thresholds. Software metrics can tell how reliable and maintainable the software is. They can also reveal flaws i n the development process - for example, when the metric like test coverage is low, it can mean that the process places very little emphasis o n writing new tests. The quality of the software does not consist only of measurable metrics. A recent study among Google employees [7] presents the theory that quality is not just about metrics; it comprises four distinct, interconnected types of quality. Those types include: Process quality It refers to the quality of the development processes. Google's theory is that a high-quality software product starts w i t h a high-quality development process. This can include comprehensive testing, code reviews, a n d effective planning. Code quality The Google developers described the code quality as "the ease of working w i t h a n d understanding the code". The easier it is to w o r k w i t h code, the lower the developer's mental overhead w h e n reading it. Thus, it can lead to increased maintainability, readability, developer 3 2. SOFTWARE Q U A L I T Y , PATTERNS A N D A N T I - P A T T E R N S velocity, and overall product quality. This is the primary quality aspect on w h i c h this thesis w i l l focus. System quality The system quality refers to the "quality as the business sees it". It often refers to metrics such as performance, security, outages, and the product's behaviour i n the production environment. It is a challenge to measure this type of quality, since events like outages or security incidents are rare - there might not be enough data to statistically prove improvements or deterioration. Product quality This type of quality is primarily defined as "how the customer experiences it". It refers to the product's usability, reliability, and end-user experience. 2.2 Software Quality Factors M c C a l l et al. defined one of the first software quality factors [8]. They define a factor as "a condition or characteristic that actively contributes to the quality of the software". The factors might include developers, users, and business needs. They divided factors into multiple groups, some examples are: • correctness - satisfaction of requirements, • maintainability - effort to fix errors i n the code, • reusability - the program can be used i n other applications, • testability - effort required to test if the p r o g r a m does its i n tended function, • usability - the user's effort to enter inputs and interpret outputs of a program. 4 2. SOFTWARE Q U A L I T Y , PATTERNS A N D A N T I - P A T T E R N S Each factor has assigned criteria, w h i c h are attributes b y w h i c h the factor can be identified - for example, factor efficiency includes criterion storage efficiency defining the m i n i m u m storage requirements d u r i n g a particular operation. Each criterion includes quantitative metrics. In the case of storage efficiency, one metric is the storage requirement for the system to be allocated. This hierarchical structure defines a comprehensive framework for software quality metrics i n relation to quality factors. 2.3 Software Metrics Software metrics are often used to measure the quality of software systems. This allows managers, stakeholders and developers to track quality and a quantitative overview of their system's complexity. They are also often used to detect particular code smells or anti-patterns. There are multiple studies a n d standards defining them. Palomba et al. [9] introduce a b u g prediction framework based o n the code smells detected b y the code metrics. Table 2.1 shows an example of code metrics used for the detection of particular code smells. Based on the metrics and code smells detected, they assess their severity to predict software bugs. Chidamber a n d Kemerer created one of the most famous metric sets, k n o w n as C K metrics [10]. They focus on measures i n object-oriented systems and include 6 metrics that measure class, inheritance, and coupling complexity. There are also more straightforward metrics, such as the number of methods and fields i n a class, the number of classes, and the number of levels i n the class hierarchy [11]. Each metric can capture different details of the code structure and complexity, and might be used to measure different aspects of the code. Even standards from the ISO family define some sets of metrics. For example, the ISO/IEC 9126 [12] family of standards divides software metrics into internal and external. External metrics measure software behaviour during system use and can be used during the testing and operations phases of the product lifecycle. Otherwise, internal metrics are typically used during the development stage. The metrics are divided into categories like Security metrics, Usability metrics, M a i n tainability metrics, etc. Each category has its representative i n both 5 2. SOFTWARE Q U A L I T Y , PATTERNS A N D A N T I - P A T T E R N S Table 2.1: Examples of code metrics used for code smell detection [9] Metric Description Used for Access To Foreign Data (WMC) Changing Classes (CC) Changing Methods (CM) Lines of Code (LOC) McCabe Cyclomatic Complexity (CYCLO) Number of Accessor Methods (NOAM) Weight of Class (WOC) The number of attributes from unrelated classes accessed by accessor method. Number of classes which calls measured method Number of methods which call measured method Number of lines of codes of method / class Number of linearly independent paths in a method. The number of getter and setter methods. The number of public methods divided by the total number of public members. God Class Shotgun Surgery Shotgun Surgery Brain Method Brain Method Data Class Data Class external and internal metrics. The ISO/IEC standard is today replaced by the I S O / I E C 25002:2024 family I S O / I E C 25002:2024 [13], w h i c h defines software quality requirements and their evaluation. 2.4 Patterns in Software Development Patterns are the basic elements of software design. In general, they describe h o w components are structured, h o w they communicate, how they distribute responsibilities, and what their roles are [1]. They serve as the building blocks of software components. Developers often need to solve problems they have experienced i n the past, but at the core, the solutions are very similar. Software patterns abstract those solutions and make them reusable for similar cases. Patterns also define implementation skeletons that help developers to easily implement the desired functionality. Nevertheless, they help to build larger software systems with complex architectures. Software patterns are often grouped into 3 categories: design, architectural patterns, and idioms [14]. 6 2. SOFTWARE Q U A L I T Y , PATTERNS A N D A N T I - P A T T E R N S D e s i g n patterns are often used w i t h object oriented design; we are talking about relationships between classes or objects [1]. The application of design patterns is "lower level" than that of architectural patterns, and their application does not often influence the architecture of the entire system, only a minor part (subsystem) [14]. Architectural patterns commonly serve as foundational structural templates for software architectures. They have a significant impact on h o w subsystems are structured and h o w they interact. These patterns might define the internal structure (architecture) of an individual subsystem (folder structure, responsibilities,...), or the composition and structure of multiple related subsystems. The selection of appropriate architectural patterns is crucial for achieving a maintainable and scalable design for software systems [14]. Idioms, unlike the previous two categories, are specific to a particular programming language. The context of one idiom might be shared across languages, but the actual implementation details are different. They represent the lowest level patterns [14]. A m o n g other things, their purpose is to define best practices for writing clean, dynamic code specific to the p r o g r a m m i n g language. A n example of such an idiom could be the naming convention - i n Java, method names are often written i n lowerCamelCaseO, but i n Python, words are separated w i t h underscores - method name (). 2.5 Software Anti-patterns The anti-patterns are i n the core very similar to the software patterns described i n the previous section. The main difference is that patterns are often considered best practices - they often bring many benefits, such as improved maintainability, scalability, and code quality. In contrast, anti-patterns are bad practices. According to Brown et al. [2], it is "a c o m m o n solution to a problem that generates decidedly negative consequences". W i t h frequent use of anti-patterns, software quality may decrease, code may become unreadable or untestable, and any change to the codebase may require significant effort. A n anti-pattern can be created from a properly used design pattern, but i n an unsuitable place i n the code, due to the programmer's lack of knowledge 7 2. SOFTWARE Q U A L I T Y , PATTERNS A N D A N T I - P A T T E R N S or experience [2]. The anti-patterns can also be divided into design and architectural levels, similarly to the patterns mentioned in Section 2.4. The introduction of anti-patterns into the code base is almost never accidental. It often arises from uninformed decisions, time pressure, or a lack of knowledge or experience. William et al. identified multiple mistakes that cause the creation of anti-patterns [2]: • Haste - m a k i n g hasty decisions often leads to trade-offs and a decrease i n software quality. The typical victim is testing. • A p a t h y - often causes us unwillingness to solve k n o w n problems and bugs. Not all problems have straightforward solutions, but a passive approach to solving them might lead to the adoption of improper solutions. • Narrow-mindedness - refusing to learn new best practices and standards. Developers often continue to work the same way they have for years, showing little willingness to adapt or change their approach. • Sloth - a sign of a developer w h o consistently chooses the first and easiest solution without carefully considering its implications or long-term consequences. • Avarice - architecture complexity often leads to many challenges in maintainability and development of a software system. Under time pressure and fast time-to-market, some development steps might be skipped (such as testing). This can lead to significant problems for the system's future. • Ignorance - defined as "intellectual sloth" - the failure to seek understanding. This results i n people w h o are unaware of h o w to use technology properly. • P r i d e - developers often prefer to invent n e w designs of solutions, instead of reusing existing ones. Such an approach might lead to an increased need for testing and documentation, adding unnecessary complexity. 8 2. SOFTWARE Q U A L I T Y , PATTERNS A N D A N T I - P A T T E R N S Example of Design vs. Architectural Anti-patterns God Class Design Anti-pattern Class with too many responsibilities. It heavily accesses data from other layers, is large and complex, and has very low method cohesion. In a welldesigned system, responsibilities should be uniformly distributed among classes [15]. Big Ball of Mud Architectural Anti-pattern It occurs when there are no defined boundaries between subsystems, with no regulated growth. The overall system's structure is not well defined. One change could break multiple dependent functionalities due to tight coupling [16]. 2.6 Code Smells and Anti-patterns M a n y sources use this term interchangeably. They are tightly coupled, degrade software quality, increase technical debt, and reduce the maintainability of software systems or codebases. But each of them affects software quality at different levels. A c c o r d i n g to Rivera et al. [17], the anti-patterns are defined more on the design level of a software system. They are often categorised as Linguistic Anti-patterns, Software Reuse Anti-patterns, Performance Anti-patterns, Scrum Anti-patterns, Code smells are often defined at the lower, implementation level. They often refer to code structure issues, long methods, database smells, or presentation smells. Code smells can often be eliminated through refactoring, while anti-patterns represent deeper structural problems and may require greater effort to understand and eliminate. But there is no strict difference between those terms, and some anti-patterns (or code smells) may partially belong to both categories. We can demonstrate this interchangeability and no strict difference on the Enterprise Anti-patterns mentioned i n catalogue by Micka [4]. For example, anti-pattern D U O (Long Producer Method) can be seen as a code smell because it indicates method complexity at the i m plementation level. A l s o , the anti-pattern DI8 ( G o d D I Class) mentions the number of injected dependencies - this might belong to both categories, since it can be understood simply as the number of injected classes through the constructor (in other words), w h i c h is 9 2. SOFTWARE Q U A L I T Y , PATTERNS A N D A N T I - P A T T E R N S an implementation-level issue. Or it can be seen as a design-level issue, where responsibility is incorrectly spread across classes, and some classes implement more functionality than they should. 2.7 Usage of AI/ML in Software Quality This section describes various approaches and tools that leverage multiple forms of A I to improve the quality of software systems. Traditional rule-based systems make decisions based on predefined thresholds. Therefore, they lack automatic adaptability to new environments and the ability to improve over time. A I models can learn dynamic thresholds, adapt to changes, and perform more complex tasks. The following text highlights only a few topics, while the actual scope of A I application i n software quality is considerably broader. In the context of this thesis, we use traditional supervised learning algorithms, such as Random Forests. For semantic understanding and classification, we use Natural Language Processing ( N L P ) processing models like CodeBERT. These models belong to the Deep Learning category of Machine Learning. For clustering, we use unsupervised machine learning algorithms like H D B S C A N . Since all of these algorithms and approaches fall under the category of Machine Learning in Artificial Intelligence, we refer to the term simply as M L for clarity. 2.7.1 Automatic Code Refactoring Refactoring is the process of i m p r o v i n g an existing codebase. It is a series of small modifications to existing code whose primary purpose is to improve the quality of the refactored system by enhancing its structure, testability, performance, or readability. Refactoring should preserve the code's functionality. It is essential to have refactored code covered by tests, so that developers minimise the risk of breaking functionality and introducing new bugs. The most common is manual refactoring. The developer performs it manually using code suggestions and tools from the Integrated Development Environment (IDE), the compiler, and unit tests, which can be r u n after each refactoring step. This approach might require a high effort, especially in large enterprise-grade systems. Also, use the 10 2. SOFTWARE Q U A L I T Y , PATTERNS A N D A N T I - P A T T E R N S static analysis and refactoring assistance tools integrated into the IDE (such as IntelliJ I D E A ) . Those tools are quite powerful but do not offer a deeper semantic understanding of the code or the ability to identify its performance issues [18]. Refactoring for performance optimizations To improve automatic refactoring capabilities, Polu [18] suggested an A l - d r i v e n refactoring framework for performance optimisations. The tool utilises multiple methods and approaches. First, it parses the code into an Abstract Syntax Tree (AST), so the A I model can extract structural and semantic information (e.g., function calls,...), and then converts it to a G r a p h Neural Network ( G N N ) representation. Using transformer-based models, such as CodeBERT, it analyses the code semantics and provides refactoring suggestions. In the end, it runs the performance evaluation on both the original and refactored code to see the results. The resulting framework successfully optimises the refactored code w i t h 98% accuracy. Refactoring using Large Language Models (LLMs) The use of L L M s shows great potential in code refactoring tasks. H o w ever, they still introduce many hallucinations and need h u m a n intervention or verification of the suggested output. Cordeiro et al. [19] conducted research on current opportunities and limitations. They identified current approaches that use L L M s , such as Test-Driven Development ( T D D ) and automated code refactoring. Regarding refactoring, models integrated into IDEs often suggest changes while the developer is d o i n g the manual w o r k based on the suggestions, because they lack contextual understanding. The mentioned studies also show that the models perform m u c h better w h e n the prompt includes an explanation of refactoring categories, w h i c h the m o d e l should look for. In the end, the study suggests that a closer integration of automated test generation is needed to improve L L M refactoring capabilities. Developers can generate tests based on the modified code when no existing test case is present. Another research focus should be on context-enriched prompts to provide more context for refactoring 11 2. SOFTWARE Q U A L I T Y , PATTERNS A N D A N T I - P A T T E R N S code into L L M s . They suggest including more details i n the prompts, such as a guide to remove specific code smells. 2.7.2 Explainable Software Defect Prediction Before releasing a software system to production, stakeholders want to be sure it is reliable, well-tested, and has few weaknesses. A method of software defect prediction (SDP) enables analysis of the codebase, pinpointing weak points and helping allocate appropriate testing re- sources. Gecer et al. [20] developed a framework that uses M L models to predict software defects. Since M L models are often 'black boxes" w i t h limited transparency, stakeholders may not always trust their outputs. Therefore, they used a method called Explainable A I (XAI). It enables m o d e l interpretability and reasoning about the model's internal structures. Global explanations enable visualisation of the importance of features and the overall model's logic, while local explanations provide insights into the concrete decisions made (for example, why the following module was marked as defective). The whole framework utilises multiple M L models (random forests, naive Bayes, neural networks, and multilayer perception), trained on a large benchmark data set containing 21 software metrics. The solution helps developers, managers, and stakeholders prioritise the efforts needed for defect mitigation, together w i t h explanations of concrete metrics that influence quality. 12 2. SOFTWARE Q U A L I T Y , PATTERNS A N D A N T I - P A T T E R N S Table 2.2: Examples of A I usage i n Software quality Topic Technology Al-driven refactoring framework AST, G N N , CodeBERT for performance optimisations leveraging neural networks and transformer-based models [18]. Research suggestions on using L L M , TDD, IDE integration LLMs in refactoring and development, mainly using patterns like TDD [19]. Using Explainable AI models to XAI, Random forests, Naive Bayes, increase trust in the models by metrics stakeholders during defect prediction [20]. Overview of usage AI in Quality As- LLMs integrated in IDE, D N N , surance for test data synthesis, test N L P case generation, exploratory testing, defect tagging [21]. 13 3 Related Works The first part of this chapter discusses the catalogue of enterprise Java anti-patterns introduced i n the previous thesis [3] [4], providing a clear overview of the included anti-patterns. The second section focuses on state-of-the-art work on anti-pattern detection i n software development. 3.1 Enterprise Anti-patterns Catalogue While many internet sources refer to catalogues of anti-patterns, only a few are related to enterprise development. Previous thesis Catalogue of Anti-Patterns in Java Enterprise Development by Batel' [3] introduced a set of 24 anti-patterns related to enterprise applications i n Java. The catalogue is divided into 5 categories: General Issues, Persistence Layer, Service & facade Layer, Dependency Injection, and REST A P I . The follow-up thesis Anti-patterns Detection in Java Software Enterprise Development b y M i c k a [4] revised the first version of the catalogue. M o r e generic anti-patterns (like unused imports or variables) were removed, while a d d i n g a set of new, strictly enterprise-related anti-patterns. The new version of the catalogue is also divided into 5 categories with a total of 28 anti-patterns. It introduces new categories, such as Security and Mocking, while removing non-enterprise-related categories, such as General Issues or Representational State Transfer (REST) Application Programming Interface (API), from the first version. The catalogue's primary purpose is to help developers learn about them, since those anti-patterns might cause serious performance, maintainability, and security problems. It also serves as a template for a n automatic detection tool called J E A D (formerly called J E N A , introduced i n [3]), w h i c h is capable of detecting these issues using a rulebased approach, and also using machine learning ( M L ) models (see Chapter 4). The brief summary of the catalogue from M i c k a [4] is i n the A p pendix A . This thesis introduces a new category, Technical Debt, which is presented i n Appendix A.6. It also includes a brief analysis of the de- 14 3- R E L A T E D W O R K S Table 3.1: O v e r v i e w of anti-patterns used i n this thesis, based o n M i c k a [4] a n d extended w i t h Technical Debt Service layer SER1 Multi-service • SER2 Tiny service * SER3 The client completes a service * Mocking M O C 1 Final method call with exception MOC2 Constructor call with exception M O C 3 Static Call With Exception MOC4 Inappropriate Method Mocking Security SEC1 Storing Secrets In Insecure Places * SEC2 Disabling CSRF Protection SEC3 Lifelong Access Tokens SEC4 Insecure Default Configuration SEC5 Signing Jwt With Fixed Secret SEC6 Insecure Communication Symbol * indicates anti-patterns detectable by machine learning. tectability of each anti-pattern by M L algorithms i n the context of this thesis. Table 3.1 shows a clear overview of the included anti-patterns. 3.2 State of the Art in Anti-pattern Detection This section describes currently available tools a n d research o n antipattern or code-smell detection i n source code. The literature reviewed primarily covers non-enterprise development research tools, w i t h very few papers focusing o n enterprise development. The majority of tools focus o n detecting more generic anti-patterns (god classes, Dependency injection DI1 Unused injection DI2 Direct container call DI3 Concrete class injection DI4 Open window injection DI5 Framework coupling DI6 Multiple forms of injection DI7 Open door injection DI8 God DI class • DI9 Multiple assigned injections DUO Long producer method * D i l l Intransigent Injection * DI12 Static dependence provider Persistence layer PERI N + l query problem PER2 Dredge • PER3 Crush Technical debt TECH_DEBT1 Self Admitted Technical D e b t * TECH_DEBT2 Commented Out Code * 15 3- R E L A T E D W O R K S large classes,...). The chapter also discusses the differences between rule-based and machine-learning approaches to detection. 3.2.1 Rule-based Approaches The traditional w a y of detecting an anti-pattern is a rule-based approach. Often based on code metrics, together w i t h defined static thresholds. If the threshold is exceeded, the evaluated component (class, method, etc.) is marked as "bad", otherwise as "good". It is often a challenge to define static thresholds, and you need an experienced analyst to analyse them for the specific code metric. A study by Kecia et al. [22] analysed more than 40 open-source Java projects to define reference thresholds for six code metrics. They used statistical methods to find the distributions of each metric between all projects. From that, they defined reference ranges and assigned metric values as "good", "regular", or "bad". For example, for the metric "number of public methods", the good range is 0-10, the regular range is 11-40, and the bad range is greater than 40. This article shows that defining references for a single metric requires significant effort. Incorrect thresholds may lead to many false positives i n detection systems. The following examples present some selected static analysis tools: (1) One of the tools for rule-based analysis is the open source community-driven P M D project [23]. W h i l e its primary focus is detecting Java code smells and anti-patterns, it can also detect issues in 17 other languages. It is built on predefined rules; the base package includes more than 400 built-in rules. For Java, it includes rules for checking code best practices, code style, design, performance, security, etc. Customisation of the rules is done through X M L configuration, where the user can easily modify pre-defined properties for each rule. It also allows the creation of custom rules, which can be implemented using Java code that directly accesses the A S T or as X M L configuration, where A S T nodes are accessed and evaluated via XPath locators. For Java analysis, it uses the A S M framework [24] to construct the A S T by reading bytecode, including runtime bytecode to resolve runtime A P I references. The tool builds a comprehensive abstraction over the A S M framework, w h i c h allows complete A S T traversal using the visitor design pattern. It also includes a set of predefined algorithms to compute code metrics (such as the number of public methods i n 16 3- R E L A T E D W O R K S a class), but the set is very limited. Thanks to this abstraction, it would be possible to create custom rules for detecting anti-patterns i n enterprise development, similar to J E N A . V 2 (see Example 2). However, the custom rules are essentially add-ons to the core system, bundled as JAR files and included i n the P M D classpath, which makes debugging the generated rules m u c h harder. (2) JENA.V2 is a static analysis tool for detecting enterprise antipatterns i n Java. It was developed together w i t h a catalogue (see Section 3.1) i n the Master's thesis of Bate! [3] and M i c k a [4]. It includes issue detectors 19 for anti-patterns listed i n the catalogue. The application uses an interactive C o m m a n d Line Interface (CLI) built w i t h Spring Shell [25] as the Spring Boot application [26]. Since it is a rulebased tool, it provides a JavaScript Object Notation (JSON) configuration to set metric thresholds, regular expressions, and conditions that define rules. The tool also allows configuring w h i c h annotations are used to detect bean classes, for example. This makes it highly customizable and framework-independent. The J E N A does not support adding new detectors v i a plugins, so whenever a new detector is added, the code must be updated. However, it provides a set of interfaces that enable easy extensibility. The tool is primarily intended for manual use via the C L I , so integration into the Continuous Integration / Continuous Delivery ( C I / C D ) pipeline is not straightforward. Additional functionality includes aggregating found issues and tracking the evolution of anti-patterns between project versions. It is built using the Java Parser w i t h the Java S y m b o l Solver [27], enabling proper inference of Java types on the classpath. For proper work, the evaluated application must have exposed dependencies (JAR files). For this purpose, the authors suggest using Maven plugins or Gradle scripts. They also prepared a C L I c o m m a n d that modifies M a v e n Project Object M o d e l ( P O M ) files to include the required plugin. This thesis aims to enhance the tool through machine learning detection, while improving user experience and deployment. (3) SonarQube [28] is the most famous, comprehensive and robust rule-based static analysis tool widely used by the largest software companies. It offers multiple tiers; the basic free community edition allows analysis of 21 languages and frameworks. The language-specific scanner is p r o v i d e d for each language included i n the C I / C D and b u i l d process (for Java as a M a v e n or Gradle plugin). The scanner 17 3- R E L A T E D W O R K S then communicates w i t h the SonarServer, w h i c h provides configurations, plugins, and other parameters needed for the scan. After the scan is completed, the scanner sends the results to the SonarServer, where users can browse an intuitive dashboard that provides statistics, scan history, and issue management. It also provides a configuration of quality gates. They include a set of conditions that the code measures during analysis. Depending on the result, the code passes or fails the quality gate. The quality gate settings are based on overall code statistics, metrics, and code issues. Like P M D , SonarQube also includes a predefined set of checks. The Java sonar scanner [29] includes more than 600 rules, of w h i c h more than 350 are code smells. The built-in checks include a lot of enterprise-level detectors, especially for the Spring framework 1 . C o m p a r e d to the enterprise anti-pattern catalogue (see Section 3.1), it is missing, especially, the persistence layer and technical debt checks, but it includes many similar dependency injection rules. SonarQube supports creating plugins i n Java. For the A S T traversal, it uses Eclipse JDT. The plugins are then deployed to the SonarServer, which provides them to the scanners. Compared to P M D (Example 1) and J E N A . V 2 (Example 2), SonarQube requires a more robust infrastructure, particularly the SonarQube Server component. Alternatively, the cloud-hosted version (SonarCloud) can be used to avoid managing this infrastructure. Additionally, the Community Edition has limited functionality, and a subscription is required to access advanced features and the cloud-hosted version. 3.2.2 M a c h i n e Learning Approaches A l t h o u g h rule-based approaches can sometimes achieve relatively high detection precision, finding the correct metric thresholds can be very challenging. They are also not a good choice for detecting complex anti-patterns i n complex systems. Sometimes it is also necessary to capture the semantics and non-linear relationships between source code features and code smell categories, w h i c h makes it a suitable domain for machine learning ( M L ) algorithms. The most common is binary classification, where models learn code snippets and software metrics associated w i t h labels ("is smell", "is clean") using supervised 1. examples: the optional REST parameter should be an object, field injection should not be used, disabled CSRF protection warning, and many more 18 3- R E L A T E D W O R K S Table 3.2: Related rule-based anti-pattern detection tools Name Purpose P M D [23] Modular rule-based detector built on top of A S M framework, primarily Java. JENA.V2 [4] Rule-based Java Enterprise Anti-pattern detection tool built on top of Java. Symbol Solver. SonarQube [28] Cloud-based enterprise solution for rule-based analysis of source code across various languages. DIAnalyzer [30] Java dependency injection anti-pattern analyser. JDeodorant [31] Eclipse plug-in for code smell detection and refactor- ings. learning techniques. However, M L algorithms also include a lot of complexity and effort. The often-problem is the complex, hidden structure of the models, w h i c h might not be trusted by stakeholders and developers (see Section 2.7.2). Another pitfall is the high effort needed to collect the accurate datasets needed for learning. So, it is questionable whether the effort to train a complex m o d e l is worthwhile. The following paragraphs present a collection of machine learning tools and approaches for anti-pattern and code-smell detection. (1) A l i et al. [32] introduced a novel approach to detect code smells using the relation-aware BERT (RABERT) model. The standard architectures and approaches for natural language and code processing use transformer models, such as CodeBert [33] and GraphCodeBert [34]; however, they do not perform well at capturing structural relations among various abstract components of code. The suggested approach integrates relational embeddings to capture structural dependencies between software metrics. It is especially useful for detecting structural software issues. They created a dataset based on more than 50 open-source projects f r o m G i t H u b , w i t h 20 labelled software complexity metrics, but their research primarily focuses on the Large class code smell2 . A l i et al. conducted a comparative evaluation between transformer-based models and traditional M L techniques (gradient boosting, decision trees,...). A m o n g transformer models, R A B E R T significantly outperformed other BERT-based models w i t h 91% pre- 2. A class accumulates many responsibilities, making it harder to maintain. 19 3- R E L A T E D W O R K S cision but lower recall (53%), resulting i n an F l score of 53%. This means their selected approach is better suited to high-assurance systems, where false positives must be minimised. A m o n g traditional M L techniques, the m o d e l w i t h the highest F l score was Gradient boosting, but it h a d lower precision at 80% - it generated more false positives. They also compared training and inference time, showing that transformer-based models are much slower in both measures. So, classical M L models are better suited for real-time applications. (2) The study by Reis et al. [35] presents an experiment using an approach called Crowdsmelling to collect datasets for training M L models to detect code smells. The experiment took 3 years, d u r i n g w h i c h more than 100 teams w i t h 3 members each classified the presence of 3 code smells (Long M e t h o d 3 , G o d Class 4 , Feature E n v y 5 ) . This resulted in a data set that was used to train 6 M L models. The participants were third-year students in the software engineering course of the bachelor's study program. The p r i m a r y objective of the research was to find out if the C r o w d s m e l l i n g approach is suitable for code smell detection and what is the machine learning model. The results show that the models perform best at finding the G o d Class anti-pattern ( F l score around 80.5% on average across all models), then L o n g M e t h o d (around 76%) and Feature E n v y (around 45%). The authors note that classifying more complex code smells with fewer occurrences yields the worst results (Feature Envy) and that participants tend to follow the advisor's suggestions. Regarding the best model, all of them performed relatively well; the differences were small, but i n most cases the Random Forest model stood out. Regarding Crowdsmelling, the results show that the dataset evolves over time and is improving. The authors summarised the results as promising and are convinced of the feasibility of this approach. (3) H o et al. [36] suggested a novel method for detecting code smells using M L models. They introduced an approach called EnseSmells that combines statistical, semantic, and structural features of code. The approach consists of two main components, the Extractor and the Classifier. The extractor consists of two modules. The first m o d - 3. Complex method implementing more than one functionality. 4. Class with large size, poor cohesion, with many responsibilities. 5. Method, which uses more functionality from other classes than from its own. 20 3- R E L A T E D W O R K S ule is the statistical semantic module, which compares code-language models such as CodeBERT, C u B E R T , and code2vec to create sourcecode embeddings. To derive features from the embeddings, they use their DeepSmells model from previous work [37], w h i c h uses a C o n volutional Neural Network ( C N N ) . The second part is the structural module, w h i c h utilises C K [38] to extract 70 metrics from the code snippets. After preprocessing the metrics, they apply a deep neural network to effectively capture key structural features for code smell detection. The second component, the classifier, combines the vector outputs of both modules i n the previous component using vector concatenation. The result is fed to the deep, imbalanced neural network for classification. Since the classes are imbalanced (more clean snippets than smelly ones), they introduced a sensitivity-weight adjustment to fine-tune the relative importance of the minority class. The results show improvements over existing state-of-the-art models of 6% to 28%, depending on the evaluated code smell. 21 3- R E L A T E D W O R K S Table 3.3: Related machine learning anti-pattern detection approaches Topic Techniques Detection of code smells using BERT models, relational embedrelation-aware BERT and relation dings, Gradient Boosting, Decision embeddings. Comparison with tra- Trees ditional M L techniques [32]. Experiment using the Crowdsmelling, Random Forests, Crowdsmelling approach for Naive Bayes, J48, AdaBoostMl gathering data for datasets to improve the dataset's reliability, focused on multiple code smells [35]. EnseSmells approach combining BERT-based models, code2vec, statistical, semantic and structural C N N , D N N features for detection of code smells. Uses about 70 metrics for detection [36]. WekaNose - machine learning Labeling, Sampling, M L algorithms based tool for detection of code smells. Allows dataset creation and M L models training [39]. Approach for improving M L models performance by detecting code smells using continuous feedback. Results show continuous improvement of the model's reliability [40]. Naive Bayes, Random Forests, Logistic Regression, Code Metrics 22 4 JEAD: Java Enterprise Anti-patterns Detector J E A D , formerly k n o w n as J E N A [3] [4], is a static analysis tool for detecting anti-patterns in Java enterprise development. The detectors are based on a catalogue of anti-patterns (see Section 3.1). This chapter introduces new features and improvements to detection. First, to provide more context, it focuses on the capabilities of the previous version. Then it describes the thesis's primary goal: introducing the possibility of detecting anti-patterns using machine learning models. It includes a description of the architecture, configuration options, and communication with the inference server that hosts the models (see Chapter 5). The last part discusses additional work done besides the primary goal. 4.1 Previous Version - JENA.V2 J E N A . V 2 introduced by M i c k a [4] is a c o m m a n d line interface tool based on the Spring Shell project [25]. The application can be controlled by a predefined set of well-documented commands and their parameters, w h i c h can be entered into the interactive C L I . It allows analysis of a project i n 4 stages: (1) Project preparation is executed using the c o m m a n d prepareProjects. A s a parameter, it takes the target directory w i t h the analysed project. If the project uses the Maven build system, it looks for pom.xml and adds the maven-dependency-plugin to expose J A R dependencies, w h i c h are then scanned by the Java S y m b o l Solver [27]. In Gradle, it appends a script to the build.gradle configuration doing the similar thing. The user then has to manually r u n the project's b u i l d to apply those plugins. (2) Configuration is an optional step. U s i n g the copyConfig command allows exporting the pre-defined configuration to a target path. This configuration can be manually adjusted for the specific project and used as input to the next stages. (3) The parsing and analysis stage is executed using the detectlssues command. Arguments include the project path, the project label, the configuration path, and other settings. It uses the Java Parser and the Java Symbol solver to asynchronously parse the code. The code is parsed into the A S T and each class (represented as ClassOrlnter- 23 4. J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R faceDeclaration) is passed to the detector. Each detector is associated w i t h one IssueCategory (corresponding to the categories i n Table 3.1) and can detect one or more issues i n that particular category. The found issues are then automatically printed as a table i n C L I a n d saved to database. (4) Presentation of results stage can print the results using aggregatelssues command. It takes a project label as an argument and prints a table m a p p i n g issue categories to identify anti-patterns. The data can also be exported i n the C S V format using exportData command. 4.1.1 Space for improvements The current implementation of J E N A .V2 opens a space for multiple i m provements, which can enhance the reliability and precision of the detection and improve the user experience: • J E N A . V 2 currently relies o n rule-based detectors. The primary goal of this thesis is to analyse the possibility of using detectors based o n M L techniques. It could improve the adaptability of detectors across different code bases without requiring adjustments to predefined thresholds. • Support for the L o m b o k [5] library. J E N A . V 2 does not support annotation processors. Since detection sometimes depends on the presence of components i n the code, this can lead to many undetected issues. • J E N A . V 2 lacks a deployment package. A t the moment, w h e n a user wants to r u n J E N A , they have to b u i l d the project f r o m scratch or r u n it i n an IDE. This really reduces the user experience w h e n using the tool. • Since J E N A . V 2 was developed almost 2 years ago, many dependencies are outdated. Also, the dependency structure i n Maven's pom.xml is incorrect. Projects using Spring Boot [26] do not share a common dependency management approach, which may lead to incompatibilities. • The project is composed of multiple sub-projects. They do not share the same naming conventions and are not correctly defined 24 4. J E A D : JAVA E N T E R P R I S E A N T I - P A T T E R N S D E T E C T O R as Maven modules. It is also unclear which sub-projects provide important functionality and w h i c h are just test fixtures. 4.2 Machine Learning Detectors The main objective of this thesis is to improve J E A D with the detectors using M L models and to analyse its reliability and usability i n terms of enterprise anti-patterns. The current version relies only on static rules defined i n the configuration. The main problem with static rules is their inability to capture the semantic and structural features of code. They rely solely on a static threshold for a particular code metric (or regular expression,...), saying whether this code snippet is an antipattern or not. Machine learning models can eliminate those problems, but they may involve longer analysis times and greater effort to build (see Section 3.2). This chapter outlines the architecture of machine learning detectors, covering everything f r o m configuration to code snippet extraction, and ultimately addressing communication w i t h the dedicated server (see Chapter 5) that facilitates the deployment of machine learning models. Figure 4.1 presents the simplified detection flow for machine learning detectors. M o r e details about each component are provided i n the system-level diagram of the J E A D components shown in Figure D . l . Source code JEAD o - > • O O — o o o o AST Parsing - J < List of issues Feature extraction Evaluation ^ Inference Server ^ Figure 4.1: J E A D Machine Learning Detection Flow 25 4. J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R 4.2.1 Architecture The architecture requirements primarily include independent parsing of code snippets and asynchronous queues for each model, so that calls to the Inference Server do not block parsing or processing of other code. Table 4.1 summarises basic architecture concerns related to the requirements. The M L detectors work alongside the rule-based detectors, but they have different source root callback functions that are passed to the Java Parser and called for each parsed compilation unit. The M L callback is located i n the MachineLearningDetectorCallback. Once the detectlssues c o m m a n d is executed, it loads the configuration for M L models (see Section 4.2.5) and delegates responsibility to MachineLearningDetectorCombiner. Sends each parsed Java class to the code extractors (see Section 4.2.2). Once the code extractor returns the m o d e l w i t h extracted code features, it passes them to the InferenceQueue (see Section 4.2.3), which asynchronously sends the code features to the Inference server for inference. W h e n the response w i t h labelled snippets is returned, the results for each model are stored i n its inference queue. W h e n all code is processed, the handler for the detectlssues command stops all inference queues and synchronously waits for all found issues. The issues are then processed and merged w i t h the issues from rule-based detectors, w h i c h are running i n parallel. The simplified schema of the M L issue detection process and architecture is shown in Figure D . 2 . 4.2.2 Code Extractors Since the M L models are trained o n code features (code comments, code metrics,...), not on entire code snippets, there must be a mechanism for extracting those features from the code. For this purpose, we introduced code extractors. Since the project uses the Spring Framework [41], the code extractors are implemented as Java classes registered as framework component beans. A l l code extractors must implement interface CodeExtractor, w h i c h defines methods Stream e x t r a c t ( . . .) and S t r i n g g e t l d e n t i f i e r ( ) . The generic type parameter defines the model class, w h i c h is returned by the extract method. Each m o d e l must implement the EvaluationModel interface 26 4. J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R Table 4.1: J E A D architecture concerns description Concern Description Interoperability Uses gRPC interface to communicate with Inference Server. Configurability Settings for each model can be configured independently. The parameters for queues and evaluation are configurable. Modularity Code is easily extensible (through predefined interfaces) and easy to implement new functionality. Performance Handles more models simultaneously. Each model has a separate asynchronous queue. Timeliness Might introduce processing delay due to batch processing of items in the queue. to identify the code snippet's position i n the code during evaluation. The extract method is called by the MachineLearningDetectorCombiner w i t h A S T of the parsed class. The method processes the p r o v i d e d class and returns a stream of models, since a single class may include multiple code features. The getldentifier method returns a string, which defines a unique identifier of a particular extractor used in the configuration to map the extractor to a concrete m o d e l name and detector (see 4.2.5). It is also important to be able to b u i l d a training dataset for M L models. We introduced the extractCode C L I command, w h i c h allows extracting code features from a specified project using code extractors. The c o m m a n d also allows specifying the output type, w i t h the user able to choose between J S O N and J S O N Lines (JSONL). The set of output formats can be easily extended v i a the Output!vr-matter interface. The parameters of the commands are as follows: • configPath (c): optional, path to the configuration file with static rules, • projectPath (p): path to the target project, • format (f): name of the output formatter, • extractor (e): name of the code extractor, 27 4. J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R • outputPath (o): path to the output file, • settings (s): optional, additional options for code extractors. Listing 4.1: Example usage of the extractCode command e x t r a c t C o d e -p / h o m e / m a r t i n / s o u r c e - p r o j e c t - f j s o n l -e g o d - m e t r i c s -o /home/mart i n / g o d - d i - m e t r i c s . j s o n l 4.2.3 Inference Queues Each configured M L m o d e l has its o w n inference queue. Their purpose is to asynchronously process extracted code snippets a n d send them to the inference server i n batches. Such an approach significantly improves performance b y creating an asynchronous gap between code extraction and inference. Since inference might be performanceintensive and time-consuming, a synchronous approach w o u l d block extraction until the item is processed. It w o u l d also create a network overhead, because each extracted item w o u l d have to be sent sepa- rately. Inference queues are managed by the InferenceQueueHolder, which is responsible for the start and termination. Each queue has a configurable batch size and batch period (in milliseconds). The queue itself uses ScheduledExecutorService w i t h a fixed rate set to the batch period. This means that the batch is processed every X milliseconds as defined in the configuration. Executor service uses virtual threads to improve performance a n d minimise platform thread overhead [42]. Once the code extractor processes the code and returns the evaluation model, it is wrapped i n the Inferenceltem record, w h i c h provides a unique I D a n d a m a p p i n g callback that maps the item evaluated by the M L model to the Issue entity. This Inferenceltem is then passed to the InferenceQueueHolder, w h i c h selects the appropriate InferenceQueue according to the M L model name for scheduling. Once a thread in the queue is awakened at the batch period, it checks whether the queue has enough items (the batch size). If so, it empties the queue and forwards the batch to the inference server (see Section 4.2.4). 28 4. J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R W h e n the code extractors are finished, the InferenceQueueHolder terminates all queues. The termination sequence shuts d o w n the executor service and flushes the queue i n a synchronous loop, waiting until the queue is empty a n d all items are processed. In this state, the batch size parameter is not considered because the queue might not be full. 4.2.4 Communication with Inference Server Since all M L models trained as part of this thesis were done using the Python language, it is necessary to deploy them somewhere. For this purpose, we introduce the Inference server, which, thanks to its m o d ular architecture, enables efficient model deployment (see Chapter 5 ) . The server provides gRPC A P I [43] through which the J E A D sends extracted code features for inference. The inference server returns either probabilities or labels as numeric values (depending o n the selected model). The probabilities are then evaluated against the thresholds defined i n the Y A M L configuration and converted into issues. J E A D uses dependencies s p r i n g - g r p c - s p r i n g - b o o t - s t a r t e r [44] to autoconfigure the needed beans and protobuf-maven-plugin [45] to generate a client stub f r o m the protocol buffer definition. The p l u gin then generates InferenceServiceGrpc service, whose blocking stub is registered as a bean i n GrpcClientConfig configuration class. The main communication logic is placed i n the InferenceService class. The method dolnference takes as a parameter a batch of items for i n ference and the name of the model. First, to create an anti-corruption layer, it maps the internal models to the g R P C m o d e l s 1 using InferenceMapper. The resulting g R P C model includes just a list of evaluation items (ID and content, w h i c h represent the extracted code features). Then, it sends the blocking request to the inference server. W h e n the response arrives, it maps the response payload back to the original internal Inferenceltem model, including all additional metadata that are not sent over gRPC. This is possible thanks to a unique ID added to each evaluation item. 1. This ensures the gRPC models are not used internally in the JEAD. In case of API change, only the mapper is adjusted. 29 4. J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R Listing 4.2: Example of model configuration i n the application.yaml i n f e r e n c e : m o d e l s : - ^ c o m m e n t s - m o d e l m o d e l - n a m e : c o m m e n t s - m o d e l b a t c h - s i z e : 30 b a t c h - p e r i o d : 100 4.2.5 Y A M L Configuration The Y A M L configuration allows configuring the connection U R L to the Inference server, specifying the M L models the J E A D should use for inference, and pairing the models w i t h M L detectors that evaluate labels against predictions returned by the inference server. The configuration is located i n d e t e c t o r / s r c / m a i n / r e s o u r c e s / a p p l i c a t i o n . y m l or, i n a ZIP bundle, i n conf i g / a p p l i c a t i o n . yml, together w i t h other Spring Boot [26] properties. The application needs to be restarted after each configuration change. Here are the examples of the properties related to the M L and inference can be configured: (1) Models configuration object includes defining model-name, b a t c h - s i z e and b a t c h - p e r i o d (those properties are mentioned i n Section 4.2.3). The model's name serves to pair the m o d e l w i t h the one deployed on the Inference server (unique identifier). The object must also have a defined anchor so that it can be referenced later. Listing 4.2 shows an example of a configuration for one model. (2) Detector configuration first includes the detector-name property, but it does not have any special function; it is just for better readability of the configuration. Then, property e x t r a c t o r refers to a previously defined model. The extractor's name must match the identifier of a source code extractor (see Section 4.2.2), w h i c h w i l l be used for extracting the code features sent to the Inference server. The model property must include an alias of the anchor defined i n the i n f erence. models object (an alias always starts with * symbol). The last property is evaluations w h i c h is described i n point 3. (3) Evaluations configuration defines the labels and thresholds that are returned from the Inference server. For each label-name, they 30 4. J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R Listing 4.3: Example of M L detector and evaluation configuration in the application, yaml i n f e r e n c e : d e t e c t o r s : - d e t e c t o r - n a m e : t e c h n i c a l - d e b t e x t r a c t o r : comments m o d e l : * c o m m e n t s - m o d e l e v a l u a t i o n s : - l a b e l - n a m e " t e c h n i c a l _ d e b t " t h r e s h o l d : 0.8 i s s u e - t y p e S E L F _ A D M I T T E D _ T E C H N I C A L _ D E B T - l a b e l - n a m e " c o d e _ c o m m e n t ii t h r e s h o l d : 0.8 i s s u e - t y p e C0MMENTED_0UT _C0DE define t h r e s h o l d property. W h e n the returned prediction is equal to or greater than the prediction threshold, it produces the issue with the defined issue type i n i s s u e - t y p e property. The issue type must be one of the values defined i n IssueType enum. Listing 4.3 shows an example of an evaluation configuration. (4) Inference Server configuration allows the configuration of the U R L to the g R P C interface of the r u n n i n g Inference server i n stance i n the address property. Then, the enabled property allows us to define whether the M L inference and detectors should be used. If disabled, only rule-based detectors are used. See Listing 4.4 for an example. 4.3 Additional Work The following section introduces support for a tool called Lombok [5], w h i c h was not supported i n the previous thesis and limited J E A D ' s usage i n the newer projects. The following section then continues with a description of an enhanced project structure to simplify future development, as well as the creation of a deployment package that 31 4. J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R Listing 4.4: Example of Inference server configuration i n the application, yaml s p r i n g : g r p c : c l i e n t : c h a n n e l s : i n f e r e n c e - s e r v e r : a d d r e s s : l o c a l h o s t : 8081 i n f e r e n c e : e n a b l e d : t r u e bundles the entire application and releases it as a self-contained ZIP file. 4.3.1 Lombok Support The L o m b o k [5] library provides a set of annotations to omit boilerplate code. W h e n the annotation is used (for example, ©NoArgsConstructor), it uses the annotation processor to generate the code for a noargument constructor i n the class where the annotation is used. A n other example is annotations such as ©Getter or ©Setter, which generate getters and setters for fields in the particular class. This generated code is not visible i n the .Java source files that are used by the Java Parser to compose AST. This lack of actual source code in the .Java files prevents the Java Parser/Java Symbol Solver from correctly analysing the source code, resulting i n imprecise metrics for evaluating anti- patterns. For this purpose, the binary (.jar file) of the Lombok dependency includes Delombok [46]. It is a primitive C L I application that takes a directory containing source code and a path to the output directory as input. Then it generates Java source code that resolves all Lombok annotations, enabling full static analysis. For this purpose, we introduced J E A D ' s M a v e n and Gradle plugins, w h i c h can be included i n the analysed project. These plugins are included using the prepareProject c o m m a n d i n the b u i l d description 32 4. J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R scripts (pom.xml or build.grutile). D u r i n g the project build, the plugin delomboks the code and creates a separate folder containing the resolved code. W e also moved the functionality of maveri-deperidericy - p l u g i n , introduced i n the previous version [4], to the newly introduced plugins. Its purpose is to expose all .jar dependencies so the Java Symbol Solver can correctly resolve all types of third-party l i braries. This eliminates the need for multiple included b u i l d plugins in the target projects. The prepareProject command modifies the b u i l d configurations and includes b u i l d plugins as defined i n application.yaml. There is a preconfigured, correct version of the J E A D plugins that matches the current version of the application bundle (see Section 4.3.4). The versions are resolved at b u i l d time using maven-resources-plugin [47], w h i c h replaces placeholders w i t h the concrete value defined i n the pom.xml by the automated G i t H u b Workflow. The workflow also u p loads the plugins to G i t H u b Packages [48], so the plugins can be automatically d o w n l o a d e d a n d d o not need to be added manually. Both plugins use the j e a d - p l u g i n - c o r e library, which includes executors for both tasks/goals. The project structure overview is shown i n the A p p e n d i x B. Both plugins are built w i t h Java 11 compatibility, so they can also be used i n older projects. Listing 4.5: Example usage of the prepareProjects command p r e p a r e P r o j e c t s - d / h o m e / m a r t i n / a n a l y s e d - p r o j e c t JEAD Maven Plugin The M a v e n p l u g i n is included i n the tag of pom.xml i n the target project. It includes two goals: delombok, copy-dependencies , which are by default bound to the package phase. Both goals include configurable parameters that can be used to customise behaviour, but the default configuration should be sufficient in most cases. The following steps should be applied to successfully prepare a M a v e n project for analysis: 1. Execute prepareProjects command (see Listing 4.5). 2. R u n mvn clean package i n the target project. 33 4. J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R 3. Check folder target/dependencies for exposed .jar files a n d src-delombok for resolved L o m b o k source code (if L o m b o k is used). J E A D Gradle P l u g i n The prepareProjects c o m m a n d includes generic b u i l d script blocks in the build.gradle. However, manual adjustments may be required, since the correct position of the included script may differ between projects, and cannot be determined automatically. Similar to the Maven plugin, it includes two tasks: jeadCopyDependencies and jeadDelotnbok. But none of them is b o u n d to any other Gradle task, so they have to be executed manually. The following steps should be applied to successfully prepare a Gradle project for analysis: 1. Execute prepareProjects command (see Listing 4.5). 2. R u n gradle b u i l d i n the target projects. 3. In case of some errors, manually fix the build.gradle a n d r u n again. 4. R u n gradle jeadCopyDependencies to expose jar files. 5. R u n gradle jeadDelombok (only if the L o m b o k is used). 6. Check folder target/dependencies for exposed .jar files a n d src-delombok for resolved L o m b o k source code (if L o m b o k is used). 4.3.2 Dependency Updates & M i g r a t i o n to Java 25 Since J E N A . V 2 [4] was developed almost 2 years ago, it included multiple outdated third-party dependencies. Also, we updated from Java 17 to Java 25 to support the latest language features. D u r i n g the update, w e also fixed and improved the structure of the pom.xml files. Some dependencies, like Spring Boot, were not handled correctly There was a missing spring-boot-dependencies entry i n dependencyManagement section, w h i c h enables correct automatic versioning of dependencies under the Spring Boot framework [26]. We also had to 34 4. J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R Table 4.2: List of selected updated dependencies G r o u p I D Artifact O l d v . N e w v. org. springf ramework.boot spring-boot-starter 3.1.1 3.5.10 org.mockito mockito-coref l 5.2.0 5.21.0 org.postgresql postgresql 42.6.0 42.7.9 net.bytebuddy byte-buddy& - 1.18.4 org.hibernate hibernate-corec 6.2.7 6.6.41 tools.jackson.core jackson-databind 2.15.2 3.0.4 a. Changed from mockito-inline to mockito-core. b. Added to preserve mocking support. c. Removed explicit dependency. By default included in Spring Boot. update the Maven and Gradle wrappers to their latest versions due to incompatibility w i t h Java 25. The following table lists some selected updated dependencies. Not all dependencies were updated to their latest versions due to instability or incompatibilities. One of the examples is the Spring Boot framework. A t the time the thesis was being w o r k e d on, version 4 h a d just been released. Some dependencies, like Spring Shell [25] included some bugs and major changes preventing the smooth use of the application. 4.3.3 Improved Project Structure The structure of JENA.V2's sub-projects was not ideal and was harder to understand. This thesis slightly improved the structure by ensuring naming consistency, a correct Maven project structure, and automatic build of Gradle projects via Maven. The visualisation of the new structure is i n the A p p e n d i x B. The J E A D includes several test fixture projects2 . They allow running unit tests for rule-based detectors against real projects. We moved them into a subproject called t e s t - f i x t u r e s , w h i c h makes the structure clearer and separates non-production projects. The new build plugins are then located inside b u i l d - p l u g i n s subproject. They share common Maven properties and a few dependencies 2. antipatterns, authorization-server, power-mock-usage and test-gradle-project 35 4. J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R that are not relevant to the detector. The overall structure of M a v e n modules was improved, so it is possible to build or install all projects from the root folder using mvn clean i n s t a l l . Since two projects use Gradle 3 , we also added to both projects Maven's pom.xml w i t h logic that executes Gradle tasks specific to each M a v e n phase. 4.3.4 Enhanced Deployment To provide users w i t h a better experience, we decided to create a package that includes the built jar application, the configuration files, Docker Compose files required to r u n the Inference Server (see Section 5.7), and a comprehensive R E A D M E file w i t h all the necessary instruction for r u n n i n g the application. The bundle is published as a compressed zip file. The user can just d o w n l o a d this bundle, u n pack it, and r u n the prepared jar archive directly, or start the Docker containers without b u i l d i n g the whole application. The creation of the bundle is done by the maven-assembty-plugin [49], w i t h the descriptor located i n the M a v e n sub-project assembly (see the project structure i n A p p e n d i x B). The structure of the zip package is shown on Figure 4.2. This runtime assembly package is automatically built using G i t H u b Actions [50]. The action is triggered w h e n a Git tag is created whose name starts w i t h the letter "v", for example, vl.0.1. The action performs the following steps to b u i l d and package the application: 1. Extract the version from the Git tag and set it for Maven projects. 2. R u n tests and install the J E A D M a v e n and Gradle plugins. 3. Publish J E A D M a v e n and Gradle p l u g i n artefacts to G i t H u b Packages [48]. 4. R u n tests for J E A D detector. 5. Package the J E A D detector into the zip archive. 6. Create a G i t H u b Release w i t h the version and u p l o a d the zip archive to it. 3. test-gradle-project and jead-gradle-plugin 36 4- J E A D : JAVA ENTERPRISE A N T I - P A T T E R N S D E T E C T O R JEAD/ .... config/ Root directory application.yml Spring Boot config Detection config Environment variables f o r Docker GPU-compatible Compose f i l e ...Compose f i l e without GPU comp .. JAR archive with JEAD DETECTOR README with instructions 1 conf iguration.j son .env compose.gpu.yaml .... compose.yaml detector.jar _README.md Figure 4.2: Structure of the J E A D zip package Since the detector requires a database and optionally an Inference Server, Docker [51] and Docker Compose [52] must be installed, or an equivalent alternative must be used. The Appendix C describes the necessary steps to r u n the detector and evaluation. Those steps are also included i n the README. md file i n the J E A D runtime package. 37 5 Inference Server This chapter describes the purpose of the Inference server and its technology background. First, it summarises existing solutions and w h y we have decided to create a custom one, then it describes the architecture and the technologies used. The following part discusses the project structure, the public interface, and, ultimately, the Dockerization and deployment of the server, including Graphics Processing Unit ( G P U ) compatibility. The purpose of the Inference server is to enable the deployment of M L models v i a a unified A P I . Since most A I development is done i n Python, mainly due to its simplicity and strong library support. The J E A D detector is written i n Java, and it w o u l d not be possible to call Python functions easily and reliably. D u e to these facts, we decided to create Inference server, a modular g R P C server that allows hosting M L models in separate subprocesses with independent access to G P U cards, deployable in Docker [51] containers. The M L models are delivered outside of a Docker image i n a pre-defined file-based structure called "models root". This allows for small, modular Docker images. A user can deploy the model by adding a folder containing a defined Python worker file. Then, after proper configuration, the J E A D sends the extracted code snippets to the Inference server. The server forwards snippets to the specified model and returns the response w i t h predictions, w h i c h are then further processed by the J E A D . 5.1 Existing Solutions There are multiple robust and ready-to-use solutions. But most of the solutions were too complicated for our simple use case. The requirements for the Inference server are: • Small Docker Image, • modular A P I , preferrably using g R P C , • modular (plugin-based) architecture that allows adding models without server code modification, 38 5- INFERENCE SERVER Table 5.1: Existing Inference Server solutions Name FOS Runtimes1 REST gRPC Image Size2 NVIDIA Triton / / / / - / > 4 GB Inference Server [53] TensorFlow / / / 200 M B / 2 GB Serving [53] MLServer [54] / / / / - / > 4 GB KServe [55] / / / / - / > 250 M B • free and open source, • can host models built by different Python libraries, • allows running easily o n the user's machine. Probably all solutions presented in Table 5.1 could be used to infer J E A D ' s code snippets, but are often not well-suited for deployment on a local machine or produce very large Docker images. We decided to build our o w n solution tailored to our simpler use case. The solution can also be used across different use cases and integrated with various applications. Some of the concepts were inspired by N V I D I A Triton Inference Server [53]. C u s t o m solution also allows us to customise the A P I and use cases according to our needs. 5.2 Architecture A s a p r i m a r y structure of the project, we decided to use a layered architecture. It brings the benefits of simplicity, l o w development effort and separation of concerns. Since the project is relatively small at the moment, we use 3 layers. In a typical application, the bottom layer is the database layer. But since our Inference server does not communicate w i t h the database, but communicates w i t h M L models, 2. Support of more Python libraries/runtimes for model definition. 2. C P U / G P U compatible image size. We always show the minimum size found; it often depends on the selected runtime. 39 5- INFERENCE SERVER it is a bit special and differs from the standards. The layers and their responsibilities are: 1. Presentation Layer - g R P C interface (see Section 5.4), 2. Business Layer - business logic and validation, models storage, loading, and unloading M L models, 3. M o d e l s layer - communication w i t h deployed models (see Section 5.6). The architecture leverages Dependency Injection principles [56]. We do not use any framework; w e manually create services during application startup and manually inject dependencies into the constructors of dependent objects. This way, we ensure testability by unit tests of all dependencies, since they can be easily mocked. Thanks to this, w e implemented a set of unit and integration tests to ensure the server's reliability. The application is written i n P y t h o n language. To improve performance, w e use an asynchronous p r o g r a m m i n g model, primarily using the asyncio library [57]. Thanks to this, Python can handle m u l tiple tasks i n the event loop simultaneously, significantly improving throughput. However, the m a i n bottleneck of the Inference server is always the M L m o d e l , because models often require substantial resources to provide fast inference, including G P U resources. The asyncio library is also widely used for communication w i t h M L models, where Futures enable handling multiple commands i n parallel. Without that, only one command could have been processed at the same time (more on this i n Section 5.6). The project and its dependencies are managed by the Poetry [58]. It allows us to define pyproject.toml file w i t h a list of all dependencies, together w i t h their versions a n d other metadata. After installation, the produced lock file can be committed to Version Control System (VSC) to ensure that all dependencies have the same versions across different environments. 40 5- INFERENCE SERVER inference-server/ proto/ Protobuf definitions folder .env.example ....Template f o r of environment variables 0 — compose. l o c a l .yaml Compose f i l e f o r l o c a l run compose.yaml Compose f i l e f o r l o c a l run c Dockerfile Docker container build specification poetry.lock Poetry lock f i l e poetry.toml Poetry project specification REAEDME.md README f i l e with instructions a. Should be copied and renamed to .env file before starting the server locally. b. Builds the project using Dockerfile c. Fetches the latest Inference Server from Docker Hub. Figure 5.1: Structure of the Inference Server project 5.3 Project Structure Figure 5.1 provides a general overview of the project's structure, without details about the source code structure, w h i c h is omitted for simplicity. The source code folder follows a package-by-layer structure. 5.4 Public gRPC Interface The Inference server uses the g R P C [43] interface o n the presentation layer. g R P C was chosen mainly for its ability to provide typesafe clients and stubs, as well as its lightweight binary format. O n the server side, we use the P y t h o n library grpcio [59]. The server stub is generated from the protobuf definition i n the proto folder at the project root. To generate, the script scripts/generate-server.sh must be r u n after i n stalling the Poetry project. The interface n o w includes 5 endpoints located i n the service called InfereceService: • ServerReady for checking whether the server is online, • ModelReady for checking whether the model is ready for inference a n d loaded, • LoadModel to load the specific model, 41 5- INFERENCE SERVER • U n l o a d M o d e l to unload the specific model, • Modellnference to r u n the inference o n the specific model. Currently, only the Modellnference and ServerReady are used from the J E A D detector. The first one mentioned uses the InferenceRequest message as the payload. The Listing 5.1 shows the protobuf description of that message. A s the first parameter, it takes the model's unique name for which inference should be performed. The second parameter is the list of InferenceRequestContent messages. It includes the unique ID of that message (the ID is also returned i n the response, so J E A D can pair the requested code snippet with the inference result). The content includes a string, which is then passed directly to the model's worker. The string typically contains J S O N , which the model can parse. The use of the J S O N format is a trade-off between the truly dynamic structure of the A P I endpoint and lower performance due to parsing, w i t h more overhead than the pure binary format gRPC provides. However, since each model requires different data i n different structures, this seemed to be the optimal solution. Listing 5.1: InferenceRequest message protobuf definition message I n f e r e n c e R e q u e s t { message I n f e r e n c e R e q u e s t C o n t e n t { s t r i n g i d = 1; s t r i n g c o n t e n t = 2; } s t r i n g m o d e l _ n a m e = 1; r e p e a t e d I n f e r e n c e R e q u e s t C o n t e n t c o n t e n t s = 2; } 5.5 Models Root Folder Structure To have a truly dynamic m o d u l a r / p l u g i n architecture, each m o d e l is basically a separate plugin. This p l u g i n structure consists of a set of folders, each containing a specific P y t h o n script. The root folder 42 5- INFERENCE SERVER models_root/ comments_model/ worker.py model/ 1 model.onnx multi_service_model/ worker.py model/ 1 model.onnx requirements.txt requirements.gpu.txt Figure 5.2: Example of models root folder structure is called "models root". It must include two files: requiretnents.txt and requirements.gpu.txt. Both files include Python dependencies i n the Requirements File Format [60]. Those dependency files should include dependencies of all M L models the user wants to deploy. The primary motivation is to split the dependencies of the Inference server itself and those of M L models so they do not conflict. Then, the model's root contains M L models, each i n a separate folder. The name of the folder serves as a unique identifier (name) of the model. Each folder must include a file n a m e d worker.py containing a class n a m e d MLWorker with predefined methods (see Listing 5.2). Then, each folder can contain files and folders specific to each M L model, which are handled by the user b y logic i n the MLWorker class. The Figure 5.2 shows a n example of the models root folder structure. Listing 5.2: MLWorker class template c l a s s MLWorker: def l o a d ( s e l f ) : def u n l o a d ( s e l f ) : def e x e c u t e ( s e l f , d a t a ) : 43 5- INFERENCE SERVER gRPC Interface Inference Server _y worker Manager ) > Socket Client Models Root ' Subprocess 1 ->! /model_l/worker.py Socket Server ' Subprocess 2 -->! /model_2/worker.py i Socket Server Figure 5.3: Simplified architecture of Inference Server w i t h models root folder 5.6 Models Loading and Communication During the server start-up, it checks for the requirements file. Depending on the mode ( G P U or C P U ) , the correct requirements file is chosen. Then, it creates a Python virtual environment and installs the dependencies using pip [61] within it. W h e n the model is loaded, it is started as a separate process within this environment. The process is started using Python's internal subprocess library. It starts the socket_worker.py script, which is shared for all models. This script acts as a socket server, started o n a randomly picked port. The Inference server itself is then a socket client that sends commands over the socket interface to the M L models3 . The Inference server manages connections and processes. Each sent c o m m a n d is w r a p p e d w i t h a request ID, and all p e n d i n g requests are stored i n a dictionary together w i t h Future (from asyncio library [57]), so a response can be processed asynchronously. This also allows processing more requests simultaneously over a single socket stream. Since the socket server script is shared across all models, there must be a way to dynamically load the worker.py script for the concrete model. To achieve this, we utilized importlib package f r o m Python's standard library. It provides utilities to load a P y t h o n script o n a defined path as a module. Once the m o d u l e is loaded, the script has access to the defined MLWorker class, which can be easily instantiated and its methods called. Since the internal socket server script also runs i n the virtual environment, where a user has defined their o w n dependencies, all code 3. There are 3 commands available: inference, load, shutdown. 44 5- INFERENCE SERVER should use only modules f r o m the standard P y t h o n library to avoid conflicts w i t h those dependencies. The diagram i n Figure D.3 shows the server's simplified modular architecture. It includes examples of two deployed M L models. 5.7 Dockerization and Deployment The application is containerised as a standalone without M L models. This allows the creation of small Docker containers. The production container is automatically created using GitHub Actions [50]. The action is triggered w h e n a Git version tag, starting w i t h the letter "v", is committed, for example, vl.0.1. The action first installs the Poetry project a n d then generates the g R P C server stub (see Section 5.4). Then, it runs unit and integration tests. In the end, it builds a Docker image and publishes it to the Docker H u b repository [62]. The J E A D zip package (mentioned i n Section 4.3.4) includes a compose file that downloads the image from a remote repository and runs a local container. There are two compose files: compose.yaml and compose.gpu.yaml. The second is just an extension of the first, which allocates N V I D I A [63] graphics cards to the running container. This means that the G P U compose file cannot be r u n separately. Before starting the container, the zip package includes an .env file w i t h two properties. The property MODELS_ROOT_HOST defines a path to the m o d e l root directory. The property USE_GPU is a boolean that determines whether the Inference server should be started i n GPU-compatible mode and install the model's G P U dependencies. The compose file in the zip package always includes a tag for the correct version of the Inference server compatible w i t h the compiled J E A D detector. The m o d e l root folder must be located o n the host machine. It is then m a p p e d to the container as a volume. W h e n Inference Server creates a virtual environment, it is created inside the model's root folder and populated with the installed dependencies. Note that some dependencies are compiled specifically for a concrete device or operating system, so the virtual environment used when running the server outside a Docker container w i l l most likely not work inside the con- tainer. 45 5- INFERENCE SERVER The A p p e n d i x C includes a guide on how to r u n Inference Server using Docker, including the J E A D detector and running the evaluation. 5.8 Future Work This thesis aimed to create an Inference Server mainly for inference on local environments. Thus, it d i d not implement any security aspects. Future w o r k should focus on securing the g R P C interface using an A P I key included i n the request header. This A P I key w o u l d also be configured in J E A D , and only requests w i t h the correct A P I key would be allowed. If needed, a more sophisticated authorisation mechanism could be considered, for example, permissions to access concrete m o d els bound to a specific A P I key/user. Another security aspect is encrypted communication. A t the moment, the communication between J E A D and the Inference server is not encrypted. The same applies to T C P socket communication between J E A D and M L model workers. Both communication protocols should be secured and encrypted using TLS authentication. The models are automatically deployed w h e n the first request for the concrete model arrives. Or, they can be deployed using a separate endpoint. However, the purpose of deploying each m o d e l separately is to save resources. If a future requirement is to run the Inference server as a "permanent" service, it should include an automatic mechanism to undeploy unused models. The model could be undeployed if it is not used for a period of time. M o r e A P I endpoints could also improve the server's usability. For example, some endpoints listing available or deployed models might be helpful. W i t h this, some standalone C L I application, or another type of User Interface (UI) could be created to provide more control over the Inference server. The U I can also be included i n the J E A D detector C L I . 46 6 Detecting anti-patterns Using Machine Learning Models This chapter describes the process of training M L models to detect enterprise Java anti-patterns. From the catalogue of anti-patterns (see A p p e n d i x A ) , w e selected three anti-patterns suitable for M L detection. Each anti-pattern uses a bit of different detection technology and approach to demonstrate the possibilities. For each model, we discuss an approach to creating the training/fine-tuning data set, a data preprocessing pipeline, training the model, and converting the model to the O N N X format [64]. The O N N X format is a standard representation of M L models. It allows reducing the Python dependencies used for inference, together with a unified A P I for all models to obtain predictions. It also supports hardware acceleration ( G P U ) . Table 6.1 shows an overview of trained anti-pattern detectors together w i t h the technologies used. A l l pipelines used for data preprocessing and training are i n the Poetry training project. Each pipeline is created as a Jupyter Notebook, w h i c h requires m a n u a l execution of each needed block. Training or fine-tuning some models may require a G P U , especially transformerbased models. Some datasets were enhanced w i t h L L M samples, which require an A P I key for access. Datasets are available i n the thesis attachment. 6.1 Anti-patterns Selection Motivation The catalogue of anti-patterns (see A p p e n d i x A ) includes multiple anti-patterns, which are suitable for detection using M L models. The catalogue provides a brief analysis for each suitable anti-pattern. W e selected three of them, each representing a different technique a n d technology used for detection. The purpose of those selected models is to create a proof of concept for M L detection, and to verify that the selected architecture works correctly. The DI8 anti-pattern is a detection technique based on code metrics. The metrics are extracted from the code using J E A D and then passed to a metric-based m o d e l for evaluation. Another category, w h i c h i n - 47 6. D E T E C T I N G ANTI-PATTERNS U S I N G M A C H I N E L E A R N I N G M O D E L S Table 6.1: Overview of M L anti-patterns detectors w i t h technologies used Anti-pattern Technology Python library DI8 G o d D I R a n d o m Forests scikit-learn [65] model SER1 M u l t i Service CodeBERT for H u g g i n g Face embeddings, tranformers [66], H D B S C A N for scikit-learn [65] clustering T E C H _ D E B T CodeBERT for H u g g i n g Face classification transformers [66] eludes the SER1 anti-pattern, involves using unsupervised learning techniques i n w h i c h there is no dataset to learn model-specific patterns, but techniques like clustering are used instead. The last category presented uses a supervised learning approach, based on the semantic analysis of the code (comments). Those categories mentioned i n the previous paragraph represent the most often used M L techniques. There are definitely more techniques and anti-patterns i n which M L learning can improve detection capabilities. For example, a m o d e l can help detect security tokens stored i n insecure locations (SEC1) rather than relying solely on regular expressions. In the case of the D i l l anti-pattern, a m o d e l could help identify computationally intensive services. Then, w i t h the aid of static analysis, the locations where lazy initialisation should be added can be determined. 6.2 (DI8) God Dependency Injection Detection This anti-pattern is purely metric-based. The rule-based detector implemented i n JENA.V2 [4] relies on a number of injected fields evaluated against a static threshold. This static threshold often generalises poorly across projects and may need to be manually adjusted. To fully utilise the model's capabilities, we decided to increase the number of code metrics used for detection, since the number of injected fields alone 48 6. D E T E C T I N G ANTI-PATTERNS U S I N G M A C H I N E L E A R N I N G M O D E L S might not be representative enough. The metrics used for the detection are: • Cyclomatic Complexity calculates the amount of decision logic to express code complexity, • Lack of Cohesion of Methods 5 measures how many methods share access to the c o m m o n attributes, • Number of Object Methods i n the class, • Number of Class Methods i n the class, • Number of Injected Fields injected by some Dependency Injection framework, • Lines of Code. There are many approaches to training models based on metrics. Fontana et al. [67] [68] use R a n d o m Forests, Naive Bayes, J48 or JRip models. A z e e m et al. [69] i n a systematic literature review mention that R a n d o m Forests, together w i t h J48, are selected as the most effective algorithms i n multiple studies. W e decided to use R a n d o m Forests, primarily for its good balance between performance and resource heaviness. It also has good support i n the scikit-learn library [65]. We trained a R a n d o m Forest m o d e l for a binary classification problem, where label 0 represents a clean code snippet and label 1 represents a snippet containing an anti-pattern. Dataset One possibility to obtain the dataset is to use the J E A D code extractor to extract code metrics from various open-source projects. But this w o u l d include processing many open-source projects to get a representative number of code metrics. Since code-metrics datasets are relatively c o m m o n , w e used the open-source Classes and Metrics dataset (version 3.2.2024) [70]. It includes more than 48 metrics from 1,000 G i t H u b repositories w i t h 532,000 Java classes. The dataset uses a folder structure. Each project i n this dataset has a folder containing C S V files. Each C S V file includes data for 49 6. D E T E C T I N G ANTI-PATTERNS U S I N G M A C H I N E L E A R N I N G M O D E L S a particular metric. Since this structure w o u l d be too complex for labelling, we created a custom script to extract those metrics into JSONL, where each J S O N line represents a Java class and all required metrics. To label the snippets, we used a combination of automatic labelling and manual inspection of samples. Automatic labelling was performed using a custom script, w h i c h defines "extreme" values for each metric. For example, if the number of object-oriented methods is greater than 50, the provided code snippet w i l l most likely be an anti-pattern. This helped us reduce manual labelling effort, but of course, it could introduce some biases. To minimise bias as much as possible, we used a r a n d o m sampling approach for manual inspection. Snippets that were not labelled by this automatic approach were labelled manually. To make working w i t h J S O N L and C S V files easier and more unified, we utilised the Pandas library [71]. Training For training the R a n d o m Forests model, we use the scikit-learn l i brary [65]. First, the prepared dataset is loaded into a DataFrame using the Pandas library. We then split the dataset randomly into training and test sets, allocating 20% to the test set. For the actual training, we use RandomForestClassifier, w h i c h handles the training automatically. Then, we convert the trained m o d e l to the O N N X standard to simplify deployment. For this purpose, we use a separate library called skl2onnx [72]. The output is a single file containing the model in the desired format. 6.3 (SER1) Multi-service Detection The Multi-service detector is a bit different from the other two. To create this detector, we d i d not train any model; instead, we utilised existing algorithms and models. Micka [4] defines the SER1 Multi-service anti-pattern as a service w i t h many unrelated methods using completely different types. The rule-based detector for this anti-pattern uses only the number of methods, compared against a static threshold, to determine whether it is present. 50 6. D E T E C T I N G ANTI-PATTERNS U S I N G M A C H I N E L E A R N I N G M O D E L S We took the concept of detecting this anti-pattern more from the developer's point of v i e w than f r o m a code-metrics perspective. Developers often detect this class by analysing the semantic meaning of method names and the types methods take as arguments or return. W h e n a class has many semantically unrelated methods, it is often marked as an anti-pattern1 . Sivakumar et al. [73] used CodeBERT and CodeT5+ transformer models to generate embeddings. After post-processing i n the dimensional reduction algorithm and clustering, they are able to capture semantic similarity and visualise similar solutions i n the software projects. To perform a semantic analysis of the method, we extract method signatures from the tested classes using the J E A D extractor, generate token embeddings and apply a clustering algorithm to find the number of clusters. The number of clusters can indicate whether there are any semantically unrelated groups of methods. The M L detector uses CodeBERT [33] to generate high-dimensional token embeddings from method signatures. Each method signature is represented as an array of vectors (one vector per token). To obtain a vector representation for each sentence, we apply the mean pooling technique. Most clustering algorithms do not work well w i t h highdimensional data (CodeBERT embeddings have 768 dimensions), so we perform dimensionality reduction using U M A P [74]. The resulting vector includes about 50 dimensions, w h i l e preserving most of the semantic-related vectors. In the end, we use the Hierarchical DensityBased Spatial Clustering of Applications with Noise ( H D B S C A N ) [75] algorithm to perform clustering. It is an extension of the D B S C A N [76] algorithm that allows finding more accurate clusters even w h e n each cluster has a different density. The advantage of both algorithms is that they do not require knowledge of the expected number of clusters, unlike algorithms like K-Means. After we pass dimensionally-reduced embeddings to H D B S C A N , we get an array, where each item represents a cluster number or noise. W i t h that, we can compute the total number of clusters w h i l e ignoring the noise for our application. Then, if the number of clusters is 1. For example, the class CarService includes methods createCar, updateCar, removeCar, but also unrelated methods like startRace, endRace, getRaceTime, which should be most likely moved to RaceService. 51 6. D E T E C T I N G ANTI-PATTERNS U S I N G M A C H I N E L E A R N I N G M O D E L S f \ J E A D Extract Method Signatures \. J Send to Inference Server . J ( ^ C o d e B E R T Signatures to Embeddings v. J Embedding Mean Pooling f \ J E A D Extract Method Signatures \. J Send to Inference Server . J ( ^ C o d e B E R T Signatures to Embeddings v. J Embedding Mean Pooling f / \ J E A D Transform Evaluated Snippets to Issues ^ J -* f > Count Number of Clusters and Eevaluate V J f ^ H D B S C A N Clusterization of Embedding Vectors V J r -\ U M A P Dimensional Reduction of Vectors J / \ J E A D Transform Evaluated Snippets to Issues ^ J f > Count Number of Clusters and Eevaluate V J ^ f ^ H D B S C A N Clusterization of Embedding Vectors V J r -\ U M A P Dimensional Reduction of Vectors J Figure 6.1: Multi-service detector machine learning pipeline greater than 2, we mark the class as an anti-pattern. This threshold was deducted and fine-tuned during evaluation o n multiple projects. The threshold 1 seemed too strict, and the pipeline consistently identified more false positives. We also ignore classes w i t h fewer than 10 methods. In such cases, the clustering algorithm lacks sufficient samples to correctly identify clusters. Figure 6.1 shows a visualisation of the whole pipeline. 6.4 (TECH_DEBT) Technical Debt Detection The Technical Debt detector is the only of the three M L detectors that is not implemented as a rule-based detector, because this anti-pattern was added to the catalogue i n this thesis and thus not implemented w i t h other rule-based detectors i n J E N A . V 2 . Technical debt refers to suboptimal solutions deliberately introduced into codebases, typically when there is time pressure to deliver functionality, and the team agrees to implement workarounds. There are many types of technical debt, but we focus only o n Commentedout C o d e and Self Admitted Technical Debt (SATD), w h i c h indicate that some functionality requires future attention. L i et al. [77] published an approach leveraging a BERT-based deep learning approach to detect SATD. They used code comments, commit messages, p u l l request comments, and issues to create a dataset for training a BERTbased model. M a h m o o d [78] introduced an approach using CodeBERT [33] to detect various types of inline code comment smells, including commented-out code, and compared the results w i t h other M L techniques. The CodeBERT model significantly outperforms other techniques. 52 6. D E T E C T I N G ANTI-PATTERNS U S I N G M A C H I N E L E A R N I N G M O D E L S We decided to fine-tune one CodeBERT model for both tasks using a multi-label classification approach. Dataset We used the J E A D code extractor to manually extract comment codes from the open-source project. Table 6.2 presents all the projects that were used to create dataset. There are three types of Java comments JavaDoc, Line comment and Block comment. The JavaDoc a n d Line comments are pre-processed i n following ways. (1) JavaDoc comments are separated into two parts: the description and tags. One separate comment snippet is created from the description. Another comment snippets are created for each JavaDoc tag. This helps reduce the length of separate comments, because JavaDoc comments always contain a lot of information. A l s o , the semantic meaning is often slightly different between the description and each tag. (2) Line comments are merged. W h e n multiple consecutive lines contain the Java Line comment, they are merged into a single comment. Line comments are often used instead of block comments because developers can select multiple lines a n d use a shortcut to create line comments. This results i n the larger "block" of line comments. W e squash comments because such blocks can often include semantically relevant information. The dataset was then manually labelled. It includes about 3,000 samples per class. Clearly, most of the classes were for "clean" comment labels, so we used random undersampling to balance the data set. We also used L L M s models to generate artificial samples and variations from examples i n open-source projects. 20% of the dataset is used for testing, a n d the remaining 80% for training. Fine-tuning The fine-tuning of the m o d e l is done using the HuggingFace [66] library. It includes a comprehensive set of utilities to easily download, fine-tune, and save M L models from their library. Before running the training script, w e preprocessed each comment b y a d d i n g a special token representing the comment type (JavaDoc, Block, or Line) at 53 6. D E T E C T I N G ANTI-PATTERNS U S I N G M A C H I N E L E A R N I N G M O D E L S Table 6.2: Projects used for technical debt model fine-tuning Project Name C o m m i t Hash Source Apache Hive d89f7c55 [79] Apache Tomcat cl6254d [80] ThingsBoard 73a60d3 [81] PA165 projects" - [82] a. Set of 30 projects from the PA165 course fought on Masaryk University in Brno. Source code is not publicaly available. the beginning. This way, the m o d e l can learn differences between individual types. For example, JavaDoc comments may include H T M L or M a r k d o w n code, whereas other types cannot. The special tokens are also passed directly to the model as an argument. The Listing 6.1 shows an example of how comments should look w h e n passing to the model. Since we fine-tuned the model w i t h this format, it must also be used at inference time. Listing 6.1: Example of comments w i t h special tokens [JAVADOC] J a v a D o c Comment [ L I N E ] L i n e Comment [BLOCK] B l o c k Comment After such preprocessing, each comment is tokenised using the related tokeniser. Each transformer-based model available on HuggingFace has its o w n tokeniser, which is included with the model, ensuring compatibility. The tokenised inputs are then passed to the Trainer A P I , w h i c h handles the training and all related operations. Training is carried out i n three iterations (epochs). Fine-tuning is performanceintensive, so a G P U is highly recommended. Otherwise, the time required for fine-tuning can be long. After training, the model is exported to the O N N X format [64]. During inference, the model needs a G P U card for faster evaluation. It can also r u n i n Central Processing Unit ( C P U ) mode, but performance is significantly influenced. For inference, we use onnxruntime [83] library. After passing the comment snippets to the O N N X session, it returns 54 6. D E T E C T I N G ANTI-PATTERNS U S I N G M A C H I N E L E A R N I N G M O D E L S probabilities. They are then sent back to the J E A D , where evaluated against probability thresholds defined i n the configuration. Based on this, J E A D creates issues if needed. 55 7 JEAD Evaluation on Open Source Projects This chapter presents the results of the J E A D evaluation on opensource projects. The first chapter discusses the selection criteria for open source projects used for evaluation. The second part describes the steps for preparing the target projects, analysing them, and processing the results. The evaluation focuses mainly on machine learning models (see Section 6) integrated into the J E A D , compared to the rulebased detectors introduced i n the J E N A . V 2 [4]. The last section discusses threats to the evaluation's validity, including limitations of the thesis, dataset size, and reproducibility. The goal of the evaluation is to demonstrate that the selected architecture and machine learning models are comparable to rule-based detection. For evaluation, we only use the machine learning models we mentioned i n 6.1. If the model has an equivalent rule-based detector, we show the comparison to demonstrate the differences and the ability to detect anti-patterns correctly. Other rule-based detectors are omitted, since this thesis introduced only minor changes and the results w o u l d not a d d additional value compared to the evaluations in previous works [3] [4]. 7.1 Project Selection Criteria The m a i n criterion for the selected project is its size, w h i c h should allow m a n u a l inspection of classes to manually label the reference dataset. Then, the J E A D issue-detection results w i l l be evaluated against this g r o u n d truth. Thanks to that dataset, we w i l l be able to b u i l d a confusion matrix, enabling us to calculate more detailed metrics for evaluating the model's performance. This approach is used only for models that detect class-level SER1 and DI8 anti-patterns. The M L model for T E C H _ D E B T w o u l d require manual examination of all comments i n the respective codebase, potentially resulting i n hundreds or thousands of samples. In contrast, the project should not be small, as anti-patterns like SER1 are more likely to emerge i n larger codebases. Projects are searched on G i t H u b . They have to be written i n Java using the Spring Boot Framework. We are also searching for actively 56 7- J E A D E V A L U A T I O N O N O P E N S O U R C E PROJECTS maintained projects (with the latest commits not older than 1 month) that support at least J D K 17. This should, at least partially, ensure that the projects are up to date and use the latest practices i n Java enterprise software development. Because J E A D is highly configurable, using the Spring Boot framework is not strictly required. However, its default configuration is tailored for Spring Boot, w h i c h is also currently the most commonly used web framework in the Java ecosystem. The last condition is that the selected projects should include at least some representatives from each anti-pattern mentioned in the evaluation section. The selection of projects is relatively limited, likely due to the proprietary nature of enterprise-grade software. According to the previously mentioned criteria, we selected two projects: • K l a w [84], • A p o l l o [85]. 7.2 Evaluation Strategy A s mentioned in the previous chapter, we manually labelled a groundtruth dataset for both projects to evaluate DI8 and SER1 models. This allows us to b u i l d a confusion matrix1 [86] for both M L detectors and also rule-based detectors. The confusion matrix is used primarily in M L applications to evaluate classifiers, but since rule-based detectors are also classifiers, we can use it to compare the performance of both approaches. Comparing both approaches allows us to evaluate differences and compare the previous version, J E N A . V 2 , w i t h J E A D . From the metrics, we w i l l focus on [86]: • Precision, • Recall, • F l score, • Macro average for each measure. 1. The matrix is composed of True Positives (TPs), False Positives (FPs), True Negatives (TNs), False Negatives (FNs). 57 7- J E A D E V A L U A T I O N O N O P E N S O U R C E PROJECTS In real-world scenarios, the clean code samples occur m u c h more often than anti-pattern samples. A s a result, our ground-truth dataset is highly imbalanced, w i t h the majority of samples being clean and only a few being anti-pattern samples. The most informative metric is the M a c r o F l score. The F l score is the harmonic average of Precision and Recall. The macro F l score is the average of the scores for both classes (in binary classification), mitigating the imbalance of the classes by giving equal weight to each class [86]. For the T E C H _ D E B T model, we provide a confusion matrix computed during training (evaluated on the test partition of the dataset), along w i t h the metrics presented earlier. To illustrate the difference between training metrics and a sample i n an open-source project, we count TPs and FPs and present the results i n percentages. Due to the large number of comments i n the projects, creating a ground-truth dataset w o u l d be a high effort w i t h little benefit. 7.3 (DI8) God Dependency Injection Anti-pattern The results for this model show that the success rate of detecting an anti-pattern varies from project to project. For K l a w [84], the model successfully detected one more anti-pattern sample than the rulebased detector, but produced more FPs. O n the other hand, rule-based detectors detected more positive samples i n the A p o l l o [85], again producing almost 2 times more FPs. The confusion matrix is presented in Table 7.1. According to the performance measures presented i n Table 7.2 and Table 7.3, both approaches are very comparable and yield similar results, as the F l scores i n each project are similar across the two detection strategies. The average precision and recall metrics show that the M L approach generalises and adapts across different code bases, as the difference between those metrics across projects is lower than for rulebased approaches. This means that anti-patterns detected i n the Apollo project are more closely aligned w i t h the defined static threshold than in Klaw, leading to more positive items being detected. This threshold can, of course, be adjusted through configuration, w h i c h is not possible for the M L model. O n the contrary, the m o d e l uses more metrics to decide whether the provided class is an anti-pattern, w h i c h might 58 7- J E A D E V A L U A T I O N O N O P E N S O U R C E PROJECTS explain better generalisation across codebases. In conclusion, based on these results, it is not possible to say w h i c h approach is generally better, mainly because the number of anti-patterns i n both projects was low, but M L models slightly outperform i n terms of stability. Table 7.1: Confusion matrix of DI8 anti-pattern detection per project Project Approach TP T N FP F N Total K l a w M L 4 85 3 7 99 K l a w Rule-based 3 87 0 8 99 A p o l l o M L Rule-based 6 9 150 144 7 13 3 0 166 166 Table 7.2: DI8 anti-pattern detectors performance measures comparison (project K l a w ) A p p r o a c h Anti-pattern Precision Recall Fl-score Items Clean code 0.92 0.97 0.94 92 M L DI8 code 0.57 0.36 0.44 7 macro average 0.75 0.66 0.69 99 Clean code 0.92 1 0.96 96 Rule-based DI8 code 1 0.27 0.42 3 macro average 0.96 0.64 0.69 99 7.4 (SER1) Multi-service Anti-pattern A s presented i n the confusion matrix (Table 7.4), the M L approach dramatically outperforms the rule-based detector i n FPs. It appears that the static threshold based o n the number of classes can detect most positive issues, but also produces many FPs. O n the contrary, the M L approach, which is based on the semantic clustering of method 59 7- J E A D E V A L U A T I O N O N O P E N S O U R C E PROJECTS Table 7.3: DI8 anti-pattern detectors performance measures comparison (project Apollo) A p p r o a c h Anti-pattern Precision Recall Fl-score Items Clean code 0.99 0.96 0.97 153 M L DI8 code 0.46 0.67 0.55 13 macro average 0.72 0.81 0.76 166 Clean code 1 0.92 0.96 144 Rule-based DI8 code 0.41 1 0.58 22 macro average 0.70 0.96 0.77 166 names (see Section 6.3), was not able to detect all cases and missed more cases than the rule-based approach. The results are a bit different from project to project. According to the F l score, the rule-based approach has a slight advantage over M L i n Klaw project (see Table 7.5). It detected more and missed fewer classes, but produced more FPs. This implies that the project has fewer classes w i t h more methods, which the static detector marked as issues. But the methods might be more semantically similar, or the difference in vector embeddings might not have been so obvious, so the clustering algorithm d i d not mark them as clustered. For the A p o l l o project (Table 7.6), the rule-based analyser produced a large number of FPs, while the M L detector produced significantly fewer. This means that the A p o l l o project has many classes w i t h more methods marked as issues by the static threshold, but the methods are semantically similar. In conclusion, the M L models show better generalisation across projects but do not detect all possible issues. But it significantly outperforms the rule-based analyser i n producing fewer FPs, especially on project Apollo. This increases the reliability of the produced issues. The rule-based approach is less adaptable to different code structures and w o u l d require adjustments to the static threshold. 60 7- J E A D E V A L U A T I O N O N O P E N S O U R C E PROJECTS Table 7.4: Confusion matrix of SER1 anti-pattern detection per project Project Approach TP T N FP F N Total K l a w M L 3 54 0 6 63 K l a w Rule-based 5 51 3 4 63 A p o l l o M L Rule-based 2 2 99 82 1 18 0 0 102 102 Table 7.5: SER1 anti-pattern detectors performance measures comparison (project Klaw) A p p r o a c h Anti-pattern Precision Recall Fl-score Items Clean code 0.9 1 0.95 60 M L SER1 code 1 0.33 0.50 3 macro average 0.95 0.67 0.72 63 Clean code 0.93 0.94 0.94 57 Rule-based SER1 code 0.625 0.56 0.59 6 Rule-based SER1 code 0.625 0.56 0.59 macro average 0.78 0.75 0.76 63 7.5 (TECH_DEBT) Technical Debt Anti-patterns Since the T E C H _ D E B T 1 and T E C H _ D E B T 2 anti-patterns are implemented using a single M L model, the evaluation is combined into a single chapter. Also, the comparison w i t h the rule-based detector is omitted, because the anti-patterns were defined i n this thesis, and no detector was developed i n J E N A . V 2 [4]. The Table 7.7 shows the model's TPs and FPs statistics, along w i t h the total number of f o u n d issues and the number of available comment samples i n the project. The comment sample does not refer to an individual comment, but rather to the samples after extraction and processing by J E A D (see Section 6.4). The T E C H _ D E B T model achieved high performance during training and evaluation on the test partition of the dataset with an F l score 61 7- J E A D E V A L U A T I O N O N O P E N S O U R C E PROJECTS Table 7.6: SER1 anti-pattern detectors performance measures comparison (project Apollo) A p p r o a c h Anti-pattern Precision Recall Fl-score Items Clean code 1 0.99 0.99 99 M L SER1 code 0.67 1 0.8 3 macro average 0.83 0.99 0.90 102 Clean code 1 0.82 0.90 82 Rule-based SER1 code 0.1 1 0.18 20 macro average 0.55 0.91 0.54 102 of 0.93 and a precision of approximately 92.9% (see Table 7.8). H o w ever, while evaluating on project Klaw, the precision for T E C H _ D E B T 1 achieved only 22.4 % w i t h a false positive rate of 77.6 %. The results showed a precision of 50%, slightly better than before, for the label T E C H _ D E B T 2 . The evaluation of the A p o l l o project shows a n even greater drop i n precision and a n increase i n the false-positive rate of the T E C H _ D E B T 1 m o d e l , reaching almost 92%. These results show the m o d e l does not perform well i n generalisation across different codebases. It performed very well on the training dataset, but because the set of open-source projects used to train the model was relatively small (around 3000 samples per label), the model was slightly overfit to the patterns i n those projects. The identification of Software Anti-patterns related to S A T D varies significantly across different codebases. Each codebase employs unique markers to indicate bugs, including differences i n n a m i n g conventions, comment structures, and terminology. One c o m m o n issue is that the model often misclassifies comments containing phrases associated with the T E C H _ D E B T 1 label, such as "it s h o u l d . . . " , "create...", and "delete...". These phrases typically convey that something is i n complete or requires future work. However, they can also appear in comments that are contextually "clean" and d o not indicate any issues. A s a result, the dataset used to train the model may be imbalanced i n its representation of these terms, potentially leading to a high 62 7- J E A D E V A L U A T I O N O N O P E N S O U R C E PROJECTS false-positive rate. The future enhancement of this m o d e l should i n clude the creation of a high-quality, balanced dataset. The corpus of open-source projects w o u l d need to be larger, w i t h m u c h greater effort devoted to labelling and dataset processing. FPs produced w i t h a commented code label ( T E C H _ D E B T 2 ) often included comments explaining some parts of the code, together with the code snippets. For example, snippets i n the project Apollo included a textual visualisation of the release process feature described in the unit tests. Another F P included examples of properties used in the configuration files, which are more like explanatory, clean comments than code snippets. It is necessary to identify such cases i n the dataset's clean labels so the m o d e l can correctly recognise patterns and reduce the false-positive rate. In future work, it should also be considered to split the model into two separate models, one for each technical debt anti-pattern. The primary motivation for multi-label classification was that a code snippet might include both commented-out code and technical debt, but these examples are rare (at least i n the projects we used for training). This way, the m o d e l could learn to correct the opposite clean patterns for each anti-pattern more precisely. In contrast, this adds another layer of complexity to training and data preprocessing and increases the need for more resources for model deployment. Table 7.7: True and False positives statistics of T E C H _ D E B T model Project Anti-p. TP FP TP + F P TP (%) FP (%) Total K l a w T D l 13 45 58 22.4 77.6 2009K l a w TD2 16 16 32 50.0 50.0 2009 A p o l l o T D l TD2 15 9 170 59 185 86 8.1 13.2 91.9 86.8 2418 7.6 Validity and Applicability of the Models The results indicate that machine learning models are suitable for detecting structural and semantic anti-patterns i n Java enterprise systems, offering improved adaptability across different codebases. H o w - 63 7- J E A D E V A L U A T I O N O N O P E N S O U R C E PROJECTS Table 7.8: T E C H _ D E B T m o d e l performance o n test dataset d u r i n g training Epoch Precision Recall F l 1 0.9138 0.9054 0.9095 2 0.9142 0.9156 0.9147 3 0.9290 0.9344 0.9316 ever, rule-based approaches remain competitive, particularly i n terms of recall a n d interpretability. The findings suggest that neither approach is universally superior, a n d that combining them provides the most robust solution. A hybrid strategy, where machine learning models are used to improve generalisation and reduce false positives while rule-based detectors ensure coverage, appears to be the most appropriate approach for practical anti-pattern detection i n enterprise environments. 64 7- J E A D E V A L U A T I O N O N O P E N S O U R C E PROJECTS Key Findings God DI • Machine learning and rule-based approaches achieve comparable performance, with similar F l scores across both projects, making it difficult to declare a clear winner. • The M L model shows better stability and generalisation across different codebases by using multiple features rather than fixed thresholds. • Rule-based detection can sometimes achieve higher recall but is sensitive to threshold configuration and produces more inconsistent results between projects. Multi-service • The M L model significantly reduces false positives, making its detections more reliable, especially in projects like Apollo. • However, it has lower recall, missing some true anti-pattern cases compared to the rule-based approach. • Rule-based detection finds more issues but produces many false positives and requires tuning, while M L offers better generalisation across different project structures. Technical Debt • The model achieves high performance during training (Fl « 0.93), but this does not transfer to real-world projects. • In practice, it shows very high false-positive rates and poor precision, indicating weak generalisation. • The main issues are overfitting and imbalanced training data, especially due to variability in natural-language comments across codebases. 65 7- J E A D E V A L U A T I O N O N O P E N S O U R C E PROJECTS 7.7 Threats to Validity One validity threat is the manual labelling of both the training and ground-truth datasets for evaluation. Evaluating code snippets and metrics is often subjective because it is hard to determine the correct boundary between w h e n a code snippet is an anti-pattern and w h e n it is not. This may lead to inconsistencies across the evaluated projects, w i t h some developers seeing the evaluation differently. Another threat is the limited number of projects used for m o d e l training, especially for the T E C H _ D E B T model, resulting i n a small, tightly coupled dataset. The chosen approach involves significant manual labelling of the dataset, w h i c h is limited i n the thesis due to other w o r k on m o d e l deployment and detection infrastructure. The labelling is often performed by a group of experienced developers, or using the Crowd-smelling [35] approach (see Section 3.2.2). This approach enables better diversification of the dataset across various projects, allowing the model to generalise the identified snippets more effectively. One key factor is reproducibility. The electronic attachment of the thesis includes all necessary scripts, source code, and datasets for training the models, conducting manual evaluation, or r u n n i n g the evaluation. However, M L models (especially the T E C H _ D E B T model) require a G P U for training; otherwise, training may take several hours or be impossible on a C P U . To mitigate this threat, the finetuned m o d els are included in the thesis attachment and are ready for deployment on the Inference Server. Using a G P U for inference is optional but recommended, as it significantly improves performance. 66 8 Conclusion This thesis aimed to refactor and extend the J E N A static analysis detector developed i n previous theses [3] [4], enabling the use of M L models for the detection of Enterprise Java anti-patterns. The n e w version of the tool is called J E A D . We implemented an infrastructure that supports sending code features for evaluation by M L models. This infrastructure includes multiple changes and improvements on the J E A D side, for example, the implementation of code extractors, inference queues, and extended configuration, w h i c h allow dynamic registration of m o d els. We also improved J E A D by adding support for the Lombok code generation library and introducing custom J E A D M a v e n and Gradle plugins. A significant improvement to the project's structure made future development clearer for developers. The user experience was also enhanced by the zip package, automatically generated by GitHub Actions and eliminating the need to rebuild the project each time. The infrastructure also includes implementation of the Inference Server, w h i c h can dynamically load M L models and expose them through the unified g R P C interface. J E A D can connect to this server and send code features for evaluation. M L models are included and loaded as plugins, enabling customisation and easy addition of models. The server is released as a Docker image and can be r u n w i t h Docker Compose scripts p r o v i d e d i n J E A D ' s zip package. The source code is published i n a G i t H u b repository1 . Created Docker Images are published on D o c k e r H u b 2 . We also defined and prepared three M L solutions that demonstrate their potential to detect Java Enterprise Anti-patterns. The results show that they are comparable to rule-based detectors and, i n some cases, even better. The DI8 and SER1 models showed better stability and generalisation across the evaluated codebases than the corresponding rule-based detectors. However, the T E C H _ D E B T model d i d not generalise well to the evaluated projects and produced many false positives. This is mainly due to the limitations of the thesis and to a smaller 1. https://github.com/Ricaps/JEAD 2. https:/ /hub.docker.eom/r/ricaps/jead 67 8. C O N C L U S I O N number of projects selected for the dataset, so the m o d e l does not generalise as well across other code bases. In conclusion, M L models show great potential for detecting enterprise anti-patterns. However, there are cases where rule-based detection might be sufficient, mainly due to the effort required to train models, infrastructure needs, and the performance and resource requirements for m o d e l deployment. M o d e l s often require more data and effort to achieve better performance and reliability. Also, the m o d els are often "black boxes", so they might not be trusted by stakeholders and developers, leading to the analysis results being ignored. Future work should a i m to define more M L solutions using prepared infrastructure. O u r thesis selected a few anti-patterns f r o m the catalogue to demonstrate the possibilities of machine learning (or artificial intelligence i n general). There should also be a focus on i m p r o v i n g the Inference Server i n terms of security, automatic models undeployment, and A P I improvements. 68 Bibliography 1. G A M M A , Erich; H E L M , Richard; J O H N S O N , Ralph; VLISSIDES, John. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley Professional C o m p u t i n g Series. Pearson Education, 1994. ISBN 9780321700698. 2. B R O W N , W i l l i a m H . ; M A L V E A U , Raphael C ; M C C O R M I C K , Hays W ; M O W B R A Y , Thomas J. AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis. 1st. John W i l e y & Sons L t d , 1998. ISBN 978-0-471-19713-3. 3. BATE!, Jakub. Catalogue of Anti-Patterns in Java Enterprise Development. Brno, 2022. Master's Thesis. Masaryk University, Faculty of Informatics. 4. M I C K A , Petr. Anti-patterns Detection in Java Software Enterprise Development. Brno, 2024. Master's Thesis. M a s a r y k University, Faculty of Informatics. 5. Project Lombok [online]. 2025. [visited o n 2026-02-10]. Available from: h t t p s : / / p r o j ectlombok. o r g / . 6. G A F F N E Y JR, John E. Metrics i n software quality assurance. In: Proceedings of the ACM'81 conference. 1981, p p . 126-130. 7. G R E E N , Collin; J A S P A N , Ciera; H O D G E S , Maggie; L I N , Jessica. Developer Productivity for H u m a n s , Part 7: Software Quality. IEEE Software. 2024, vol. 41, no. 1, p p . 25-30. Available from DOI: 10.1109/MS.2023.3324830. 8. M C C A L L , J i m A ; R I C H A R D S , Paul K ; W A L T E R S , Gene F. Factors in software quality, volume i. concepts and definitions of software quality. 1977. Tech. rep. 9. P A L O M B A , Fabio; Z A N O N I , Marco; F O N T A N A , Francesca A r celli; D E L U C I A , A n d r e a ; O L I V E T O , Rocco. Toward a smellaware b u g prediction model. IEEE Transactions on Software Engineering. 2017, vol. 45, no. 2, pp. 194-218. 69 B I B L I O G R A P H Y 10. C H I D A M B E R , S.R.; K E M E R E R , C.F. A metrics suite for object oriented design. IEEE Transactions on Software Engineering. 1994, vol. 20, no. 6, p p . 4 7 6 ^ 9 3 . Available from DOI: 10 . 1109/32 . 295895. 11. B E L L I N , David; TYAGI, Manish; T Y L E R , Maurice. Object-oriented metrics: an overview. In: Proceedings of the 1994 Conference of the Centre for Advanced Studies on Collaborative Research. Toronto, O n tario, Canada: I B M Press, 1994, p. 4. C A S C O N '94. 12. Software engineering — Product quality — Part 1: Quality model. Geneva, Switzerland: International Organization for Standardization and International Electrotechnical Commission, 2001. No. ISO/IEC 9126-1:2001. Available also from: https : / /www . i s o . org/standard/22749 .html. W i t h d r a w n standard. 13. Systems and software engineering — Systems and software Quality Requirements and Evaluation (SQuaRE) — Quality model overview and usage. Geneva, Switzerland: International Organization for Standardization and International Electrotechnical Commission, 2024. N o . ISO/IEC 25002:2024. Available also from: https : //www. i s o . o r g / s t a n d a r d / 7 8 1 7 5 . h t m l . 14. B U S C H M A N N , Frank; M E U N I E R , Regine; R O H N E R T , Hans; S O M M E R L A D , Peter; S T A L , Michael. Pattern-oritented Software Architecture. A System of Patterns. John Wiley & Sons L t d , 2001. ISBN 9780471958697. 15. L A N Z A , Michele; M A R I N E S C U , Radu. Object-oriented metrics in practice: using software metrics to characterize, evaluate, and improve the design of object-oriented systems. Springer, 2006. 16. F O O T E , Brian; Y O D E R , Joseph. Big ball of m u d . Pattern languages of program design. 1997, vol. 4, pp. 654-692. 17. R I V E R A , Richard; M O S Q U E R A , Marcela; FLORES, Pamela; A N C H U N D I A , Carlos E.; J I M E N E Z , Alejandro; C A R P I O , Xavier. Smells vs. Software Antipatterns: Do Definitions Matter? In: 2025 IEEE/ACIS 23rd International Conference on Software Engineering Research, Management and Applications (SERA). 2025, pp. 169-174. Available from DOI: 10.1109/SERA65747.2025.11154518. 70 B I B L I O G R A P H Y 18. P O L U , O m k a r Reddy. A I - D r i v e n Automatic C o d e Refactoring for Performance Optimization. International Journal of Science and Research. 2025, vol. 14, no. 1, pp. 1316-1320. 19. C O R D E I R O , Jonathan; N O E I , Shayan; Z O U , Ying. L L M - D r i v e n Code Refactoring: Opportunities and Limitations. In: 2025 IEEE/ACM Second IDE Workshop (IDE). IEEE, 2025, pp. 32-36. 20. G E Z I C I G E C E R , Bahar; K O L U K I S A T A R H A N , Ayca. Explainable A I framework for software defect prediction. Journal of Software: Evolution and Process. 2025, vol. 37, no. 4, e70018. 21. M O H A P A T R A , Partha Sarathi. Intelligent Assurance: Artificial Intelligence-Powered Software Testing in the Modern Development Lifecycle. Deep Science Publishing, 2025. Available from DOI: 10. 70593/978-93-7185-046-9. 22. F E R R E I R A , Kecia A . M . ; B I G O N H A , M a r i z a A.S.; B I G O N H A , Roberto S.; M E N D E S , Luiz F.O.; A L M E I D A , Heitor C. Identifying thresholds for object-oriented software metrics. Journal of Systems and Software. 2012, vol. 85, no. 2, p p . 244-257. ISSN 0164-1212. Available from DOI: 10.1016/j . j s s .2011.05.044. Special issue w i t h selected papers from the 23rd Brazilian S y m p o s i u m on Software Engineering. 23. PMD - source code analyzer [online]. P M D O p e n Source Project, 2026. [visited on 2026-02-19]. Available from: h t t p s : / / d o c s . pmdc o d e . o r g / l a t e s t / i n d e x . h t m l . 24. ASM framework [online]. I N R I A , France Telecom, 2025. [visited on 2026-02-19]. Available from: https : / /asm . ow2 . i o / i n d e x . html. 25. Spring Shell [online]. Broadcom, 2026. [visited o n 2026-02-20]. Available from: https : / / d o c s . s p r i n g . i o / s p r i n g - s h e l l / r e f e r e n c e / i n d e x . h t m l . 26. Spring Boot [online]. Broadcom, 2026. [visited o n 2026-02-20]. Available from: https : / / d o c s . s p r i n g . i o / s p r i n g - b o o t / i n d e x . html. 27. Java Parser [online]. Github repository. 2026. [visited o n 2026- 02-20]. Available from: https : / / g i t h u b . com / javaparser / javaparser. 71 B I B L I O G R A P H Y 28. SonarQube Documentation [online]. SonarSource Sari, 2025. [visited on 2026-02-19]. Available from: https : / / d o c s . sonarsource. com/. 29. Code Quality and Security for Java [online]. Github repository. SonarSource Sari, 2026. [visited o n 2026-02-19]. Available from: https://github.com/SonarSource/sonar-Java. 30. L A I G N E R , Rodrigo Nunes. Cataloging Dependency Injection AntiPatterns in Software Systems. 2020. Available from DOI: 10.17771/ PUCRio. acad. 47298. M A thesis. Pontifical Catholic University of Rio de Janeiro (PUC-Rio). 31. F O K A E F S , Marios; T S A N T A L I S , Nikolaos; S T R O U L I A , Eleni; C H A T Z I G E O R G I O U , Alexander. JDeodorant: identification and application of extract class refactorings. In: Proceedings of the 33rd International Conference on Software Engineering. Waikiki, H o n olulu, H I , U S A : Association for C o m p u t i n g Machinery, 2011, pp. 1037-1039. ICSE '11. ISBN 9781450304450. Available from DOI: 10.1145/1985793.1985989. 32. A L I , Israr; R I Z V I , Syed Sajjad Hussain; A D I L , Syed Hasan. E n hancing software quality w i t h A I : A transformer-based approach for code smell detection. Applied Sciences. 2025, vol. 15, no. 8, p. 4559. 33. F E N G , Zhangyin; G U O , Daya; T A N G , D u y u ; D U A N , N a n ; F E N G , Xiaocheng; G O N G , M i n g ; S H O U , Linjun; Q I N , Bing; L I U , Ting; J I A N G , Daxin, et al. Codebert: A pre-trained model for programm i n g a n d natural languages. In: Findings of the association for computational linguistics: EMNLP 2020. 2020, pp. 1536-1547. 34. G U O , Daya; R E N , Shuo; L U , Shuai; F E N G , Z h a n g y i n ; T A N G , D u y u ; L I U , Shujie; Z H O U , Long; D U A N , N a n ; SVYATKOVSKIY, Alexey; F U , Shengyu, et al. Graphcodebert: Pre-training code representations w i t h data flow. arXiv preprint arXiv.2009.08366. 2020. 35. REIS, Jose Pereira dos; A B R E U , Fernando Brito e; C A R N E I R O , Glauco de Figueiredo. Crowdsmelling: A preliminary study on using collective knowledge i n code smells detection. Empirical Software Engineering. 2022, vol. 27, no. 3, p. 69. 72 B I B L I O G R A P H Y 36. H O , A n h ; B U I , A r m M T ; N G U Y E N , P h u o n g T; D I S A L L E , A m leto; L E , Bach. EnseSmells: Deep ensemble a n d p r o g r a m m i n g language models for automated code smells detection. Journal of Systems and Software. 2025, vol. 224, p. 112375. 37. H O , A n h ; B U I , A n h M . T.; N G U Y E N , P h u o n g T.; D I S A L L E , Amleto. Fusion of deep convolutional and L S T M recurrent neural networks for automated detection of code smells. In: Proceedings of the 27th International Conference on Evaluation and Assessment in Software Engineering. O u l u , Finland: Association for Computing Machinery, 2023, p p . 229-234. E A S E '23. Available f r o m DOI: 10.1145/3593434.3593476. 38. A N I C H E , Mauricio. CK: Code metricsfor Java code by means of static analysis [online]. GitHub, 2022 [visited on 2026-02-22]. Available from: h t t p s : / / g i t h u b . com/mauricioaniche/ck. 39. A Z A D I , Umberto; A R C E L L I F O N T A N A , Francesca; Z A N O N I , Marco. Machine Learning based Code Smell Detection through WekaNose. 2018. Available from DOI: 10.1145/3183440.3194974. 40. C R U Z , Daniel; S A N T A N A , A m a n d a ; F I G U E I R E D O , Eduardo. Evaluating a continuous feedback strategy to enhance machine learning code smell detection. Science of Computer Programming. 2026, vol. 247, p. 103346. ISSN 0167-6423. Available from DOI: 10. 1016/j.scico.2025.103346. 41. Spring Framework Documentation [online]. Broadcom, 2026. [visited on 2026-02-26]. Available from: https : / / d o c s . s p r i n g . i o / s p r i n g - f r a m e w o r k / r e f e r e n c e / i n d e x . h t m l . 42. R O N PRESSLER, A l a n Bateman. JEP 444: Virtual Threads [online]. OpenJDK, 2025. [visited o n 2026-02-26]. Available from: h t t p s : //openj dk.org/jeps/444. 43. A N I C H E , Mauricio. gRPC: A high performance, open source universal RPCframework [online]. 2026. [visited o n 2026-02-26]. Available from: h t t p s : / / g r p c . i o / . 44. Spring gRPC: GRPC Client [online]. V M W a r e , 2025. [visited on 2026-02-26]. Available from: h t t p s : //docs . s p r i n g . i o / s p r i n g g r p c / r e f e r e n c e / c l i e n t . h t m l . 73 B I B L I O G R A P H Y 45. SCOPES, Ashley. Protobuf Maven Plugin [online]. 2026. [visited on 2026-02-26]. Available from: https : / /ascopes . g i t h u b . i o / protobuf-maven-plugin/. 46. Delombok [online]. 2025. [visited on 2026-02-10]. Available from: https://projectlombok.org/features/delombok. 47. Apache Maven Resources Plugin [online]. 2026. [visited o n 2026- 03-10]. Available from: https : //maven. apache . o r g / p l u g i n s / maven-resources-plugin/. 48. GitHub Packages documentation [online]. 2026. [visited on 2026-03- 10]. Available from: https : / / d o c s . g i t h u b . com/en/packages. 49. Maven Assembly Plugin [online]. 2026. [visited o n 2026-03-11]. Available from: https : / /maven. apache . o r g / p l u g i n s / m a v e n - assembly-plugin/. 50. GitHub Actions [online]. 2026. [visited on 2026-03-11]. Available from: h t t p s : / / g i t h u b . com/features/actions. 51. Docker [online]. 2026. [visited o n 2026-03-11]. Available from: https://www.docker.com/. 52. Docker Compose [online]. 2026. [visited on 2026-03-11]. Available from: h t t p s : / / d o c s . docker. com/compose/. 53. NVIDIA Triton Inference Server [online]. 2026. [visited on 2026-03- 11]. Available from: h t t p s : / / d o c s . n v i d i a . com/deeplearning/ t r i t o n - i n f e r e n c e - s e r v e r / u s e r - g u i d e / d o c s / i n d e x . h t m l . 54. MLServer [online]. 2026. [visited on 2026-03-11]. Available from: h t t p s : / / d o c s . s e l d o n . a i / m l s e r v e r . 55. KServe [online]. 2026. [visited on 2026-03-11]. Available from: h t t p s : / / k s e r v e . g i t h u b . i o / w e b s i t e / . 56. F O W L E R , Martin. Inversion of Control Containers and the Dependency Injection pattern [online], [visited on 2026-03-12]. Available from: h t t p s : / / m a r t i n f owler. c o m / a r t i c l e s / i n j e c t i o n . h t m l . 57. asyncio - Asynchronous I/O [online]. 2026. [visited on 2026-03- 12]. Available from: https : / /docs . python . o r g / 3 / l i b r a r y / asyncio.html. 74 B I B L I O G R A P H Y 58. Poetry: Python packaging and dependency management made easy [online]. 2026. [visited o n 2026-03-12]. Available from: https : / / p y t h o n - p o e t r y . o r g / . 59. Python gRPC [online]. 2026. [visited o n 2026-02-26]. Available from: h t t p s : / / g r p c . i o / d o c s / l a n g u a g e s / p y t h o n / q u i c k s t a r t / . 60. Requirements File Format [online]. 2026. [visited on 2026-03-13]. Available from: https : / / p i p . p y p a . i o / e n / s t a b l e / r e f erence/ r e q u i r e m e n t s - f i l e - f o r m a t / . 61. pip: The PyPA recommended toolfor installing Python packages, [online]. 2026. [visited o n 2026-03-13]. Available from: https : / / p y p i . o r g / p r o j e c t / p i p / . 62. Docker Hub [online]. 2026. [visited on 2026-03-13]. Available from: h t t p s : / / h u b . d o c k e r . c o m / r e p o s i t o r y / d o c k e r / r i c a p s / j ead/ general. 63. NVIDIA [online]. 2026. [visited o n 2026-03-13]. Available from: h t t p s : / / w w w . n v i d i a . c o m / . 64. ONNX [online]. 2026. [visited o n 2026-03-13]. Available from: h t t p s : / / o n n x . a i / . 65. scikit-learn [online]. 2026. [visited on 2026-03-13]. Available from: h t t p s : / / s c i k i t - l e a r n . o r g / s t a b l e / i n d e x . h t m l . 66. Transformers [online]. H u g g i n g Face, 2026. [visited on 2026-03- 15]. Available from: https : //huggingf ace. c o / d o c s / t r a n s f ormers/ index. 67. F O N T A N A , Francesca Arcelli; Z A N O N I , Marco; M A R I N O , Alessandro; M A N T Y L A , M i k a V. Code Smell Detection: Towards a M a chine Learning-Based Approach. In: 2013 IEEE International Conference on Software Maintenance. 2013, pp. 396-399. Available from DOI: 10.1109/ICSM.2013.56. 68. A R C E L L I F O N T A N A , Francesca; M A N T Y L A , M i k a V ; Z A N O N I , Marco; M A R I N O , Alessandro. C o m p a r i n g a n d experimenting machine learning techniques for code smell detection. Empirical Software Engineering. 2016, vol. 21, no. 3, pp. 1143-1191. 75 B I B L I O G R A P H Y 69. A Z E E M , M u h a m m a d Ilyas; P A L O M B A , Fabio; SHI, L i n ; W A N G , Qing. Machine learning techniques for code smell detection: A systematic literature review a n d meta-analysis. Information and Software Technology. 2019, vol. 108, pp. 115-138. 70. Code and Metrics [online]. H u g g i n g Face, 2026. [visited o n 2026- 03-15]. Available from: h t t p s : / / g i t h u b . com/yegor256/cam. 71. Pandas: Python Data Analysis Library [online]. 2026. [visited o n 2026-03-15]. Available from: https : //pandas. pydata. o r g / . 72. skllonnx: Convert scikit-learn models to ONNX [online]. 2025. [visited o n 2026-03-21]. Available from: h t t p s : / / p y p i . o r g / p r o j e c t / skl2onnx/. 73. S I V A K U M A R , A m r u t h a ; B H A V Y A , G ; M , Srinidhi; N A R M A D A , N a k k a ; PATI, Peeta Basa. Clustering a n d V i s u a l i z i n g Programming Solutions: A Transformer-Based Analysis Using CodeBERT and CodeT5+. In: 2025 International Conference on Emerging Technologies in Computing and Communication (ETCC). 2025, pp. 1-6. Available from DOI: 10.1109/ETCC65847.2025.11108390. 74. UMAP: Uniform Manifold Approximation and Projection for Dimension Reduction [online]. 2026. [visited o n 2026-03-21]. Available from: h t t p s : / / u m a p - l e a r n . readthedocs . i o / e n / l a t e s t / . 75. scikit-learn Clustering: HDBSCAN [online]. 2026. [visited o n 2026- 03-21]. Available from: h t t p s : / / s c i k i t - l e a r n . o r g / s t a b l e / modules/clustering.html#hdbscan. 76. D E N G , Dingsheng. D B S C A N Clustering A l g o r i t h m Based o n Density. In: 2020 7th International Forum on Electrical Engineering and Automation (IFEEA). 2020, pp. 949-953. Available from DOI: 10.1109/IFEEA51475.2020.00199. 77. LI, Y i k u n ; S O L I M A N , M o h a m e d ; A V G E R I O U , Paris. Automatically Identifying Relations Between Self-Admitted Technical Debt Across Different Sources. In: 2023 ACM/IEEE International Conference on Technical Debt (TechDebt). 2023, pp. 11-21. Available from DOI: 10.1109/TechDebt59074.2023.00008. 78. M A H M O O D , Sajjad. Detecting Inline Code C o m m e n t Smells Leveraging CodeBERT Model. IEEE Access. 2026, vol. 14, pp. 28367- 28382. Available from DOI: 10.1109/ACCESS. 2026.3666288. 76 B I B L I O G R A P H Y 79. Apache Hive (TM) [online]. 2026. [visited o n 2026-03-21]. Available from: h t t p s : / / g i t h u b . com/apache/hive. 80. Apache Tomcat [online]. 2026. [visited o n 2026-03-21 ]. Available from: h t t p s : / / g i t h u b . com/apache/tomcat. 81. ThingsBoard [online]. 2026. [visited o n 2026-03-21]. Available from: h t t p s : / / g i t h u b . com/thingsboard/thingsboard. 82. PA165 Java Enterprise Applications [online]. Faculty of Informatics, Masaryk University, 2024. [visited o n 2026-03-21]. Available from: h t t p s : / / i s .muni. cz/predmet/f i/jaro2024/PA165. 83. onnxruntime [online]. Microsoft, 2026. [visited o n 2026-03-21]. Available from: h t t p s : / / p y p i . o r g / p r o j e c t / o n n x r u n t i m e / . 84. Klaw [online]. A i v e n , 2026. [visited o n 2026-03-06]. Available from: h t t p s : / / g i t h u b . com/Aiven-Open/klaw. 85. Apollo: A reliable configuration management system [online]. 2026. [visited o n 2026-03-06]. Available from: h t t p s : / / g i t h u b . com/ apolloconf i g / a p o l l o . 86. A M I N , Fahmy; M A H M O U D , M . Confusion matrix i n binary classification problems: A step-by-step tutorial. Journal of Engineering Research. 2022, vol. 6, no. 5. 87. F O W L E R , Martin; B E C K , Kent. Refactoring: improving the design of existing code. Second Edition. Boston: Addison-Wesley, 2019. ISBN 978-0-13475759-9. 88. P O T D A R , Aniket; S H I H A B , Emad. A n Exploratory Study on SelfA d m i t t e d Technical Debt. In: 2014 IEEE International Conference on Software Maintenance and Evolution. 2014, pp. 91-100. Available from DOI: 10.1109/ICSME.2014.31. 77 A Java Enterprise Anti-pattern Catalogue The following sections present a catalogue of Java Enterprise A n t i patterns based on the Master's thesis b y M i c k a [4]. This thesis expanded the catalogue b y a d d i n g the Technical Debt section. A d d i tionally, we analyzed the suitability of all anti-patterns for machine learning detection. For anti-patterns that lack analysis text, they are not suitable for detection by machine learning models. A.l Dependency Injection Name Description M L Detection Name Description M L Detection Name Description M L Detection Name Description M L Detection DI1 Unused Injection A dependency is injected into the bean, but it is unused. It is very similar to the unused field anti- pattern. DI2 Direct Container Call A bean calls the methods of the DI container to inject a dependency. It should use an abstraction, not a direct call. DI3 Concrete Class Injection The injected type is a concrete class, instead of an interface or an abstract class. DI4 Open Window Injection Other classes can access the injected dependency. It is either passed to some other classes or stored i n the public field. 78 A . JAVA ENTERPRISE A N T I - P A T T E R N C A T A L O G U E Name Description M L Detection Name Description M L Detection Name Description M L Detection Name Description M L Detection Name Description M L Detection DI5 Framework Coupling U s i n g framework-specific annotations such as A u towired or Service instead of generic ones f r o m the Jakarta specifications, like Inject. It can make it harder to swap between Dependency Injection frameworks. DI6 Multiple Forms Of Injection The same dependency is injected using multiple injection methods. For example, using setters and fields. This can cause multiple side effects, and the code might become unreadable. DI7 Open Door Injection A injected dependency stored i n a non-final field can be overridden by the new field assignment, for example, by the public setter. DI8 God DI Class The bean has injected too many fields and does a lot of unrelated stuff. It is a variant of the Large class anti-pattern defined by Fowler [87]. Traditional M L techniques like R a n d o m Forests or Naive Bayes can help dynamically learn thresholds based o n code metrics. DI9 Multiple Assigned Injections The injected dependency is stored i n multiple fields. For example, the dependency can be stored i n the current class's field and passed to the parent class via the constructor. 79 A . JAVA ENTERPRISE A N T I - P A T T E R N C A T A L O G U E Name Description M L Detection Name Description M L Detection Name Description DUO Long Producer Method A method creating a bean (typically w i t h a Bean annotation) is long a n d complex. It also has more responsibilities than producing a bean, such as enforcing business rules. M L techniques could learn dynamic thresholds for the detection of method complexity. Some N L P models c o u l d understand the code a n d detect complex logic. Dill Intransigent Injection A performance-heavy dependency is injected eagerly at bean construction, instead of lazily loading w h e n needed. M L m o d e l could learn patterns typical for performance-heavy calls a n d help identify such beans. Dili Static Dependence Provider The class is getting dependencies using static methods. Such dependency might use the singleton design pattern, for example. It results i n tight coupling between classes. M L Detection A.2 Persistence Layer Name PERI N+l Query Problem Description The anti-pattern m a y occur w h e n w e have associated entities (many-to-one, one-to-many) with eager fetching of related data. In this case, N queries are used instead of a single query to fetch data. M L Detection 80 A . JAVA ENTERPRISE A N T I - P A T T E R N C A T A L O G U E Name Description M L Detection Name Description M L Detection PER2 Dredge This anti-pattern occurs w h e n we use deep queries to fetch entities from the database. It might end up loading the entire graph of entities, causing real performance problems. Perhaps some graph-aware m o d e l w i t h entity context could detect heavy database queries. PER3 Crush Data integrity is lost w h e n a code operates on i n valid data it loaded before another unrelated code changed it. Typically, this happens w h e n entity A loads related data X ; entity B also loads data X and modifies it; then entity A works with outdated data. A.3 Service Layer Name Description M L Detection Name Description M L Detection SER1 Multiservice Service consists of unrelated methods and can be split into multiple interfaces. It uses a method for different use cases and different types. More clusters of semantically similar method names could reveal multi-service anti-patterns. SER2 Tiny Service There are multiple related services, each one w i t h a small number of methods. It makes sense to merge them into services w i t h meaningful sizes. Semantic similarity of methods across multiple i n terfaces could help identify mergeable interfaces. 81 A . JAVA ENTERPRISE A N T I - P A T T E R N C A T A L O G U E Name SER3 The Client Completes a Service Description A service is missing important functionality, such as validation or security checks. Clients using such a service have to implement the missing functionality themselves instead of using the service. M L Detection N L P model could be used to learn patterns of missing functionality (validation,...) a n d help identify places where it is missing. A.4 Mocking Name Description M L Detection Name Description M L Detection Name Description M L Detection 82 M0C1 Final Method Call with Exception In the tested method, there is a call to a final method or a call to a method from a final class, w h i c h does functionality we w o u l d like to mock. It is harder and slower to mock the final methods. MOC2 Constructor Call with Exception There is a constructor call i n a method we w o u l d like to test, and this constructor call can throw an exception a n d communicate w i t h an external service we want to mock. The constructor call prevents mocking the layer communication w i t h external services. MOC3 Static Call with Exception The tested method calls a static method w e w o u l d like to mock because it communicates w i t h an external service. The code using static methods is tightly coupled and less testable. A . JAVA ENTERPRISE A N T I - P A T T E R N C A T A L O G U E Name M0C4 Inappropriate Method Mocking Description M o c k maker editing byte code is used, for example, M o c k maker, inline or Powermock, to mock static or final methods instead of refactoring. M L Detection A.5 Security S E C 2 Storing Secrets in Insecure Places Storing sensitive information like passwords or usernames i n insecure locations, such as configuration files or resources committed to version control sys- tems. Secrets can be saved i n many forms. A n N L P model could identify secrets leaked to the version control. SEC2 Disabling CSRF Protection The C S R F protection is turned off, for example, i n Spring Security. It allows attackers to send malicious requests f r o m their website to the honest website. It is needed especially for session-based authentica- tion. M L Detection Name SEC3 Lifelong Access Tokens Description The lifetime of access tokens is too long - hours, days. Access tokens should be short-lived and used together w i t h refresh tokens. Name Description M L Detection Name Description M L Detection Name Description M L Detection SEC4 Insecure Default Configuration A default configuration that is used is insecure. Some password encoders might use l o w security by default, so they need to be reconfigured. 83 A . JAVA ENTERPRISE A N T I - P A T T E R N C A T A L O G U E Name SEC5 Signing JWT With Fixed Secret Description JWT are signed w i t h fixed secrets instead of random secrets w i t h high entropy. M L Detection Name SEC6 Insecure Communication Description TLS is not used for H T T P communication, so the communication is not encrypted. M L Detection A.6 Technical Debt Name Description M L Detection TECHJDEBTl Self Admitted Technical Debt The self-admitted technical debt often occurs as code comments, w i t h patterns as TODO, FIXME, to be done, refactor it. It indicates that something i n the code does not w o r k properly, is a w o r k a r o u n d , is incomplete, and needs future attention. Having such an anti-pattern in the enterprise codebase is not safe, since it means the software is most probably not working reliably [88]. Some patterns are obvious, and e.g. regular expressions are sufficient. But some N L P models could semantically understand a comment and detect SATD. 84 A . JAVA ENTERPRISE A N T I - P A T T E R N C A T A L O G U E Name Description M L Detection TECH_DEBT2 Commented Out Code A healthy codebase should not include commentedout code. It often leads to maintainability and readability issues. The later use of such code might lead to the usage of untested, unsafe code. Also, the commented-out code often means missing functionality or a commented-out automated test. It is a better practice to remove dead code w h e n using a proper version control system, so the history of removed code can be recovered later. Code patterns can be partially detected using regular expressions. M L models can improve the identification of comments, w h i c h include code samples for informative purposes, not commented-out code. 85 B JEAD Project Structure The following file tree presents the high-level structure of the J E A D project and its sub-projects. For simplicity, it omits concrete files. JEAD/ Root directory .github/ GitHub Workflow definitions ai-detector/ Root directory for Python ML projects tinference-server/ Inference Server sub-project training/ Code for training ML models assembly/ Maven project for maven-assembly-plugin build-plugins/ Custom build plugins jead-gradle-plugin/ JEAD Gradle Plugin jead-maven-plugin/ JEAD Maven Plugin jead-plugin-core/ Shared logic for both plugins detector/ Static detector tool test-fixtures/ Test fixtures for auto-tests antipatterns/ authorization-server/ power-mock-usage/ test-gradle-project/ 86 C Running the Evaluation A l l necessary steps are described i n the J E A D runtime assembly package i n README .md file. The following text describes the basic steps for configuring and running the application and the evaluation. The listed commands may differ across operating systems. To r u n the evaluation using J E A D w i t h the support of machine learning, you must meet the following prerequisites: 1. Obtain the J E A D runtime assembly package (see A p p e n d i x E). 2. Obtain the models root package (or create your o w n models; see A p p e n d i x E). 3. Install Java w i t h version > = 25. 4. Install Docker with Docker Compose (or an alternative like Pod- man). 5. Configure .env file i n the J E A D runtime assembly (path to models root and G P U availability flag) Then, y o u have to perform the necessary configuration: 1. U n z i p the J E A D runtime assembly package. 2. U n z i p the models root folder and copy its absolute path. 3. O p e n the . env file i n the text editor and set: • M0DELS_R00T_H0ST to the absolute path to the models root folder. • USE_GPU to true i n case you want to install G P U dependen- cies. 4. U s i n g your G i t H u b account, generate a classic Personal Access Token ( P A T ) 1 , w i t h m i n i m u m permission read:packages. 1. https://docs.github.com/en/authentication/ keeping-your-account-and-data-secure/managing-your-personal-access-tokens* creating-a-personal-access-token-classic 87 C. R U N N I N G T H E E V A L U A T I O N 5. O p e n the conf i g / a p p l i c a t i o n . y m l file and insert the P A T to p r e p a r e - p l u g i n . r e p o s i t o r y . a c c e s s - t o k e n property. To r u n the Inference Server, PostgreSQL database and J E A D detector, you have to use the following commands: Listing C.1: C o m m a n d s to r u n the application # To run i n the GPU mode, use: docker compose - f compose.yaml - f compose . g p u . y a m l up # Or to r u n i n CPU—only mode, use : docker compose - f compose.yaml up # To s t a r t IEAD d e t e c t o r a p p l i c a t i o n , use: j a v a - j a r d e t e c t o r . j a r To r u n the evaluation on the project which is using Maven, you should perform the following steps (let's assume the evaluated project is located at / h o m e / p r o j e c t s / s p r i n g - p r o j e c t : 1. Enter prepare command to the J E A D C L I : prepareProjects - d / h o m e / p r o j e c t s / s p r i n g - p r o j e c t 2. Build the Maven project (run i n the project's directory): cd / h o m e / p r o j e c t s / s p r i n g - p r o j e c t & mvn clean package 3. R u n the evaluation using J E A D C L I : d e t e c t l s s u e s - p / h o m e / p r o j e c t s / s p r i n g - p r o j e c t 88 D Architecture Diagrams This appendix includes diagrams related to the J E A D a n d Inference server architectures. Software Engineer [Person] An engineer who wants to analyze the project for enterprise anti-patterns Builds and prepares project for the analysis [Maven/Gradle] Starts the analysis [CLI Interlace] Analyzed project [Software System] A target system for the analysis Parses code Extracts code features [Java Parser] Uses plugins to expose dependencies! and deLombok [Maven or Gradle] Inference Server [Container: Python gRPC Server] Modular gRPC server that allows hosting of pretrained machine learning models Sends code features for ML evaluation [gRPC] JEAD Detector [Container: Spring Shell Application] Static analysis tool for detection of enterprise anti-patterns JEAD Maven Plugin [Component: Maven Plugin] Maven plugin to be included in the analyzed projects. Exposes JAR dependencies and does deLombok. Support Build Plugins [Container] JEAD Gradle Plugin [Component: Gradle Plugin] Gradle plugin to be included in the analyzed projects. Exposes JAR dependencies and does deLombok. Software system [JEAD] Figure D . l : System-level diagram of J E A D architecture 89 D . A R C H I T E C T U R E D I A G R A M S < r •D I s £ 1 O a] i 1(A en 5 alts S I ^ tect ipone 2 | E E •° 1 Figure D.2: Component-level diagram of JE A D architecture D . A R C H I T E C T U R E D I A G R A M S JEAD detector [Container: Spring Boot CLI] Detector extracting code issues and sending them for inference ModelStorage [Component: e.g. Spring Service] Scan models root folder, load/unload models, handles virtual env and requirements of models. Stores metadata about the model. Code Snippets for Inference [gRPC] InferenceServicerPort [Component: Python gRPC] Handles all incoming gRPC requests Do Inference Do Inference Load Unload Sends command [TCP Socket] ModelWorkerManager [Component: e.g. Spring Service] Manages TCP socket clients and model processes Sends command [TCP Socket] Inference Server [Container] socket_worker.py [Component: Python script, TCP Socket Server] TCP Socket Server handling commands and loading of worker.py script. Shared script started for each process. socket_worker.py [Component: Python script, TCP Socket Server] TCP Socket Server handling commands and loading of worker.py script. Shared script started for each process. Calls methods of MLWorker object worker.py [Component: Python script] Worker script handling calling and the ML model 1 models_root/model_l [ML Model Process] Calls methods of MLWorker object worker.py [Component: Python script] Worker script handling calling and the ML model 2 models_root/model_2 [ML Model Process] Figure D.3: Component-level diagram of Inference Server modular architecture 91 E Electronic Attachment The following structure represents the folders a n d files included i n the thesis electronic attachment. submission-thesis/ README.md . . Documentation of the bundle structure Jead-master/ .. Source code repository datasets/ Arrow and JSONL datasets evaluation/ Models evaluation in ODS format jead-runtime/ . Runtime assembly package models_root/ ...Models root including trained ML models 92