170

In What would you choose for your project between .NET and Java at this point in time? I say that I would consider the "Will you always deploy to Windows?" the single most important technical decision to make up front in a new web project, and if the answer is "no", I would recommend Java instead of .NET.

A very common counter-argument is that "If we ever want to run on Linux/OS X/Whatever, we'll just run Mono"1, which is a very compelling argument on the surface, but I don't agree for several reasons.

  • OpenJDK and all the vendor supplied JVM's have passed the official Sun TCK ensuring things work correctly. I am not aware of Mono passing a Microsoft TCK.
  • Mono trails the .NET releases. What .NET-level is currently fully supported?
  • Does all GUI elements (WinForms?) work correctly in Mono?
  • Businesses may not want to depend on Open Source frameworks as the official plan B.

I am aware that with the new governance of Java by Oracle, the future is unsafe, but e.g. IBM provides JDK's for many platforms, including Linux. They are just not open sourced.

So, under which circumstances is Mono a valid business strategy for .NET-applications?


1Mark H summarized it as: "If the claim is that "I have a windows application written in .NET, it should run on mono", then not, it's not a valid claim - but Mono has made efforts to make porting such applications simpler."

17
  • 24
    Just to be clear, .NET is Microsoft's implementation of the CLI. Mono is a CLI implementation with Novell taking lead. Nov 20, 2010 at 17:47
  • This sounds a lot more like an answer to the previous question rather than a question in its own right. I would suggest you consider editing your question to make it stand more on its own.
    – Walter
    Nov 20, 2010 at 18:06
  • 2
    @walter, the whole point is that I am aware of the usual "java is more cross-platform than .NET"-arguments, and I list them to make the answers incorporate the best possible counter-arguments.
    – user1249
    Nov 20, 2010 at 18:15
  • 1
    This is off-topic for the question. Head over to a business planning site and browse some sample plans to see what is truly crucial for a business... Tech X vs Tech Y is about as crucial as FedEx debating Ford vs. GM for delivery vans.
    – red-dirt
    Aug 18, 2011 at 21:50

10 Answers 10

195

Sparkie's answer got it, let me complement a little.

".NET is cross platform" is too much of an ambiguous statement as both the framework and the world it was originally created for have changed and evolved.

The short answer is:

The underlying engine that powers .NET and its derivatives, the Common Language Infrastructure Standard, is cross-platform and as if you want to make your code go to multiple platforms, you need to plan on using the right APIs on the right platform to deliver the best experience on each platform.

The CLI family has not tried the "Write Once, Run Anywhere" approach, as the differences from a phone to a mainframe are too big. Instead a universe of API and runtime features that are platform-specific has emerged to give developers the right tools to create great experiences in each platform.

Think of it: programmers no longer target Windows PCs or Unix Servers. The world, now more than ever is surrounded by fascinating platforms from PCs, to gaming consoles, to powerful phones, to set-top boxes, to big servers and distributed clusters of machines. A one-size fits on all platform would merely feel bloated on tiny devices, and feel underpowered on large systems.

The Microsoft's .NET Framework product is not cross platform, it only runs on Windows. There are variations of the .NET Framework from Microsoft that run on other systems like the Windows Phone 7, the XBox360 and browsers through Silverlight, but they are all slightly different profiles.

Today you can target every major mainstream OS, phone, mobile device, embedded system and server with .NET-based technologies. Here is a list that shows which CLI implementation you would use in each case (this list is not comprehensive, but should cover 99% of the cases):

  • x86 and x86-64 based PC computers:
    • running Windows -> Typically you run .NET or Silverlight but you can also use full Mono here.
    • running Linux, BSD or Solaris -> You run full Mono or Silverlight
    • running MacOS X -> You run full Mono or Silverlight
    • running Android -> You run Mono/Android subset
  • ARM computers:
    • Running Windows Phone 7: you run Compact Framework 2010
    • Running Windows 6.5 and older: you run the old Compact Framework
    • Android devices: you run Mono/Android
  • PowerPC computers:
    • You run full Mono for full Linux, BSD or Unix operating systems
    • You run embedded Mono for PS3, Wii or other embedded systems.
    • On XBox360, you run CompactFramework
  • S390, S390x, Itanium, SPARC computers:
    • You run full Mono
  • Other embedded operating systems:
    • You run .NET MicroFramework or Mono with the mobile profile.

Depending on your needs the above might be enough or not. You will hardly get the same source code to run everywhere. For example, XNA code wont run on every desktop, while .NET Desktop software wont run on XNA or the phone. You typically need to make changes to your code to run in other profiles of the .NET Framework. Here are some of the profiles I am aware of:

  • .NET 4.0 Profile
  • Silverlight Profile
  • Windows Phone 7 Profile
  • XBox360 Profile
  • Mono core Profile - follows the .NET profile and is available on Linux, MacOS X, Solaris, Windows and BSD.
  • .NET Micro Framework
  • Mono on iPhone profile
  • Mono on Android Profile
  • Mono on PS3 Profile
  • Mono on Wii Profile
  • Moonlight profile (compatible with Silverlight)
  • Moonlight extended profile (Silverlight + full .NET 4 API access)

So each one of those profiles is actually slightly different, and this is not a bad thing. Each profile is designed to fit on its host platform and expose the APIs that make sense, and remove the ones that do not make sense.

For instance, Silverlight's APIs to control the host browser do not make sense on the phone. And shaders in XNA make no sense on PC hardware that lacks the equivalent support for it.

The sooner you realize that .NET is not a solution to isolating the developer from the underlying capabilities of the hardware and the native platform, the better off you will be.

That begin said, some APIs and stacks are available in multiple platforms, for example ASP.NET can be used on Windows, on Linux, on Solaris, on MacOS X because those APIs exist both on .NET and Mono. ASP.NET is not available on some of Microsoft's supported platforms like XBox or Windows Phone 7 and is not supported either on other platforms that Mono supports like the Wii or the iPhone.

The following information is only correct as of November 21st, and many things in the Mono world will likely change.

The same principles can be applied to other stacks, a full list would require a proper table, which I have no idea of how to present here, but here is a list of technologies that might not be present on a particular platform. You can assume that anything not listed here is available (feel free to send me edits for things I missed):

Core Runtime Engine [everywhere]

  • Reflection.Emit Support [everywhere, except WP7, CF, Xbox, MonoTouch, PS3]
  • CPU SIMD support [Linux, BSD, Solaris, MacOS X; Soon PS3, MonoTouch and MonoDroid]
  • Continuations - Mono.Tasklets [Linux, BSD, Solaris, MacOS, PS3, Wii]
  • Assembly Unloading [Windows only]
  • VM Injection [Linux, BSD, MacOS X, Solaris]
  • DLR [Windows, Linux, MacOS X, Solaris, MonoDroid]
  • Generics [some limitations on PS3 and iPhone].

Languages

  • C# 4 [everywhere]
  • C# Compiler as a Service (Linux, MacOS, Solaris, BSD, Android)
  • IronRuby [everywhere, execpt WP7, CF, Xbox, MonoTouch, PS3]
  • IronPython [everywhere, execpt WP7, CF, Xbox, MonoTouch, PS3]
  • F# [everywhere, execpt WP7, CF, Xbox, MonoTouch, PS3]

Server Stacks

  • ASP.NET [Windows, Linux, MacOS, BSD, Solaris]
  • ADO.NET [everywhere]
  • LINQ to SQL [everywhere]
  • Entity Framework [everywhere]
  • Core XML stack [everywhere]
    • XML serialization [everywhere, except WP7, CF, Xbox)
  • LINQ to XML (everywhere)
  • System.Json [Silverlight, Linux, MacOS, MonoTouch, MonoDroid]
  • System.Messaging [Windows; on Linux, MacOS and Solaris requires RabbitMQ]
  • .NET 1 Enterprise Services [Windows only]
  • WCF [complete on Windows; small subset on Silverlight, Solaris, MacOS, Linux, MonoTouch, MonoDroid]
  • Windows Workflow [Windows only]
  • Cardspace identity [Windows only]

GUI stacks

  • Silverlight (Windows, Mac, Linux - with Moonlight)
  • WPF (Windows only)
  • Gtk# (Windows, Mac, Linux, BSD)
  • Windows.Forms (Windows, Mac, Linux, BSD)
  • MonoMac - Native Mac Integration (Mac only)
  • MonoTouch - Native iPhone Integration (iPhone/iPad only)
  • MonoDroid - Native Android Integration (Android only)
  • Media Center APIs - Windows only
  • Clutter (Windows and Linux)

Graphic Libraries

  • GDI+ (Windows, Linux, BSD, MacOS)
  • Quartz (MacOS X, iPhone, iPad)
  • Cairo (Windows, Linux, BSD, MacOS, iPhone, iPad, MacOS X, PS3, Wii)

Mono Libraries - Cross Platform, can be used in .NET but require manually building

  • C# 4 Compiler as a Service
  • Cecil - CIL Manipulation, workflow, instrumentation of CIL, Linkers
  • RelaxNG libraries
  • Mono.Data.* database providers
  • Full System.Xaml (for use in setups where .NET does not offer the stack)

MonoTouch means Mono running on iPhone; MonoDroid means Mono running on Android; PS3 and Wii ports only available to Sony and Nintendo qualified developers.

I apologize for the lack of formality.

7
  • 2
    IBM, If you read this, I would like AIX (or even AS/400) to be on Miguels list!!
    – user1249
    Nov 22, 2010 at 7:59
  • 4
    thanks for a definite, authorative (sp?) answer!
    – user1249
    Nov 22, 2010 at 8:02
  • 10
    We know that IBM has done at least two ports of Mono to AIX, but the teams that did the port were not allowed to release the changes back. Nov 23, 2010 at 1:24
  • 3
    +1 - This guy should be working on the Mono Project! Please don't take the bait ;)
    – JeffO
    Jan 4, 2012 at 16:12
  • 1
    @JeffO: This guy is the creator of Mono ;-)
    – seoul
    Mar 22, 2013 at 14:32
115

First, you need to make a distinction between the Common Language Infrastructure (The open standard), and .NET (Microsoft's implementation of that standard). Mono is an implementation of the CLI, and has never claimed to be a "portable .NET". Also, the C# language is an open standard, and is not strictly tied to .NET.

I'm not aware whether Microsoft have any tool to validate that an implementation is compliant, but if they do, I'm pretty sure the mono guys have it, and use it.

Mono is trailing behind the .Net, but barely. Mono can run C# 4.0 code (current .NET version). Also, Microsoft have recently made all DLR code and libraries open source (under the Apache 2.0 license), which has enabled mono to make use of languages like IronPython, IronRuby, and F# has been made open source only last week. In addition, Microsoft are regularly releasing CTPs of upcoming features in .NET, which allows mono developers to keep up to date with current release versions.

There's a number of tools and extensions in .NET, for example, Code Contracts. These aren't always implemented fully in mono. (At present, I think there is a partial contract validator for Requires contracts). These aren't commonly used in .NET apps anyway, but if their popularity increased, so would the rate at which they get implemented in mono.

WinForms are not (entirely) portable. They are a .NET specific and not part of the CLI. The CLI does not specify any particular widget set. There are cross platform widget sets though (GTK# and Silverlight). If you were writing an application from the ground up with portability in mind, you would use one of these rather than Winforms/WPF. In addition, mono provides a thin wrapper for the Winforms API - which enables existing winforms apps to be ported more easily into GTK# (without entire rewrite).

Mono provides a tool, the Mono Migration Analyser (MoMA), which can take an existing .Net application and tell you about it's portability. (eg, identify unportable libraries that are used, P/Invokes etc).

For businesses that don't want to depend on Open Source - mono can be re-licensed. Ownership of code added to mono is handed over to novell, who can license it in alternative ways other than the usual LGPL license (which has very few restrictions anyway).

So as for the claim ".NET is portable", I think this can be a valid assertion if you are writing code from the ground up and are aware of the portability issues with the framework. If the claim is that "I have a windows application written in .NET, it should run on mono", then not, it's not a valid claim - but Mono has made efforts to make porting such applications simpler.

14
  • 20
    +1 for the last paragraph.
    – Davy8
    Nov 20, 2010 at 19:36
  • 4
    the C# language is an open standard, and is not strictly tied to .NET. and C# 4.0 code (current .NET version) are contradictory
    – Jader Dias
    Nov 20, 2010 at 23:11
  • 9
    Your last point is a good one, and equally applies to Java. Just because you've coded your app in Java doesn't mean it's automatically portable to every platform that supports Java. Particularly for more complex projects, you find many Java applications have platform-specific code. Nov 21, 2010 at 5:29
  • 5
    @user8057: Winforms is 100% implemented? Seriously? Check out the RichTextBox component. Check out drag and drop functionality on the Tree component. Swing is 100% cross-platform, on the other hand, though that might mean sucking on all platforms. Nov 21, 2010 at 21:53
  • 2
    @Yar: LOL for "though that might mean sucking on all platforms" :-)
    – Wizard79
    Nov 22, 2010 at 9:35
14

Point by point:

  • OpenJDK and all the vendor supplied JVM's have passed the official Sun TCK ensuring things work correctly. I am not aware of Mono passing a Microsoft TCK.
    There is a specification that the Microsoft CLR conforms to. Mono is not a clone of Microsoft's CLR, but rather an implementation of that same specification. On the one hand, there's the chance that this results in even greater incompatibility. In practice, this has worked very well for mono.
  • Mono trails the .NET releases. What .NET-level is currently fully supported?
    Because the documentation for .Net precedes the actual release, mono actually had completed (not a beta release) support for .Net 4 out before the official Microsoft release. Additionally, mono does a very good job of documenting what things are not supported, and they have a few tools you can run against existing project to help you spot places with the potential for incompatibility.
  • Does all GUI elements (WinForms?) work correctly in Mono?
    The vast majority of winforms works just fine. WPF, not so much. I've heard that the same is true for Java — many of the advanced widget/gui toolkits aren't as well supported on all platforms.
  • Businesses may not want to depend on Open Source frameworks as the official plan B.
    If that's the case, they definitely won't be going with Java, then, as that puts an open source framework up even higher at plan A.

In summary, if you want to build a cross-platform app right now, there's nothing wrong with starting with mono from the get-go and using that as your framework. You can even deploy mono on Windows if you want.

On the other hand, if you you're looking at building a Windows app today that you think might need to be cross platform at some unknown point in the future, you probably want to go with the native Windows widgets and tools. .Net does a much better job here than does Java, and mono is a perfectly acceptable fall back in this scenario.

In other words: Yes, .Net if cross-platform in every way that matters to your question. No, mono won't just run every .Net program out of the box, but your question is in the context of a new project. It doesn't take much work to keep new projects out of trouble and avoid compatibility issues, especially if you think in terms of developing for mono rather than developing for .Net.

Most of all, though, I think this is the wrong question in the first place. Unless you're building a new development team from scratch, you're starting with programmers that have expertise in one area or another. Your best results will be achieved by going with what your programmers already know. As important as building a cross-platform app may seem, if you have a team full of .Net programmers with little java experience, you're unlikely to fire them or make them all learn java for your next project. If you have a team full of java programmers, you're not gonna ask them to learn .Net for a Windows-only project. Either of those would be nuts.

8
  • Just to clarify the "open source" issue: I was thinking of an open source project as not being backed by a suable business entity, not as a business having a GPL'ed source code.
    – user1249
    Nov 21, 2010 at 10:33
  • 3
    Novell is not “a suitable business entity”?
    – svick
    Nov 21, 2010 at 13:53
  • @svick - I don't think "suable" is typo. He's worried about legal issues surrounding the project's backers. Nov 21, 2010 at 19:20
  • @Thorbj From a business perspective, it's better to have a strong supporting entity like Novell than an abstract entity like the JCP. Nov 21, 2010 at 19:21
  • @user8057 Ah, I've never heard that word. It looked like a strange typo.
    – svick
    Nov 21, 2010 at 19:25
11

I have worked with Mono, and I would say it is as good as you can get with an alternate platform that is open-source, and not directly supported by Microsoft. If you can be comfortable using an alternate open-source platform like Clojure or Scala, you could probably be comfortable with using Mono.

The level of .NET supported by Mono can always be found on the Mono Roadmap page.

Do all GUI elements work? As far as I know, they do, although I haven't exhaustively tried every element.

Is Mono identical to .NET? No. I suspect there will be minor (and maybe major) tweaks required here and there. You can't, at present, run the Entity Framework with it, for example.

4
  • Of course Mono isn't an exact clone but from what I've seen it is a very viable option when beginning new projects. Nov 20, 2010 at 17:51
  • Is the character in you pic 美 me3i? from 美国?
    – Jader Dias
    Nov 21, 2010 at 1:14
  • 1
    @Jader, totally unrelated - but that's the chinese character for beautiful and 美国 (when combined means US, also literally means beautiful country)
    – aggietech
    Sep 19, 2011 at 16:22
  • AFAIK Clojure and Scala are languages not platforms. And (again AFAIK) Scala should run on any JVM implementation on which Java can run.
    – Giorgio
    Sep 7, 2012 at 18:33
9

As a target, the .NET/mono universe moves very fast.

Every few years, Microsoft comes out with some compelling changes and innovations regarding the language, runtime, and infrastructure surrounding .NET. For example: Generics, LINQ, DLR, Entity Framework -- with every new revision of Visual Studio, there's generally a pretty significant increase in the feature set and usefulness of the framework it targets.

While the constant improvement in the framework is welcome, it's also problematic if you want compatibility across multiple platforms. Long-term-support platforms like Red Hat Enterprise Linux move glacially slow with regards to adopting new technology, and at any given point, there's going to be significant improvements in the Mono platform that have happened just within the last few months. So if you want to run the stuff that the cool kids are building, you're going to have to compile Mono from scratch and manage your own patches and updates. That's not cool.

Java, on the other hand, is as stagnant as a kiddie pool. Especially now that it's own by a company that just wanted Java for the patent lawsuits, you can be fairly certain that there will be no detectable changes in the language or runtime in the foreseeable future. Java is as stable a platform as FORTRAN. That's not so good if you were hoping for any sort of improvements, but not so bad if you're trying to deploy an enterprise application.

4
  • Funny you mention Fortran, as it is evolving constantly with emphasis on concurency and parallazetion as well as OOP principles. So yes Fortran 77 is stable, but since Fortran 90 came out, each revision gets better and better. Fortran 2008 is "almost" a modern language. Nov 21, 2010 at 7:28
  • 4
    I'd say that .Net/C# 1.0 was at best a poor Java clone, but by .Net 2.0 there was pretty good feature parity between the two platforms. Going from there to .Net 3.5/C# 3, Microsoft's platform has left Java well behind in most areas and it continues to gain ground with new features like dynamic typing and upcoming features like async concurrency. That said, one big reason .Net is able to move so fast is the trail left by Java. If Oracle wants to move Java forward they will be able to quickly follow the similar trail now left by Microsoft. Nov 21, 2010 at 19:25
  • "the .NET/mono universe moves very fast". Ironically, the main reason we don't use Mono is that its GC development has been excruciatingly slow. They described the current stable GC as an "interim measure" in 2003! lists.ximian.com/pipermail/mono-gc-list/2003-August/000012.html
    – J D
    Jan 5, 2011 at 19:48
  • Or you can just run Debian/Ubuntu, use a few external apt repositories, and play with the cool kids without compiling mono from scratch.
    – Quandary
    Mar 9, 2013 at 8:21
7

From a user perspective, Mono sucks at making Windows .NET apps compatible with Linux. If you actually try to run any decently written Windows app in Mono it wouldn't work.

From a packager's perspective (I used to do a bit of work at PortableApps), .NET can be both a blessing and a curse. If you're only on Windows, .NET makes deployment a lot easier because more libraries means less system-dependent stuff (most notably between versions of Windows, I believe) but is also extremely confusing even on Windows because .NET versions are neither backwards-compatible or forwards compatible. You have to download different versions of .NET for different programs.

That said, Mono is a fine starting point for making C# programs cross-platform. Just don't package the program with the latest WINE and call it done though. Look where that took Picasa.

As with the two languages/platforms political stability, RMS would probably start ranting on about how Mono is headed by Novell, whose honeymoon with Microsoft is quite notorious. Both platforms can be considered politcally unstable right now.

If you really want easy cross-platform, the tried and true path is QT which is quite stable politically as of right now it's a) LGPL'd, b) done with its major licensing issues years past, and c) backed by Nokia, which sells really really popular phones.

1
  • 5
    How quickly things change. Nokia no longer sells phones people want, and Novell no longer exists with both Qt and Mono's future in doubt. This is probably the reason why businesses don't like using anything other than 'primary-supported' systems, like Microsoft. Which is why open source is such a good idea.
    – gbjbaanb
    May 10, 2011 at 10:27
4

Mono is not a 1:1 port of Microsoft's .net. There are technologies that Mono simply won't implement or has no plans to do so (e.g., Workflow Foundation or WPF) while on the other hand they have some technologies of their own that Microsoft .NET doesn't do, e.g., SIMD Extensions.

Short Answer: Mono and Microsoft .NET are based on the same underlying foundation - CIL and BCL - but are separate projects.

2

Small comment to the statements in the original post. I'll argue that the TCK remains a theoretical tool allowing Oracle to claim Java is an open standard. Because if you notice, Apache Harmony have been trying to get certified as "Java" for several years now, unsuccessfully. It's clear that Oracle really isn't interested in an open source implementation apart from the one they are affiliated with and more or less control (OpenJDK), which btw. much like Mono, is not complete (i.e. no Java Web Start support) and missing some optimizations available in the closed source HotSpot implementation.

So arguably, as of 2010; (most of) Java is open source but not an open standard, while (most of) .NET is not open source but an open standard. There are exceptions of course, the DLR, IronPython, IronRuby and F# actually are open source. Mono is interesting because it provides the best of both worlds, open source implementations of open standards.

1
  • The openness of Java is not the important part as such. It is my experience that my programs run well on the JVM's that have passed the TCK so that is an important parameter.
    – user1249
    Sep 19, 2011 at 14:16
1

Putting all technicalities aside, a very important part takes place when actually writing the code.

As with any cross-platform technology (be it Java, Python, Ruby...), if the code is not written with portability in mind, you should assume there's basically zero chance the code will run properly (even if such a chance is in reality much, much higher), as the odd misbehavior could be quite critical. Read: don't take the random assembly and run it under Mono.

Yet for a new project (or one you can refactor easily), choosing .Net/Mono as a potentially portable runtime makes sense, but you save yourself a lot of hassles by testing your code on Mono very early on, even if the project has only a slight change of going multiplatform. If you use a continuous integration server, this can be as simple as setting up a Mono build node. Many issues can be solved while developping, just by making a habit out of it (like building path strings) and a huge chunk of your code can be portable and unit-tested on Mono just by using sane practices and a little bit of forethought. The remainder (i.e failing unit tests) is then platform-specific (like code using PInvoke) but should be encapsulated enough so as to be able to provide an alternative implementation per targeted platform. This way when the project eventually comes to being ported a good part of the work has been done at almost no cost and the remainder is to be developped Just In Time.

Of course, using a library not available (.Net) or compatible (third party) in Mono precludes any of this, but in my field this has yet to be seen. That is the strategy we actually use at work, and when applying it I have no fear of claiming that .Net+Mono is cross platform.

0

It varies is the honest answer. I have seen small web server stuff moved from IIS to Apache, running under mono with almost no difficulty. I have run unchanged Windows .Net applications using Win Forms on Linux successfully.

However, whilst it can work, if you are using an API call that's not implemented on mono then it won't work, and the only solutions are to either rewrite your application, stick with windows or write the extra stuff in mono.