93

Is anyone attempting to implement C# for the JVM? As a Java developer, I've been eyeing C# with envy, but am unwilling to give up the portability and maturity of the JVM, not to mention the diverse range of tools for it.

I know there are some important differences between the JVM and CLR but is there anything that is a showstopper?

Rob
  • 5,112
  • 9
  • 36
  • 44
  • 3
    I've also written many, many fully multiplatform apps in Java - it's an everyday thing for me and my team. We do usually run the test plan on each platform we officially "qualify," but I think it's been years since a test bug has been attributed to a platform difference. – Jared Mar 25 '09 at 18:52
  • 1
    Our main product runs on Windows, OS X and Linux unchanged. It is really not hard to do. – Thorbjørn Ravn Andersen Aug 07 '09 at 21:07
  • I've done freelance development with java and it was amazing. My partner was using linux, I was using mac, and our customer was on windows.... what else can I say? – graffic Mar 11 '10 at 08:22
  • 1
    I do my Java in Windows, othe guy does his part in OSX, CI crunches all the tests under Linux and we've deployed the software to wide variety of both Windows and Linux servers and even Solaris. So I guess I could say that I've written truly, fully, multiplatform Java programs for a while now. – Esko May 01 '10 at 16:18
  • See alsow http://stackoverflow.com/questions/95163/differences-between-msil-and-java-bytecode/ – Motti Aug 09 '10 at 14:56
  • Why won't you simply use Groovy. It gives you probably everything you like in C# and miss in Java and it runs on JVM... –  Feb 28 '10 at 15:13
  • 1
    JavaVM implemented in .NET; .NET implementation of Java LIBS; interoperability of both worlds -> IKVM.NET (http://www.ikvm.net/) – gsscoder Dec 31 '12 at 20:20
  • 1
    Seems to me that if you can convert .NET to JavaScript (JSIL does this for example), you should be able to convert it to Java... – BrainSlugs83 Sep 23 '14 at 00:08
  • c# is a language, the CLR is irrelevant. If you take the specification for c# you could build a new compiler that compiles c# code to whatever. Imo it should be possible to make a JVM language based on the c# specification, but the CLR would be the JDK, the .net CLR would be completely gone from the implementation. You could still write c# and linq, but it would be backed by the JDK. So a class like Stream might not exist, instead you might have FileInputStream and FileOutputStream. – Ryan Mann Jul 02 '15 at 17:59

9 Answers9

94

There are very significant differences between the CLR and the JVM.

A few examples:

  • Java doesn't have user-defined value types
  • Java generics is completely different to .NET generics
  • Many aspects of C# depend on elements of the framework - delegates etc. You'd need to port the library as well, even for language aspects.
  • Java doesn't support things like properties and events at a JVM level. You could fake some of this, but it wouldn't be the same.
  • I don't believe Java has any equivalent to pass-by-reference parameters, even at the JVM level
  • Subtleties to do with the different memory models would quite possibly bite, although I'm not sure how much is in the C# spec.
  • Unsafe code in general probably isn't possible in Java
  • Interoperability with native code is very different between JNI and P/Invoke. This probably isn't much of a problem for you.
  • You'd have to fake operator overloading and user-defined conversions

You could probably port a lot of C# - but you'd be left with a pretty unsatisfactory experience, IMO.

Going the other way, are you aware of IKVM? It allows you to run Java code in .NET.

Jon Skeet
  • 1,261,211
  • 792
  • 8,724
  • 8,929
  • +1, It's been awhile since I did hardcore Java but I also believe the JVM does not support deterministic finalization. At least it did not at one point. There would need tho be the concept of finalization / destructors in order to properly implement a good chunk of C# code. – JaredPar Mar 25 '09 at 17:42
  • 7
    Java has finalizers, and .NET finalization isn't deterministic either. There may be some subtle differences between the two, but I can't think of any offhand. I suspect Java's reachability tests are stronger than .NET's though: no finalization while another thread is still running an instance method – Jon Skeet Mar 25 '09 at 17:45
  • @Jared - it has try/finally, so it would be pretty easy to add using-statement to Java. – Daniel Earwicker Mar 25 '09 at 17:46
  • 3
    I think you could map value types onto reference types. Just make every assignment do a shallow clone! – Daniel Earwicker Mar 25 '09 at 17:47
  • 3
    @Earwicker: ... and change array allocation, and various other places where the semantics make a difference? I suspect it would be *very* hard to get it to work, *if* it's possible, and the result wouldn't be something you'd want to use. – Jon Skeet Mar 25 '09 at 17:50
  • @Earwicker I'm more concerned with passive finalization. Passive finalization is often used (correctly or incorrectly) for native resoucre cleanup. – JaredPar Mar 25 '09 at 17:50
  • @Jon, when were finalizers introduced? Last time i played with Java was 1.4 or 1.5ish. I'm going to feel stupid if they were around back then but I didn't remember them. – JaredPar Mar 25 '09 at 17:51
  • 3
    @JaredPar: They've been in since Java 1.0. You override the finalize() method. – Jon Skeet Mar 25 '09 at 17:55
  • 2
    @Jon, wow. I didn't ever do much playing around with native resources in Java so I'm not terribly surprised I missed that but shocked none-the-less. Learn something new everyday (hopefully) – JaredPar Mar 25 '09 at 17:57
  • 2
    Re: value types - I'm not so sure. The set of things that need mapping is quite limited, and the fact is that the performance difference with struct vs class is typically extremely small; no doubt it would hurt some applications but probably not most. – Daniel Earwicker Mar 25 '09 at 18:17
  • 4
    I think generics would be solvable too. You'd have to generate a java class with extra fields to hold the Class objects for the type parameters, so it would add some overhead, but then new T() and typeof(T) would be available. – Daniel Earwicker Mar 25 '09 at 18:21
  • The type information of a *class* is available at runtime. The issue with Java generics is that type information associated with *instances of that class* is lost. If you are suggesting that you would change the actual class of an instance, this would surely break existing code – oxbow_lakes Mar 25 '09 at 22:35
  • I understand it would be hard to map the CLR on the JVM. Would it be possible to emulate a CLR on the JVM instead, so that managed code could be run? – Thorbjørn Ravn Andersen Aug 07 '09 at 21:13
  • Well you can emulate either on either... but it would probably be pretty slow. Look at ikvm though, which I believe runs Java on the CLR. – Jon Skeet Aug 07 '09 at 22:50
  • 30
    @Jon Skeet: That gives you the worst of both worlds: Java's somewhat outdated language on Microsoft's proprietary platform. – Bart van Heukelom Jul 02 '10 at 22:04
  • +1 for IKVM. I've successfully used it to compile an Apache library (distributed as a .jar file) for use in one of my .NET projects. – Roy Tinker May 09 '14 at 16:59
  • You could fake most of these -- for example, pass by reference could be faked with a compiler generated wrapper class... -- I don't understand why the entire .NET framework would need to be ported though, just small tiny parts of it (string, date, timespan, regex...) ... -- might just be easier to write a CLR that runs on the JVM though (if you can write one in C for x86, you can write one in Java for the JVM...) – BrainSlugs83 Sep 22 '14 at 23:59
  • 1
    Java also allows compiling java-byte code on the fly and injecting it into the JVM (Rhino does it -- has properties too!) -- so at worst Generics could be faked as well... -- but also, that opens up the door for DLR type stuff... – BrainSlugs83 Sep 23 '14 at 00:04
  • @BrainSlugs83: I strongly suspect that by the time you've faked all that, or implemented the CLR on the JVM, you would end up with a system which was impractical from a performance perspective. And making things like pass by reference work via a wrapper class *sounds* simple - but the corner cases involved would take a *lot* of care to get right, I suspect. – Jon Skeet Sep 23 '14 at 05:43
  • @JonSkeet several years later, we know for sure that Java’s reachability is not stronger than .NET’s; finalization is possible while another thread is still running an instance method and [it can truly hurt](https://bugs.openjdk.java.net/browse/JDK-8145304)… – Holger Feb 06 '18 at 15:08
  • I think what you are listing is the feature differences between Java and C#, not JVM and CLR. – Su Excelle Oct 30 '20 at 20:34
  • @SuExcelle: For some things there's a fuzzy boundary, but things like user-defined value types, .NET-style generics, unsafe code, and pass-by-reference are definitely VM/CLR features. (You could "fake" some of them with workarounds that have terrible performance, but they're still differences in the underlying capabilities of the VMs.) – Jon Skeet Oct 31 '20 at 07:30
43

Visit http://code.google.com/p/stab-language

The code below if a Stab language code for JVM

using java.lang;
using stab.query;
public class Test {
   public static void main(String[] args) {
   // Sorts the arguments starting with "-" by length and then using the default   
        // string comparison
        var query = from s in Query.asIterable(args)
                    where s.startsWith("-")
                    orderby s.length(), s
                    select s;
        foreach (var s in query) {
            System.out.println(s);
        }
    }
}
Sampson
  • 251,934
  • 70
  • 517
  • 549
Vns
  • 431
  • 4
  • 2
  • 7
    stab delivers much of the meat of C# language on JVM but does so in a way that is very Java inter-operable. So it's not strictly source code compatible to C# code written for the .NET CLR but it does enable a Java programmer to enjoy a very C# like language while getting the same quality byte code generated and having non-impedance interoperability with Java libraries and frameworks. It's the right approach to take for getting C# on the JVM. – RogerV Jul 24 '10 at 14:53
  • 1
    The good language, on the good platform... wish I'd stumbled on this years ago. – Jefferey Cave Jan 09 '14 at 18:30
15

Bytecode transpilers

Grasshopper can take a CLR bytecode and transpile it for JVM. Intended primarily for web apps, it does not provide e.g. JVM implementation of Windows Forms classes. Seems somewhat dated, though. The web talks about ASP.NET 2.0, Visual Studio 2008 and so on. First mentioned by @alex

XMLVM can take CLR or JVM bytecode as input and produce either as output. Additionally it can output Javascript or Objective-C. No releases yet, only Subversion. "Experimental development version that is not to be used in a production environment."

IKVM goes in the other direction than OP wants. It provides a JVM implementation running on CLR, a JVM to CLR bytecode transpiler and a CLR library method stub generator for Java. http://www.ikvm.net/uses.html Mentioned by @Jon Skeet

RPC

Why not have CLR and JVM running alongside and make the communication as much frictionless as possible? This is not what the OP wants, but some other answers are already quite off topic in different ways, so let's cover it.

RabbitMQ, has a free option, it is a RPC server written in Erlang with API libraries for C#, Java and more.

jnBridge, the licence may be too expensive for some prospective users.

gRPC, and similar modern RPC libraries offer wide language support, code generation for client libraries in these languages, language independent wire format for data, advanced features like cascading call-cancellation and so on.

Programming languages

Write once, run everywhere ;)

Haxe, compiles to C#/CLR, Java/JVM, Javascript, Flash, Python, … Provides interop mechanisms for each of the target languages. Can be thought about as an ActionScript3 successor to some degree. Seems pretty solid stuff, with at least one company actually depending on it. Much more trustworthy than Stab, mentioned next.

Stab brings some C# features and Java interoperability. Not very useful, you get some C# features, but what you interact with is Java code which does not use them. https://softwareengineering.stackexchange.com/a/132080/45826 The language is relatively obscure, possibly abandoned, with little promise to become better. First mentioned here by @Vns.

Gust of fresh air for the JVM platform ;)

Scala, Kotlin, others, are fairly nice languages running on top of JVM which bring features that a C# programmer may miss in Java. Especially Kotlin feels like a reasonable alternative to C# in the JVM world. Scala may be a bit too large language for a programmer to get comfortable with in a short time.

Mono

That is certainly an option too. Why transpile to JVM if Mono can run it as it is. First mentioned by @ferhrosa

NEW YORK — Nov. 12, 2014 — On Wednesday, Microsoft Corp. reinforced its commitment to cross-platform developer experiences by open sourcing the full server-side .NET stack and expanding .NET to run on the Linux and Mac OS platforms.

According to this press release from which the quote comes, Visual Studio 2015 will add Linux/Mono as a supported platform.

This is a blog written by the Mono project people about it, from the other side: .NET Source Code Integration (November 2014).

.NET Core

A Windows/Linux multiplatform version of (some of) .Net governed by Microsoft. 'nuff said https://github.com/dotnet/core.

Conclusion

It would be now necessary to give these tools/frameworks a try and see how much friction there is. The OP wants to write in C# for the JVM, which may actually work quite well using Grasshopper.

Doing this with the goal to mix C# and Java world libraries in a single codebase may not work so well.

Sources

http://blog.pluralsight.com/new-course-making-java-and-c-work-together-jvm-and-net-clr-interop

Community
  • 1
  • 1
user7610
  • 17,196
  • 7
  • 97
  • 120
  • Great answer! As a C# developer who is unhappy with having to transition to Java (how can you live without properties?!), and is dubious about Scala, this really lays out the options well. – Gilthans Mar 15 '15 at 20:45
9

It might be simpler to write a converter from IL to bytecode. That way you'd automatically get support for any .NET language on the JVM.

However, this is such an obvious idea that if this hasn't already been done, it's probably extremely hard, or hard to do well/usefully.

Daniel Earwicker
  • 108,589
  • 35
  • 194
  • 274
  • 6
    You'd run into most of the problems I listed - different generics etc. – Jon Skeet Mar 25 '09 at 18:10
  • 8
    This is exactly what Grasshopper does (see @alex's answer above) it is indeed extremely hard to do well (I used to work on Grasshopper). – Motti Aug 09 '10 at 14:55
7

Look at Grasshopper. It is a Visual Studio-based SDK and patented .NET to Java converter that enables you to run .NET Web and server applications on Linux® and other Java-enabled platforms.

alex
  • 67,783
  • 9
  • 46
  • 57
2

An option for cross-platform development in C# could be mono: http://www.mono-project.com/

ferhrosa
  • 1,569
  • 2
  • 9
  • 5
1

You can use a source-to-source compiler to translate C# into a language than runs on the JVM. For example, there are several C# to Java converters that would allow C# applications to run on the JVM after being translated into Java.

Anderson Green
  • 25,996
  • 59
  • 164
  • 297
0

This answer may be late for you, but this one is just new. You may want to checkout Kotlin programming language. It offers the syntactic sugars which C# has and its the closest to C# syntax too, other than any Non-Java JVM language. Its from JetBrains.

LEMUEL ADANE
  • 6,680
  • 14
  • 48
  • 64
0

I can see two reasons why this isn't getting much enthusiasm.

The first thing to realise is that, when it comes to the actual features of the language, C# and Java are very close. Not only are C# amd Java close, they are also moving in similar directions. There are some features that the JVM won't currently support out of the box, but that's not the real problem. You can always fake what is missing. I think people prefer waiting for Java to get some more sugar, than to create an Almost-Java from scratch. By the time the port is ready, Java may have decided to catch up.

Secondly, the reason why developers prefer C# isn't so much the language itself, but the tools around it, their two-way relationship with C# and how Microsoft supports the whole thing. For example, the C#-XAML combo is friendlier than JavaFX, because C# and XAML were hacked for eachother (e.g. partial classes in C#, bindings in XAML and more). Using C# on JavaFX doesn't improve much. To get the C# experience on the JVM, you need to also port the tools, and that's a much bigger project. Not even Mono will bother.

So, my advice to a Java developer, who wants to use a fancier language ontop of familiar tools, is to check out the existing JVM languages.

Mono is an option too, but I have always been skeptical of it. Even though it is C#-.NET and cross-platform, things built with Microsoft's tools won't generally work on Mono. It is essentially its own thing. We'll see what happens now that Microsoft said they'll be collaborating.

Chris
  • 391
  • 4
  • 12