We recently released the product JavaDepend. As its name suggest, this product is the java adaptation of NDepend. Including CppDepend for C++, we now have 3 products that share around 90% of the initial NDepend code base. Each product comes with its own analyzer layer to build the internal code model from .jar, .java, .dll, .exe files.
In case you are aware of XDepend, JavaDepend is a replacement for XDepend. A completely new product has been designed actually. The main and huge advantage of JavaDepend is that it is built over Mono because it works both on Windows and any Linux distribution. A JavaDepend Mac version is in the pipe.
I’d like to feedback here a few interesting notes on migrating a large legacy code base to Mono.
Before beginning any migration task, we needed to clearly evaluate the future pain points and have an idea of time and resources needed to achieve the migration. For these reasons we needed a tool to tell us which piece of code wasn’t properly managed by Mono.
The Mono Migration Analyzer (MoMA) tool did the job! This tool helps identify issues you may have when porting your .Net application to Mono. It helps pinpoint platform specific calls (P/Invoke) and areas that are not yet supported by the Mono project.
When we analyzed our binaries with MoMA , the main issues concerned our usage of the DevExpress DXperience Windows Form library. At this point we were confident that resolving this issue was the key for a successful migration.
Most of .NET professional program are based on some GUI libraries like the ones provided by DevExpress , Infragistics ,ComponentOne and so on. In NDepend we use DevExpress for the following benefits: Nice an Modern GUI components , Docking support, Theme support, Ribbon.
We searched for an alternative working on Mono but none of the mainstream GUI lib did the job. All these libraries use P/Invoke and thus, no one is mono compatible.
To solve this problem we then choosed to use the standard .NET Components. But if we modify all our code consuming GUI, we will have two versions to maintain, one for windows and another for linux. To avoid this problem we choose to develop a wrapper with a contract similar than the DevExpress DXperience classes NDepend is consumming.
What about DevExpress components and features not present in the standard framework?
- Docking: Unfortunately there’s no docking features in the standard framework, and no docking component working on mono with the same features as DevExpress exist, the only interesting one that works on mono is the Dock Panel Suite. We used this component but we disabled the drag&drop feature , to let it work on Mono. GTK# contains a docking container, but we can’t use it with standard winforms.
- Ribbon: We choosed to disable our look and feel using Ribbon, because no Ribbon component based on standard framework exist.
- Theme support: Same as Ribbon, we disabled changing theme feature, we didn’t find any interesting theme support.
- GDI+: NDepend relies massively on GDI+ for the Matrix,Treemap and Dependency graph views. Even if GDI+ is implemented on mono, we were not sure whether it was working as expected without any modifications. But to our positive surprise, the Mono implementation of GDI+ did the job! Bravo! I really have to congrat the Mono team here!
- P/Invoke: Fortunately, in JavaDepend code base we use rarely P/Invoke , and replacing them with a 100% managed code was not a difficult task.
Let’s mention 2 problematic Windows Form components not working properly on Mono:
- DataGridView/ListView: When working with these components on Mono, everything seems OK at first glance, but after some testing, many crashes appear. For all of them a System.ArgumentOutOfRangeException is thrown. There are many bugs opened concerning these issues, and we can’t afford waiting for a stable Mono release fixing them. For that we created our own components suited to our needs, based on the actual Mono source code. There, we see clearly the power of OSS!
- RichTextBox: When we want to use the Windows Form RichTextBox as a text editor for windows, many hacks are needed, and many of these hacks use P/Invoke. In the case of Mono, unfortunately there’s no way to hack to use the standard RichTextBox. The only way is to modify the Mono component code source. So we created our RichTextBox based on the existing code source, and like for the DataGridView, we adapted it to fulfill our needs.
All in all, this experience advocates for the fact that Mono has reached a level of maturity sufficient to run a professional application on it. The migration to JavaDepend took around 3 man months. As explained, there are still room for improvement, but still, Mono is an impressive project! I hope this feedback can be useful to you, dear reader, if you need to migrate a piece of .NET code to make it works outside of Windows. Good luck! … and long life to JavaDepend!