integrating C# and Java

Viewed 45

We have the following scenario:

  • There is a program (already written) in Java which runs on a server (in the web). Let's call it JavaServerProgram. It takes user input, calculates stuff and finally generates a bunch classes. Let's call these classes JavaClasses. All these classes are serializable to json.
  • There is a library (already written) in C# that contains many classes describing a tree-like data structure. Let's call it C#Data. Let's call the root class C#Root. All classes in C#Dataare (de-)serializable to/from json.
  • The bunch of JavaClasses that JavaServerProgram outputs can be converted into a C#Root instance. We have a library written in C# for that which takes json representations of the JavaClasses as input and creates a C#Root instance. Let's call it C#Convert. This library will always be needed by another project; i.e. it can not be discontinued.
  • There is a program (already written) in C# that takes an instance of C#Root and does some actions (like shown a GUI, modifying files, ...) on a client. Let's call it C#ClientRun.

The workflow should be like this:

  1. JavaServerProgram runs on the server and outputs JavaClasses.
  2. The JavaClasses are converted into a C#Root instance on the server.
  3. C#ClientRun gets the C#Root instance as input and runs on the client.

The question is, how do we implement the whole thing?


Version A:

We use all already existing programs and libraries. That means:

  • We modify JavaServerProgram so that after creation of the JavaClasses, it serializes them into jsons and outputs them.

  • We write a C# program that takes the json representations of the JavaClasses from JavaServerProgram as input, uses C#Convert to create a C#Root instance, serializes the C#Root instance to json and outputs it.

Then, after JavaServerProgram has run, we run that C# program and finally send the resulting C#Root json to the client where it will be derserialized into a C#Root instance and input into C#Run.

Pro: We use existing code.

Con: We have overhead due to

  • the conversion being an own program (it takes time and memory for the OS to manage it),
  • "media discontinuity": Instead of directly converting the JavaClasses into C#Root, we must serialize them to json (in Java) to be able to send them to the converter. (The converter does NOT deserialize them to JavaClasses, though. It processes the jsons directly.)

Version B:

We make a Java clone of C#Covernt, i.e.

  • we duplicate all classes from C#Data in Java as well as their ability to be serialized to json,
  • we duplicate the conversion algorithm in Java but without using jsons in-between, i.e. we directly convert from JavaClasses to C#Root.

Then we extend JavaServerProgram to contain the above clone, i.e. after creation of the JavaClasses it converts them into a C#Root instance and serializes it to one json. Then we send that C#Root json to the client where it will be derserialized into a C#Root instance and input into C#Run.

Pro: We have no own-program-overhead and no "media discontinuity".

Con: We need to maintain the C#Data classes and the conversion algorithm in two languages (C# and Java).


Version C:

We find a way to write code both in C# and Java but compile it to some common intermediate language that runs in one shared environment (like JVM / .NET-VM).

Pro: No duplicate code and no overhead/"media discontinuity".

Con: Cannot see any. (The time needed to get to know this new environment does not count as a con since it will be just invested once.)


Can anyone elaborate pros and cons from a practical perspective? Like:

  • Version A: Will the expected overhead be relevant? Or is it going to be small?
  • Version B: Is maintaining duplicate code in different languages practical? Is it common? Are there tools to assist? (Maybe there are tools that can automatically convert from C# to Java?)
  • Version C: Does such an environment as described exist? Which one? Has anyone experience with it?
1 Answers

I would probably prefer the Version B alternative.

From my understanding that will create a clean separation of concerns between java and c#, i.e. all Java runs on the server, all c# on the client. They will also share a common object model of the objects that need to be transferred. Note that the data format should be clearly documented, so it is obvious what side is incorrect if there are any issues.

You might also consider making a entirely separate API between the client and server, even if it may happen to look very similar to some existing data structures. That could let you evolve the API without necessarily needing to affect other systems.

But your question implies that this library is used in other contexts, so I would probably recommend figuring out what language to use in what situations. Otherwise you will keep running into problems like "Code from project K would be perfect for project L, but is in the wrong language". As well as risking various employment issues. I.e. holy language wars, conflicts, knowledge gaps, extra training, recruitment difficulties etc.

Version A will do extra work on the server that might or might not cause a performance overhead, but more importantly it will make debugging more difficult, since it might be difficult to tell if the error is in the java code or the conversion code. And the server developer may not be able to debug the c# code efficiently.

Version C is a nice thought, but even if it is possible it would be a uncommon solution. So you will likely have much more issues with build systems, compatibility and finding help when there are issues.

Related