1

We want to use existing C# sources within our Java project. So far, this would not be a great problem since using e.g. Java Native Interface (JNI) is quite straight forward. The problem is that the software shall also run on non-windows OS. So, we can compile the C# sources with Mono in order to make them executable on e.g. Linux. But how about the integration within Java? JNI or any COM-based solutions for C# <-> Java interoperability are OS-dependent and only work e.g. on Windows.

One possible solution would be the implementation of webservices. Has anybody another idea of how to solve this problem? I would be very thankful for alternative suggestions!

Thanks very much!

Regards

  • How tightly integrated does this have to be? I have a Windows-based system written in C# that talks to an Android app written in Java, with object interchange using Google Protocol Buffers. I can explain more if that's of any interest. – RenniePet Oct 04 '14 at 17:40
  • There is no requirement about tightness... if we would realize it with webservices, we would have two separated applications anyway :-). Your solution sounds good... is there any reference-implementation for using Protocol Buffers in Java? What about computational efficiency... do you think this solution would be faster than using webservices? – Stephan Hutterer Oct 04 '14 at 18:02
  • The answer is going to depend largely on your specific requirements. For example, one possible solution is to run Java inside the CLR: http://www.ikvm.net/ But then we lose a lot of the interesting features and the performance of the JDK. So, could you provide more information about what is acceptable and what is not? – Samuel Audet Oct 05 '14 at 00:21
  • That's a great idea... we did not think about a CLR (although we do not have experience with it). So, the Java application will be the main application of the software, that realizes some kind of enterprise solution (contains the business logic, the database access, as well as the frontend-interface). The C# part contains mathematical algorithms (that are too extensive to be reimplemented in java) that are used by the main application; they will be called very often (in some use cases multiple times per second). For the main application, it is important for us to use mainstream technologies... – Stephan Hutterer Oct 05 '14 at 07:02
  • So it sounds like we should keep the main app running in the JDK? Hum, there isn't a whole lot of mainstream technologies for that. JNI for Java is portable, but C# has no standard equivalent to JNI, so it's hard to come up with something "portable"... – Samuel Audet Oct 06 '14 at 06:31
  • Yes that's correct, the main app shall run in the JDK. – Stephan Hutterer Oct 06 '14 at 06:58
  • Why do you think I need a JNI equivalent on the C#-side? If we would compile the c# part to DLLs using e.g. Mono, we could integrate them into the Java app using JNI, right? As far as i know, this solution should work on non-windows OS as well... – Stephan Hutterer Oct 06 '14 at 07:03
  • Sure, if you're willing to limit yourself to Mono on Windows as well, then that's fine. But it sounds like you want to use Microsoft's .NET platform on Windows, and that's going to get hairy. You need to make your requirements clearer. – Samuel Audet Oct 07 '14 at 00:49
  • OK, i can see your point. So, we have to check whether it is useful to use Mono both on Windows and other OS too. If yes, we could compile the C# parts to libraries using Mono, and integrate them with JNI into the main app. This would work on Windows, Linux and Mac as well, right? This sounds like a quite feasible solution (as far as we can go without .Net on Windows. Hm... we have to check this. Do you see any alternative solutions? Thanks very much for your great support! This really helps me... – Stephan Hutterer Oct 07 '14 at 10:48

2 Answers2

2

This is maybe not an "answer" as such, more a bit of discussion of how I viewed a similar (I think) situation.

I had a major investment in a C#/.Net-based client-server style system. So when I decided that I also wanted to support an Android "client" app I looked into various options. To me the most important factor was to maintain my C# classes as the defining classes for the object interchange between the existing system and the to-be-written Java Android app.

What I eventually settled on, and tweaked to my liking, was a system where Google Protocol Buffers is the interchange media. (If you're not familiar with them they are a sort of JSON-like interchange format.) https://developers.google.com/protocol-buffers/

At the .Net end I use ProtoBuf-Net, written by Marc Gravell (he works here at SO, I believe). It includes the ability to take .Net objects and generate .proto files, the defining file for Protocol Buffers. https://code.google.com/p/protobuf-net/

At the Android end I use ProtoStuff, written by David Yu. There is a part of his code that takes a .proto file and generates the corresponding Java classes. https://code.google.com/p/protostuff/

One problem I encountered was that this didn't work well for my .Net classes that are derived classes, which was most of them. I created a workaround that is described in my comment to the answer here: How to get protobuf-net to flatten and unflatten inherited classes in .Net?

This is now working to my satisfaction.

Note that I haven't talked at all about how the Android app connects to the Windows-based system and how the communications is performed. That was secondary for me - my primary consideration was making the C# class definitions the definitive definitions and having Java classes created from them automatically, and then the object-to-object interchange. (In the event I'm using a home-made TCP/IP communications link, but the actual communications could be anything, probably also web services.)

Hope this helps.

Community
  • 1
  • 1
RenniePet
  • 11,420
  • 7
  • 80
  • 106
  • This is indeed very similar to my use case. In fact, it would be quite advantageous to integrate the C# class declarations into the java part in some automated way. However, we have the same issue that the C# classes are derived classes. I will check your solution in more detail... very thanks! – Stephan Hutterer Oct 05 '14 at 07:10
1

So I did a lot of research on this topic and want to share my findings with you:

One (from a technical point very attractive) option is to use commercial bridges between Java and .Net. For sure, the most popular products are JNBridge and Javonet. Both products seem to be quite easy-to-use, have good support and seem to be very sophisticated. Especially JNBridge already supports bridging between Java and Mono too, which allows the portation to also non-Windows OS, which is one of our main requirements as stated above. Javonet also wants to integrate Mono and is going to release this feature soon. However, both solutions are commercial and one needs to weigh their features against the respective costs. Nevertheless, from a pure technical point of view, they look great and also state to enable very fast communication between Java and .Net (faster than with web services).

Another option is to connect Java and .NET via COM. Since COM is generelly defined platform-independently, this could work on multiple OS. There are lots of open source projects that could be used for such an implementation, such as EZJCOM, J-Interop, JACOB or JCOM. The main restriction (expecially for our project) is that Mono only supports COM-interoperability under Windows (yet). So, this is not really an option for us. But if you want to create Java-.NET interoperability on Windows only, this is a good way.

The straighforward way of integrating Java and C# is to use Java Native Interface (JNI). You can also find manifold implementations that make JNI more easy to use, the most popular one is probably jni4net which seems to be a very active and frequently used project. But there are also others with specific pros and cons, such as Caffeine, Espresso or csjni. Finally, JNI is not 100% platform independet. It is applicable on different platforms, but you have to generate platform-specific code which makes it clearly less usable for our purposes. If you limit your application to Windows, jni4net seems to be a very good choice.

The third option could be to run both the Java and the .Net part within a Common Language Runtime. Ikvm.net is one possible and very popular solution therefore (as mentioned above by Samuel Audet). The drawback of this option is the loss of features and efficiency of the JDK.

The last and surely most generic alternative is to set up webservices between the Java and the .Net world. For this solution, one needs to find appropriate ways for serializing/deserializing objects from/to Java and .Net. There are manifold possible solutions for that available. RenniePet mentioned a sophisticated solution based on Protocol Buffers. Others exist as well such as http://java-cs-bridge.sourceforge.net/. This option might have a potential drawback when considering communication runtime, but may be the way to go for us.

Hope this may help anyone in the future that is confronted with the same problem.