I'd like to know good strategies for deploying a domain-specific-language which must run under at least 2 languages (Java, C#) and probably more (Python, and possibly Javascript).
Some background. We have developed and deployed a domain-specific language currently written in C#. It's deployed though a series of method calls whose arguments are either common language primitives (string, double, etc.), Collections (IEnumerable, HashSet, ...) or objects in a domain-specific library (CMLMolecule, Point3, RealSquareMatrix). The library is well tested and the objects have to comply to a stable deployed XML schema so change will be evolutionary and managed (at least that's the hope).
We hope the language will become used by a wide and partially computer-literate community, used to hacking their own solutions without central control. Ideally the DSL will create a degree of encapsulation and produce the essential functionality they need. The libraries will manage the detailed algorithms which are many and varied but fairly well known. There's a lot in common with the requirements of the DSL in Domain-specific languages vs. library of functions.
I'd appreciate ideas on the best architecture (clearly once it's deployed we cannot easily backtrack). The choices include at least:
Creation of an IDL (e.g. through CORBA). The W3C did this for the XML DOM - I hated it - and it seems to be overkill
manual creation of similar signatures for each platform and best endeavour to keep them in sync.
Creation of a parsable language (e.g. CSS).
declarative programming in XML (c.f. XSLT). This is my preferred solution as it can be searched, manipulated, etc.
Performance is not important. Clarity of purpose is.
EDIT There was discussion as to whether application calls contitute a DSL. I have discovered Martin Fowler's introduction to DSLs (http://martinfowler.com/dslwip/Intro.html) where he argues that simple method calls (or chained calls) can be called a DSL. So a series like:
point0 = line0.intersectWith(plane);
point1 = line1.intersectWith(plane);
midpoint = point0.midpoint(point1);
could be considered a DSL
There seems to be some ambiguity in the question between language and library. The terms "internal DSL" and "external DSL" are useful, and I think are due to Martin Fowler.
An "external" DSL might be a standalone command-line tool. It is passed a string of source, it parses it somehow, and does something with it. There are no real limits on how the syntax and semantics can work. It can also be made available as a library consisting mostly of an eval-like method; a common example would be building a SQL query as a string and calling an execute method in an RDBMS library; not a very pleasant or convenient usage pattern, and horrible if spread around a program on a large scale.
An "internal" DSL is a library that is written in such a way as to take advantage of the quirks of a host (general purpose) language to create the impression that a new language can be embedded inside an existing one. In syntactically-rich languages (C++, C#) this means using operator overloading in ways that seriously stretch (or ignore) the usual meanings of the operator symbols. There are many examples in C++; a few in C# also - the Irony parser toolkit simulates BNF in a fairly restrained way which works well.
Finally, there is a plain old library: classes, methods, properties, with well-chosen names.
An external DSL would allow you to completely ignore cross-language integration problems, as the only library-like portion would be an eval method. But inventing your own tool chain is non-trivial. People always forget the huge importance of debugging, intellisense, syntax highlighting etc.
An internal DSL is probably a pointless endeavour if you want to do it well on C# and Java. The problem is that if you take advantage of the quirks of one host language, you won't necessarily be able to repeat the trick on another language. e.g. Java has no operator overloading.
Which leaves a plain old library. If you want to span C# and Java (at least), then you are somewhat stuck in terms of a choice of implementation language. Do you really want to write the library twice? One possibility is to write the library in Java, and then use IKVM to cross-compile it to .NET assemblies. This would guarantee you an identical interface on both of those platforms.
On the downside, the API would be expressed in lowest-common-denominator features - which is to say, Java features :). No properties, just getX/setX methods. Steer clear of generics because the two systems are quite different in that respect. Also even the standard way of naming methods differs between the two (camelCase versus PascalCase), so one set of users would smell a rat.
If you are willing to re-describe your language using ANTLR you could generate your DSL interpreter in multiple languages without having to manually maintain them including all of the languages you mentioned plus more.
Antlr is a parser/lexer generator and has a large number of target languages. This allows you to describe your language once, without having to maintain multiple copies of it.
See the whole list of target languages here.
Although I do not want to promote my own project too much, I would like to mention PIL, a Platform Independent Language, an intermediate language I have been working on to enable the support of multiple software platforms (like Java, Python, ...), specifically for external DSLs. The general idea is that you generate code in PIL (a subset of Java), which the PIL compiler can then translate to one of many other languages, currently just Java or Python, but more will be added in the future.
I presented a paper about this on the Software and Language Engineering conference about 2 days ago, you can find a link to the publication of the PIL website (pil-lang.org), if you're interested.
Ability to escape to the implementation language in the event you need to do something that just isn't supported by your DSL, or for performance reasons (though I realize that isn't a priority).
I am researching DSL for implementing rules in a rule engine in C#, some of the rules are really complex and may change significantly in the future, so being able to escape out to C# is really useful. Of course this breaks cross-platform compatibility, but it is really just a way of hacking around edge cases without having to change your DSL.
You'd be best off writing the library in C (or some language like rpython which will generate C-code) and then using SWIG or similar to generate the language specific bindings for C#, Java Python etc.
Note that this approach won't help if you are using Javascript in the browser - you'll have to write the javascript library separately. If you are using javascript through Rhino, then you'd be able to just use the Java bindings.
It is possible to interpret JavaScript from inside a Java-program directly using the script engine, and apparently also from C#. Python can be run on the JVM and the .NET engine.
I would suggest that you investigate these options, and then write your library in a common subset of the execution paths available to the language you choose. I would not consider writing it in a language which requires post translation and conversion, since you introduce a step which can be very, very difficult to debug in case of problems.
I would like to expand on Darien's answer. I think that ANTLR brings something to the table that few other lexer/parser tools provide (at least to my knowledge). If you would like to create a DSL which ultimately generates Java and C# code, ANTLR really shines.
ANTLR provides four fundamental components:
Lexer Grammar (break down input streams into tokens)
Parser Grammar (organize tokens into an abstract syntax tree)
Tree Grammar (walk the abstract syntax tree and pipe the metadata into a template engine)
StringTemplate (a template engine based on functional programming principles)
Your lexer,parser, and tree grammars can remain independent of your final generated language. In fact, the StringTemplate engine supports logical groups of template definitions. It even provides for interface inheritance of template groups. This means you can have third parties use your ANTLR parser to create say python, assembly, c, or ruby, when all you initially provided was java and C# output. The output language of your DSL can easily be extended as requirements change over time.
To get the most out of ANTLR you will want to read the following:
The Definitive ANTLR Reference: Building Domain-Specific Languages
Language Implementation Patterns: Create Your Own Domain-Specific and General Programming Languages
Related
He's the deal: I'm making some theorical research on .NET and Java platforms for my graduation course and I reached a cloudy area: Can C# be considered part of the .NET Framework? Analog to this, is Java (the programming language) considered part of the Java platform?
Let me review the facts:
.NET is a development platform specified by the ECMA-335 Standard; it is an implementation of this standard, if you will. C# however, is an implementation of another standard, ECMA-334 which states clearly that its implementation does not require an implementation of the ECMA-335 standard - the CLR in Microsoft's case (which a lot of people mistakenly call .NET when there's a lot more to it than just the CLR).
Also, we have Mono, a different implementation of the ECMA-335, on which C# also runs (from everything I read, it is implied that Novell doesn't have a ECMA-334 implementation of its own, which is perfectly reasonable), but C# is not PART of Mono.
There's the fact that I read somewhere that a programming language is not part of a platform, but unfortunatelly I can't seem to find the source.
There's also the fact that Wikipedia "Computing Platform" article states that a programming language is a platform; Wiki is, however, virtually worthless if you want your research to be taken seriously.
Microsoft seems to promote C# as a part of .NET, but being .NET a multi-language platform, wouldn't be so every language that supports/is supported by it?
So far, I only spoke of .NET, but I also need an answer regarding Java. Actually, a general response would be the best.
So, can anyone help me to put the pieces together? Reference material is much appreciated.
On a different issue, I've found A LOT of books out there that explain the inner workings of the CLR, isn't anything on the same lines for the JVM? I mean, there's the Specification, of course, but I was aiming for something easier to digest, I'm not planning to build a Java compiler after all..
As everybody seems to notice, it depends on your definitions.
But Ecma 334 (and/or some other Ecma doc) also specify MSIL (or CIL), and that definitely is part of the platform.
And I think C# is not part of the platform, the MS compiler just targets the CLR by outputting MSIL. it's not so hard to imagine an implementation for another platform, managed or unmanaged.
Java confuses the issue a little by having both a platform and a language called Java but it's not so hard to see the distinction.
So, can a language be part of a Platform? Yes, see MSIL.
But most languages (including C# and Java) are not.
A lot of languages (C, C++) make an active effort to be portable across platforms.
Are you asking in general? If so then it would seem to me that surely the answer is yes, a programming language can be part of a platform. For instance, the ECMA-335 standard includes a specification of the CIL programming language. It could have pointed to the C# language as well and referenced the ECMA-334 standard. It just doesn't.
This is really a question of loose vs. tight coupling applied on a broad scale. Loose is generally preferred as a design choice. Tight is nonetheless always an option.
Thinking about the question a bit more, I think I understand better what you are uncertain about. There's the CLI, specified by ECMA-335, and then there's .NET, which is obviously tied to Microsoft.
The CLI does not include C#; on that much I think we can agree. Does .NET?
Honestly, I'm not really sure. Considering .NET is a product maintained by Microsoft, I suppose it's really up to them whether C#, VB.NET, F#, etc. are or are not a "part of" .NET. Same goes for Sun with Java and the "Java platform."
Going back a bit further(1978), the distintion between UCSD Pascal & the UCSD p-System was often blurred, such that most users refered to UCSD Pascal as the operating system.
C# is a programming language. It was developed by Microsoft within the .NET initiative and later approved as a standard by Ecma (ECMA-334) and ISO (ISO/IEC 23270). Mono, DotGNU and DotNetAnywhere are not ".NET" implementations of C#. So C# is part of .NET, Mono, DotGNU and DotNetAnywhere.
Java programming language is also a language, which runs on the Java Platform. Remember, the JVM can run many programming languages (Scala, Groovy, JRuby, Jython). Then you have the different Java "platforms": Java Standard Edition, Java Enterprise Edition, and Java Mobile Edition. Each of these follow certain specifications defined by the Java Community Process, and they include the Java programming language.
Sun/Oracle's thinking on the subject pertaining to Java:
Java technology is both a programming language and a platform.
Later:
A platform is the hardware or software environment in which a program runs. ... The Java platform differs from most other platforms in that it's a software-only platform that runs on top of other hardware-based platforms.
So I would say according to their definition, the Java Language is not "part" of the Java platform. Just as C99 isn't part of of the Unix platform, etc.
In practice, though, the lines are somewhat blurred. The Java Language is probably more coupled to the Java Platform than they would like to admit. The Java API (the libraries) are said to be part of the Java Platform, not the language, and yet the language is coupled to certain classes or interfaces (for example, the for-each loop depends on java.lang.Iterable and java.util.Iterator).
In general, the designers attempt to contain the coupling to the java.lang package, that being for language support. That's why you see special cases like String, Object, etc. in java.lang.
From a purely theoretical standpoint, language and platform are seperate. The language specification of C# defines ONLY its structure and syntax; how it should look and act from the perspective of the programmer. From an object-oriented perspective, the language is an interface (quite literally), and platforms are implementations of it. There are many C/C++ IDEs out there, all of which can conform to the ANSI C++ specification for the language itself (some include extra gizmos). If you wanted to, you could write a compiler that will accept C# code files and produce Java intermediate instead of MSIL, or even native machine code (though as C# was designed for a managed-code platform, some features of a native-code language, like the ability to explicitly destroy objects, may need to be added to the spec to make it work).
In the real world, C# is all-but-inseperable from the .NET Framework because Microsoft developed the language spec, and MS's implementation (.NET) is by far the most prolific. So, the language is usually considered part of the platform, to the point that hardly anybody says C#.NET anymore. There are ports of the language spec (usually written for workalikes of the MS platform), but when you just say C#, developers assume you are talking about C# in the context of the .NET Framework.
A simple answer could be yes and no, as you said, it's a cloudy area. You will probably find some arguments for, and some against, both equally valid.
But my point of view is that c# is not a part of .NET. C# is designed for platforms like .NET and puts quite specific demands of the platform, like managed memory, that 32 bit assignments can be implemented atomically, etc.
Turn the question around, does .NET require c#? Throw c# out and you still have VB.NET, etc. C# can be thought of as a plugin that requires a platform with a specific interface, where .NET implements that interface.
As a "Yes" argument you could ask the rhetorical question what .NET would be without c#. Would it even survive?
Not C# or Java related but, for instance, SmallTalk platform includes not only the language and the VM but also the IDE. So I guess the answer to your question is: yes - a programming language can be a part of a platform.
C# does depend on certain .NET classes (specifically, in mscorlib) to implement its special constructs, though I suppose you could create equivalents for a different backing runtime.
foreach depends on IEnumerable or IEnumerable<T>
using depends on IDisposable
Lambda expressions can resolve to special generic representation objects Expression<>
yield return is also tied into the .NET enumeration model
So C# isn't completely independent of at least some aspects of .NET and the CLR, though you could, in principle, get the same behavior by creating a runtime/compiler that provides only the minimal subset of .NET features required to implement the language features. I don't think it would be particularly useful, however, since the language and runtime have grown and evolved together.
Are there any good ways to define interfaces/class hierarchies in a non language specific fashion and then generate corresponding source code in specified languages? In particular, I need to target both Java and C# for a fairly comprehensive API I am creating. I recall at one point seeing a post here on SF where an answer mentioned a programming language that 'compiled' to other languages-- but I have not been able to find the post. That language may be a solution for what I'm trying to do.
Thanks,
Andy
Have you considered UML? It's easy to find code-generators from UML for lots of different languages (Eg. this one can generate C#, Java and VB.NET code), but you might want to carefully evaluate if it's the right choice for you. As a standard, it has come in for substantial criticism over the years.
Lots of ways of doing something like what you want.
For example you could look at using an interface definition language (IDL). Corba's IDL allows you to declare objects & interfaces in a language neutral way. These idl files are then run through an IDL compiler which outputs the appropriate classes, headers, stubs, proxies etc. for the language of your choice.
For example IIOP.NET is an implementation of Corba for C#. I have no idea how good it is, but it would have an IDL compiler that spits out C# classes. Java has an IDL compiler called idlj as part of the JDK.
In theory therefore you could have C# and Java implemented from the same interfaces & classes.
Another way of doing something similar would be to utilise a UML tool that can generate source code from a model.
Another alternative would be to use something like WSDL / XSD to define your interfaces & types, and generate stubs from that.
Take a look at IKVM.NET. With it, you can write your program in Java (or a JVM language) and transform it into a .NET assembly. So you'll have both a JVM and a .NET version of your program.
I've had some interesting debates with colleagues about the merits if incorporating aspect oriented programming as a native paradigm to the C# language.
The debate seems to be divided into three camps:
Those folks who think that C# is already too complicated as it is, and another major feature like AOP would only muddy the waters further.
Those who think that it would be a great addition because anything that can increase the expressiveness of the language without breaking existing is a good thing.
Those who don't think it's necessary because libraries like PostSharp that perform post-compilation IL weaving already allow it in a language neutral way.
I'm curious what the community of C#/.NET developers out there think.
It would be great if languages would make it easier to develop and use AOP extensions.
For instance:
It would be nice if one could give a delegate (or anonymous method, or lambda) as a parameter to a custom attribute. It's not a lot of work to implement this in C#, it's quite easy to implement it in the CLR (since it supports types, why not methods?). And it would allow to express 'pointcuts' in an elegant way.
Support for 'fieldof' and 'methodof'. It is somewhat supported by the CLR (with bugs), not by C#. The same for 'eventof' and 'propertyof' (they have currently no support in the CLR).
Better debugging symbols could make it easier for an aspect weaver to report error messages and give the location in code.
It would be great to have a modular compiler; it would be less expensive to implement some features like source code generation based on aspects (for method and interface introductions).
That said, I don't think that the language should provide AOP extensions. This is too large (I think PostSharp 2.0 is more complex than the C# compiler itself, at least than C# 2.0). Let's face it: AOP is still rather experimental in the sense that we still don't know exactly what we want from it. There is still little experience. But we want the specification of a language to be stable and to address well-understood problems (imagine the Entity Framework were a part of the language).
Additionally, there are different ways to achieve AOP, and build-time is only one of them. There is nothing wrong in using runtime technologies, like JIT-emitted proxies (Spring/Castle); these are just for different use cases and have their own pros and cons.
So my opinion in one sentense: yes for limited and well-defined language extensions that make it easier to develop AOP frameworks; no for a full AOP implementation in the language.
I agree with the first camp. C# is already loaded with features. Leverage the PostSharp library instead.
It would be useful, but many of the uses are being included in various ways as it is. For example, we will have the ability to do post and pre validation in .NET4, which was one use for using around, in aspectJ.
By using extension methods you can inject new methods into objects you may not have source code for.
And, I don't believe it would be used much as C# developers seem to approach problems differently than Java programmers, which is easy to do since the two languages have diverged so much now.
I don't know if the companies that tend to use .NET would want to use something like AOP, and you would need tools to help understand what aspects are being injected where, such as AJDT on Eclipse.
I've been jumping from C# to Java an awful lot and the "differences" between the two are a bit of an annoyance.
Would it be possible to write a set of extentions/plugins that would merge the two languages syntaxes.
I'm talking about adding either IDE support or using language constructs that would for example:
treat these two lines equivalently:
System.out.println("Blah");
Console.out.writeline("Blah");
Automatically notice that when you type in string you mean String
Recognise common API calls and translate them in the background.
The end goal being to be able to write a java/C# program and to pick at compile time which VM/Runtime you are targeting.
If you could do this would it be a good idea?
If not why not?
The two languages are so similar it's painful in some aspects but in other aspects they are really different.
I've seen Code that will translate a C# project into Java and I'm assuming there is probably the reverse, what I am proposing is a middle ground, so we can all just "get along".
No, absolutely not. Certainly not in the languages themselves (as implied by the title) and preferably (IMO) not in the IDEs (as requested in the body).
They are different languages. The idioms and conventions are subtly different. I don't want to be thinking in Java when I'm writing C# or vice versa. I believe developers should be actively encouraged to separate their thinking. It's not too hard to switch between the two, but that switch should be present, IMO.
While I totally agree with Jon Skeet, if you must have this why not create your own library of Java API so you can create System.out namespace which has a method call printLn which calls Console.Writeline()?
That gets you close to what you want.
Just because Java and C# share some similar syntax you need to see past this and think in terms of Java Platform and .NET Platform. The two are distinctly different, so my answer is definitely not.
There actually already is a Java language for the .NET framework, developed by microsoft: J#
This way you get the java-syntax but you are still developing with the .NET framework.
But i am not recommending anyone to use it.
I knew Java before i knew C# so i tried out J# because i thought it would be an easier transition. At first I liked it but after I tried C# I'm never going back. First of all, nobody uses J# so it's kinda hard to find examples and tutorials. Second, C# has (IMO) much more convenient syntax, specially for events, properties, lambda, anonymus methods and alot of other things, it's also being updated every now and then with even more syntax sugar which i don't think J# is.
Maybe if you often write Java and sometimes have to write a .net app it might be a good option.
I think no. I also switch from java to c#. But if the syntax is identical was is to stop someone from trying to compile c# in a Java compiler, or vice-versa.
Visual Studio actually ships with a Java to C# converter, which tries to do some of the things you mention. Unfortunately it fails miserably (1) for anything beyond the simple hello world application.
Despite being very similar on the surface, there are many significant differences between Java and C#, so you would achieve very little by doing what you suggest imo.
(1) To be fair, it actually does a fairly good job if you consider the limitations given for such a task, but in practice the resulting code is of limited use and you have to do a lot of clean up after the conversion.
Firstly what you are describing is not a difference in language syntax but a differences in class libraries. Both languages are relatively simple in terms of keywords and features but understanding or knowing the libraries and how they operate requires considerable learning.
The mistakes you are describing are things that the developer should not be making to begin with - the IDE should not be guessing. There are going to be many cases where you can't easily / trivially translate between java or dotnet. In the end a skilled developer learns and knows when and which class libraries to use.
Actually in the beginning there was no dotnet - microsoft was behind java. They however proceeded to change java in ways not compatible with the java plstform standard. To paraphrase sun sued microsoft and won I'm court. Following that ms proceeded to create dotnet and particularly c# which became microsofts VM platform. Of course along the way a whole stack of things got changed. Microsoft introduced many things which broke Javas run anywhere etc. They have done the same thing with dotnet which have cause problems for the mono team to be able to faithfully reimplemwnt everything for other non windows platforms.
• String vs string.
• lowercase method names (java) v uppercase method names(dotnet).
• Giving java keywords new names - "package".
In the end dotnet was microsoft response so they can control the platform and do their own thing instead of following a standar
I learned Java in college, and then I was hired by a C# shop and have used that ever since. I spent my first week realizing that the two languages were almost identical, and the next two months figuring out the little differences. For the most part, was I noticing the things that Java had that C# doesn't, and thus was mostly frustrated. (example: enum types which are full-fledged classes, not just integers with a fresh coat of paint) I have since come to appreciate the C# world, but I can't say I knew Java well enough to really contrast the two so I'm curious to get a community cross-section.
What are the relative merits and weaknesses of C# and Java? This includes everything from language structure to available IDEs and server software.
Comparing and contrasting the languages between the two can be quite difficult, as in many ways it is the associated libraries that you use in association with the language that best showcases the various advantages of one of another.
So I'll try to list out as many things I can remember or that have already been posted and note who I think has the advantage:
GUI development (thick or thin). C# combined with .NET is currently the better choice.
Automated data source binding. C# has a strong lead with LINQ, also a wealth of 3rd part libraries also gives the edge
SQL connections. Java
Auto-boxing. Both languages provide it, but C# Properties provides a better design for it in regards to setters and getters
Annotation/Attributes. C# attributes are a stronger and clear implementation
Memory management - Java VM in all the testing I have done is far superior to CLR
Garbage collection - Java is another clear winner here. Unmanaged code with the C#/.NET framework makes this a nightmare, especially when working with GUI's.
Generics - I believe the two languages are basically tied here... I've seen good points showing either side being better. My gut feeling is that Java is better, but nothing logic to base it on. Also I've used C# generics ALLOT and Java generics only a few times...
Enumerations. Java all the way, C# implementation is borked as far as I'm concerned.
XML - Toss up here. The XML and serialization capabilities you get with .NET natively beats what you get with eclipse/Java out of the box. But there are lots of libraries for both products to help with XML... I've tried a few and was never really happy with any of them. I've stuck with native C# XML combined with some custom libraries I made on my own and I'm used to it, so hard to give this a far comparison at this point...
IDE - Eclipse is better than Visual Studio for non-GUI work. So Java wins for non-GUI and Visual Studio wins for GUI...
Those are all the items I can't think off for the moment... I'm sure you can literally pick hundreds of items to compare and contrasting the two. Hopefully this lists is a cross section of the more commonly used features...
One difference is that C# can work with Windows better. The downside of this is that it doesn't work well with anything but Windows (except maybe with Mono, which I haven't tried).
Another thing to keep in mind, you may also want to compare their respective VMs.
Comparing the CLR and Java VM will give you another way to differentiate between the two.
For example, if doing heavy multithreading, the Java VM has a stronger memory model than the CLR (.NET's equivalent).
C# has a better GUI with WPF, something that Java has traditionally been poor at.
C# has LINQ which is quite good.
Otherwise the 2 are practically the same - how do you think they created such a large class library so quickly when .NET first came out? Things have changed slightly since then, but fundamentally, C# could be called MS-Java.
Don't take this as anything more than an opinion, but personally I can't stand Java's GUI. It's just close enough to Windows but not quite, so it gets into an uncanny valley area where it's just really upsetting to me.
C# (and other .Net languages, I suppose) allow me to make programs that perfectly blend into Windows, and that makes me happy.
Of course, it's moot if we're not talking about developing a desktop application...
Java:
Enums in Java kick so much ass, its not even funny.
Java supports generic variance
C#:
C# is no longer limited to Windows (Mono).
The lack of the keyword internal in Java is rather disappointing.
You said:
enum types which are full-fledged classes, not just integers with a fresh coat of paint
Have you actually looked at the output? If you compile an application with enums in in then read the CIL you'll see that an enum is actually a sealed class deriving from System.Enum.
Tools such as Red-Gate (formerly Lutz Roeder's) Reflector will disassemble it as close to the orginal C# as possible so it may not be easily visible what is actually happening under the hood.
As Elizabeth Barrett Browning said: How do I love thee? Let me count the ways.
Please excuse the qualitative (vs. quantitative) aspect of this post.
Comparing these 2 languages (and their associated run-times) is very difficult. Comparisons can be at many levels and focus on many different aspects (such as GUI development mentioned in earlier posts). Preference between them is often personal and not just technical.
C# was originally based on Java (and the CLR on the JRE) but, IMHO, has, in general, gone beyond Java in its features, expressiveness and possibly utility. Being controlled by one company (vs. a committee), C# can move forward faster than Java can. The differences ebb and flow across releases with Java often playing catch up (such as the recent addition of lambdas to Java which C# has had for a long time). Neither language is a super-set of the other in all aspects as both have features (and foibles) the other lacks.
A detailed side-by-side comparison would likely take several 100s of pages. But my net is that for most modern business related programming tasks they are similar in power and utility. The most critical difference is probably in portability. Java runs on nearly all popular platforms, which C# runs mostly only on Windows-based platforms (ignoring Mono, which has not been widely successful). Java, because of its portability, arguably has a larger developer community and thus more third party library and framework support.
If you feel the need to select between them, your best criteria is your platform of interest. If all your work will run only on Windows systems, IMHO, C#/CLR, with its richer language and its ability to directly interact with Windows' native APIs, is a clear winner. If you need cross system portability then Java/JRE is a clear winner.
PS. If you need more portable jobs skills, then IMHO Java is also a winner.