JDeodorant is an Eclipse plug-in that identifies design problems in software, known as bad smells, and resolves them by applying appropriate refactorings.
JDeodorant employs a variety of novel methods and techniques in order to identify code smells and suggest the appropriate refactorings that resolve them.
For the moment, the tool identifies five kinds of bad smells, namely Feature Envy, Type Checking, Long Method, God Class and Duplicated Code.
Feature Envy problems are resolved by appropriate Move Method refactorings.
Type Checking problems are resolved by appropriate Replace Conditional with Polymorphism and Replace Type code with State/Strategy refactorings.
Long Method problems are resolved by appropriate Extract Method refactorings.
God Class problems are resolved by appropriate Extract Class refactorings.
Duplicated Code problems are resolved by appropriate Extract Clone refactorings.
The tool is the outcome of the research performed in the Software Refactoring Lab Department of Computer Science and Software Engineering, Concordia University, Canada and the Software Engineering Group at the Department of Applied Informatics, University of Macedonia, Thessaloniki, Greece.
JDeodorant encompasses a number of innovative features:
- Transformation of expert knowledge to fully automated processes
- Pre-Evaluation of the effect for each suggested solution
- User guidance in comprehending the design problems
- User friendliness (one-click approach in improving design quality)
JDeodorant YouTube Channel
Refactoring of the Clones - Teaser Trailer
Code Smell Visualization Demo
[12/09/2016] Bug fixes and improvements in the Move Method Refactoring implementation.
[29/08/2016] Bug fixes and improvements in the Clone Refactoring feature.
[14/06/2016] Proper creation of incoming control dependence for Try statements without resources.
- [11/06/2016] Bug fixes and improvements:
- Fixed the check for unprocessed methods in call graph analysis.
- Fixed an infinite loop in call graph analysis.
- TypeSearchRequestor excludes anonymous types from the results when searching for subclass types.
[09/06/2016] Bug fixes and improvements:
- Improved the detection of method declarations with a type parameter from method invocations.
- Fixed a common bug in Extract Class and Move Method refactorings related to Enums.
- Refactored the common logic for finding topics to class TopicFinder.
- Added a right-click pop-up menu to show the code smell visualization on user demand.
- Added a check box for the filtering of clone groups based on the Java files currently opened in the editor.
[06/04/2016] Extended method call analysis to class instance creations and constructor invocations.
[22/02/2016] Fixed all the bugs reported for Type-Checking related refactorings in the paper by Francesca Arcelli Fontana, Marco Mangiacavalli, Domenico Pochiero, and Marco Zanoni titled On experimenting refactoring tools to remove code smells.
Special thanks to Marco Mangiacavalli for the detailed report he prepared.
[11/02/2016] Fixed all the bugs reported for Extract Method Refactoring in the paper by Francesca Arcelli Fontana, Marco Mangiacavalli, Domenico Pochiero, and Marco Zanoni titled On experimenting refactoring tools to remove code smells.
Special thanks to Marco Mangiacavalli for the detailed report he prepared.
Improved the performance of method call analyzer. If the type of the reference through which a polymorphic method is called can be statically determined, then only the overriding implementation of the subclass type corresponding to the reference type is analyzed.
- Improved the views for Feature Envy, God Class, Long Method, Type-Checking by allowing the user to apply refactoring opportunities on the currently examined project, even if the user has selected another project in between. The active project is always the last project on which a detection of code smells has been performed.
- If the user has opened multiple code smell views, and each one of them contains refactoring opportunities for a different project, then a change to one of the projects will disable the "Apply Refactoring" button only for the code smell view corresponding to the changed project.
The Extract Method refactoring opportunities in which the statement declaring the variable criterion is nested in a deeper level compared to the level in which the extracted method invocation will be placed (i.e., the level in which the first statement of the slice is nested) are automatically excluded from being reported.
- The project is always being built before getting parsed. AST parsing takes place only if there are no compilation errors.
- Files generated by Parser generators are automatically skipped from the analysis for refactoring opportunities. Currently, JavaCC, ANTLR, JFlex, and CUP generators are supported.
[29/12/2015] Fixed all the bugs reported for Extract Class Refactoring in the paper by Francesca Arcelli Fontana, Marco Mangiacavalli, Domenico Pochiero, and Marco Zanoni titled On experimenting refactoring tools to remove code smells.
Special thanks to Marco Mangiacavalli for the detailed report he prepared.
[14/12/2015] Improved the handling of block nested within control statements in the generation of the Program Dependence Graph.
[12/12/2015] Improved the clone statement mapping process to prevent the mapping of statements being nested in the same level, but belonging to different basic blocks.
[06/12/2015] Methods belonging to test classes are no longer reported as refactoring opportunities for Feature Envy.
Fixed a bug occurring when the user is switching between the Duplicated Code view containing imported clones belonging to project X and the Refactoring of duplicated methods selected in the Package Explorer belonging to project Y.
[23/11/2015] The repeated clone groups and class-level clones are no longer stored in memory.
[20/11/2015] The Duplicated Code view is updated after a refactoring or any other source code edit to highlight the eliminated, edited, and shifted clones. In this way the user does not have to import new clone detection results after the application of a clone refactoring.
[03/11/2015] The import of clone detection results has become faster by disabling the resolution of bindings when configuring the JDT ASTParser.
[27/10/2015] Fixed NullPointerException taking place when the default constructor is called, but no such constructor declaration exists in the actual source code.
Bug fix in the parser for CCFinder clone detection results file.
Added a Clone Import Wizard supporting the import of clones from 5 popular clone detection tools, namely CCFinder, ConQAT, Deckard, NiCad, and CloneDR.
To use this feature go to Bad Smells -> Duplicated Code. This will open the "Duplicated Code" view for displaying the imported clone groups. Next, select a Java project from the Package Explorer, and click on the "Import Clones" button of the view.
Tons of bug fixes in Extract Clone Refactoring.
- Updated the detection of type-check elimination opportunities to support state variables having java.lang.String as type.
- Fixed the case where the classes of the inheritance hierarchy belong to the same CompilationUnit with the code performing the Runtime Type Identification (bug reported by jasyn).
- Tons of bug fixes in Extract Clone Refactoring.
[28/05/2015] The files containing the clones are opened in the editor before refactoring to avoid problems in the Undo history when applying successive Extract Clone refactorings.
[22/05/2015] Several bug fixes in Extract Clone Refactoring.
[07/05/2015] Fixed the refactoring of an if/else matched with a conditional expression (ternary operator).
- Excluded interfaces Serializable, Runnable, and Comparable from the list of accepted common super types.
- Improved the matching of variable declaration statements with assignment statements.
[22/04/2015] Extended method commonSuperType() in class ASTNodeMatcher to find also the common superInterface of two types (if there is no common superclass).
[16/04/2015] Improved precondition for the parameterization of differences to ignore incoming dependencies from advanced matched nodes.
[26/03/2015] The first stable version of the Control Structure Variant Clone Visualization and Refactoring feature is released.
- Fixed Extract Class Refactoring to make the extracted class implement the Serializable interface, if the source class implements the Serializable interface and at least one extracted field is non-transient.
- Fixed the extraction of thrown exceptions in PDG nodes. Class Instance Creations throwing exceptions are also taken into account in addition to method invocations.
- Added support for checking whether a method with the same name already exists in a class when performing an Extract Method Refactoring.
- Fixed a bug related to the handling of Synchronized blocks during the generation of the PDG.
- The updating of the model is no longer performed asynchronously. This bug caused model inconsistencies when detecting refactoring opportunities in the new code elements introduced by a previously applied refactoring.
- Added vertical scrolling to the Slice Profile table.
- Added support for collecting comments (i.e., line, block, and javadoc comments)
- Fixed the refactoring of clones already containing parameters with argN names (where N is an integer starting from 0)
- Fixed a bug in the Extract Method Refactoring mechanics
[21/09/2014] Updated the slice-profile view to display all local variables declared inside the body of the examined method.
Added an option that enables only the variables with a scope covering the entire method body.
[10/09/2014] Fixed the refactoring of clones with additionally matched statements coming from the advanced matching of control predicate statements.
[06/09/2014] Added support for the advanced matching of a VariableDeclaration statement having an initializer with a VariableDeclaration statement not having an initializer + an Assignment statement initializing the declared variable. See screenshots for details.
- [30/08/2014] Several fixes in Extract Clone Refactoring.
- Updated the search scope for sub-types using SearchEngine.createStrictHierarchyScope() introduced in JDT 3.6 This update improved significantly the performance of the search for sub-types.
- Added support for the advanced matching of different loop structures and if statements with expressions using the ternary operator. This feature was developed by Zackary Valenta as part of his NSERC USRA project.
- [20/07/2014] The first stable version of the Software Clone Visualization and Refactoring feature is released.
- Added support for Synchronized and Labeled statements in Extract Clone refactoring.
- Added support for pulling up additional duplicated methods called from the original clones in Extract Clone refactoring.
[29/03/2014] Fixed the matching of method invocations with method declarations having varargs parameters.
- Added analysis support for Enum types.
- Added analysis support for Labeled and Synchronized statements.
[22/02/2014] Clone Visualization bug fixes: a) fixed the matching of InfixExpressions, b) fixed a bug in the highlighting of differences for SimpleTypes.
- [21/12/2013] Improved the matching of method invocations with method declarations to address the cases where 'type parameter names' are replaced with actual types in the method calls.
- Improved the user interface of Extract Clone Refactoring, so that it presents multiple refactoring opportunities from a pair of methods in the same Wizard page (using a combo for allowing the user to select among the different refactoring opportunities).
- Added initial support for the mapping of if/else statements with expression statements containing a conditional expression (i.e., the ternary operator condition ? true : false).
- Fixed the handling of additional methods moved along with source method in Move Method Refactoring.
- Fixed the processing of if statements within the body of do-while loops in the construction of control flow graphs.
[06/10/2013] New Clone Visualization and Refactoring (Beta) support.
To use the new feature select two methods in the Package Explorer (holding the Ctrl key), right-click on one of the methods, and select "Refactor Duplicated Code..."
- All inner types are parsed regardless of their nesting level.
- Method calls with varargs are properly handled in method call analysis.
- Program Dependence Graph generation has been enhanced with a caching mechanism for internal method calls.
[02/09/2013] New Code Smell Package Map Explorer for Feature Envy and God Class!! This new visualization allows to explore the detected code smells at system level and discover relationships and dependencies between code smells. The visualization was developed by Kimberly Dextras-Romagnino as part of her NSERC USRA project.
[02/07/2013] Code Smell Visualizations have been enhanced with auto scrollbar adjustment and zoom support (from the View menu options or by scrolling the mouse wheel).
[21/06/2013] The binding returned from SimpleName expressions should be checked for NullPointer. Many thanks to Wei Wu (École Polytechnique de Montréal) for reporting the problem.
[13/06/2013] New Code Smell Visualizations for Feature Envy and God Class!! Whenever you double-click on a refactoring suggestion a View will open displaying a visualization for the corresponding code smell instance. The visualizations were developed by Kimberly Dextras-Romagnino as part of her NSERC USRA project.
[28/02/2013] Fixed a bug in the construction of control flow graphs. Many thanks to Danny Verloop (TU Delft) for reporting the problem.
[06/11/2012] JDeodorant was updated to support Union Types introduced in Java 7. Union types are mainly used in the new Multicatch feature.
[04/11/2012] JDeodorant was updated to support the Java Language Specification 4 (Java 7). This affected the construction of Control Flow and Program Dependence graphs, since try statements may declare resources in JLS 4. More details can be found at the JDeodorant ChangeLog.
[26/10/2012] Alias analysis in the detection of Extract Method refactoring opportunities (Long method code smell) caused in some cases an infinite recursion. The new implementation of alias analysis improves significantly the performance. This is an important update.
[09/10/2012] The exclusion of classes containing method with @Test annotations from the analysis may cause NullPointer exceptions (such a case was found in JUnit). As a result, test methods are not excluded from the analysis.
- [28/02/2012] Created a Standalone version of JDeodorant for the detection of refactoring opportunities from Eclipse applications.
The results of Type Checking bad smell are now reported in a tree view and are grouped per inheritance hierarchy or named constants.
- [16/11/2011] Added a new precondition for Move Method refactoring. The variable (parameter or field of target class type) through which the moved method will be invoked must not be assigned within the body of the candidate method to be moved.
- [04/09/2011] Fixed the unnecessary importing of nested types in all implemented refactorings.
- [22/04/2011] Several improvements in the identification process and presentation of Extract Class refactoring opportunities.
The application of the Extract Class Refactoring has been improved to handle the extraction of static members and the proper initialization of final fields in the extracted class when they are initialized inside constructors.
More details can be found at the JDeodorant ChangeLog.
- [15/03/2011] Added a user option in the input pages of the Move Method and Extract Class refactorings allowing to keep delegates to the public moved methods.
- [12/03/2011] Extract Class Refactoring has been implemented from scratch and several bugs have been fixed.
Added user rating support for the identified Extract Class refactoring opportunities.
- [09/01/2011] Try/catch blocks and throw statements are handled according to the approach proposed by Allen & Horwitz (2003).
Added a rule for the preservation of output dependences.
M. Allen, and S. Horwitz, "Slicing Java Programs that Throw and Catch Exceptions", ACM SIGPLAN Workshop on Partial Evaluation and semantics-based Program Manipulation, pp. 44-54, 2003.
- [25/12/2010] The unlabeled break and continue statements within the body of loops and the break statements within the body of switch statements are handled according to the augmented program dependence graph (APDG) approach proposed by Ball & Horwitz (1993), Kumar & Horwitz (2002).
T. Ball, and S. Horwitz, "Slicing Programs with Arbitrary Control Flow", First International Workshop on Automated and Algorithmic Debugging, pp. 206-222, 1993.
S. Kumar, and S. Horwitz, "Better Slicing of Programs with Jumps and Switches", Fifth International Conference on Fundamental Approaches to Software Engineering, pp. 96-112, 2002.
- [02/12/2010] Fixed a variety of problems related with the Type checking code smell.
- [08/11/2010] Added functionality allowing the user to rate each identified refactoring opportunity with a rating ranging from 0 to 5 stars. The ratings provided by the users will help JDeodorant team to improve the ranking mechanism that sorts the identified refactoring opportunities.
- [27/08/2010] Added support for code smell evolution analysis throughout successive versions of a given Java project. Just select an identified refactoring opportunity from the table view and click on "Evolution Analysis" button. JDeodorant will automatically analyze the evolution of the corresponding code smell in the relevant project versions loaded in the workspace. Eventually, JDeodorant will present a table showing the changes regarding the severity of the code smell among the successive project versions. Watch out the screencast showing the evolution analysis for a Feature Envy code smell.
- [12/07/2010] Added an Update Site for JDeodorant.
- [11/07/2010] The tool supports the identification of Extract Class refactoring opportunities for the decomposition of "God" classes. This feature is the outcome of a joint research effort with the SSRG Lab at the Department of Computing Science, University of Alberta.
- [01/07/2010] The speed of slice computation when constructing unions of slices has been significantly improved.
- [15/06/2010] A flexible calculator for slice-based cohesion metrics. Just right-click on a method from Package Explorer and click on "Slice-based Cohesion Metrics..." from the menu. The calculator will automatically compute the slices for all the variables which are declared within the body of the selected method and visually present its slice profile. The user can enable/disable any variable from the slice profile. The statements which are common to all enabled slices are highlighted in green color. The slice-based cohesion metrics (overlap, tightness, coverage) are dynamically re-calculated after each modification of the slice profile. See the screenshots for details.