Interprocess Communication between C++ app and Java App in Windows OS environment - java

We have a C++ application on Windows that starts a java process. These two apps need to communicate with each other (via snippets of xml).
What interprocess communication method would you choose, and why?
Methods on the table for us are: a shared file(s), pipes and sockets (although I think this has some security concerns). I'm open to other methods.

I'm not sure why you think socket-based communication would have security concerns (use SSL). It is often a very good approach as it is language agnostic, assuming that you have a well-defined communication protocol. Have a look at Google's protocol buffers, for example - they generate the required Java classes and streams.
In my experience, file systems (especially network file systems) are not well suited to such communication as they are not necessarily tuned for messaging (I've seen caching issues result in files being not picked up by the target process for example).
Another option is a messaging layer (AMQ or Tibco for example) although this will likely involve a greater administrative overhead (plus expertise) to set up.
Personally I would opt for a pure-socket approach because of its flexibility and simplicity. You will be in complete control.

I've used named pipes for communication between C# and a cross-platform c++ app and had nothing but good results. Barring that sockets is definitely the way to go.

Sockets are nice. They give you the ability to very easily create a blackbox testing layer around each component, as well as run each component on its own machine.
Security is definitely a concern, but there are a good range of options depending on how important it is. You can use SSL, custom handshaking, password protected logins and firewalls to help secure it.
Edit:
Not something I'd recommend, but there's also shared memory using JNI. Just thought I'd mention it because it's not on your list.

Ice is pretty cool :)

Related

Inter-process-communication between a Java application and a local server

Firstly Cheers to all PROGRAMMERS [ Today = Programmers day :) ]
Secondly,
I'm working on a project where the specifications require using a server as a front end and an application in the back end. The project is an advanced smart home system. The server will handle commands coming from the client through the internet (let's say like a remote control from outside the house) and send them (through a channel of communication) to the application (planning on using JAVA application) which will handle the main logic like controlling hardware stuff (lights ...) , reading from a microphone (local mic) and accessing a database to act as a speech recognition system (offline).
Now I'm still in the planning phase and I'm not sure which technologies are the best for this project. I'm thinking to use Node.js or Apache as the server and a JAVA application as the back end and any SQL database for the application's SRS.
I hope this illustration demonstrates clearly how the system works:
The main question is:
What is the best way to make the Java application communicate with the server (communication channel [must be bidirectional]) ?
and Do you recommend a specific server other than the mentioned ones for this job ?
What crossed my mind so far:
1- JSP and servlets (making the server is the application too). But I don't want a server to handle the offline stuff and I'm not sure if java servlets can access hardware interface. I also want the server to be separate from making critical decisions (different layer for security reasons and since it won't be used as frequently as the local [offline] system).
2- Communication channel :
A- A shared file, but it's a bad idea since I don't want the application to check if the file contents changed (command received) or not from time to time (excessive operations).
B- A an inter-process-communication through a port (socket communication) seems the best solution but I don't know how that would turn in terms of operation cost and communication errors.
OS used : Linux Raspbian
EDIT:
I'm sure ZMQ+Apache is good enough for this task, but how is it in comparison to WebServices (like SOAP) ? Would WebServices be a better solution in terms of standard implementation and security ?
All related suggestions are welcomed, TQ
ZeroMQ is great for internal communications, or any other similar communication solutions.
For specifically your case, I can see that ZeroMQ would be a best fit.
Reasons:
You offline server have to be agnostic to web solution.
Communication can be reliable and bi-directional, possibly another patterns like (pub>sub, req<>res, etc).
Restarting any of sides would not require to restart the sockets (connection) on other side, as messages are queued.
Possibility to scale not just on same hardware, but as well to local area network or even through internet.
Big community of support. It might look a bit hard to get into, but in reality it is dead simple, just go to examples and once concept understood - it is very easy and neat to work with.
ZeroMQ has lots drivers for most popular languages, that includes Java and Node.js.
Considerations:
You need to think over packets and data will be sent. So some popular data protocols like XML or JSON is good way of thinking.
Responsibilities over different services - make sure they are not dependant on each other too much. Or if main offline server - is a core of system, make sure it does not depend on web facing service, so that web face can be removed/replaced/improved etc.
Few more points to think about:
Why Java, and what about modular approach? For example if you want to expand and scale - add more sensors into smart home solutions, then having one giant application would require to change it, it is harder to maintain as well as maintain different clients with own needs. Think modular way - some core functionality for offline stuff, but many aggregator processes that would talk to different sensors. This makes easier to support different setups and environments, as well maintain the system as a whole by improving independent components.

Using IPC to combine multiple languages

This is a general "noob" question about software design, so I apologise if it seems vague,
but I would really appreciate the advice. Note the system described below is purely an example, not a specific product I have in mind.
I often have a need to combine the functionality of several libraries or utilities, written in different languages. For example, if I want to code a high-performance audio processing application for the desktop, I will write it in C / C++. Then, I want to add a nice GUI. But I don't want to learn Qt. I like the look and feel of Adobe Air, and would like to use that. Later, I have a need to access a USB device. But the USB library I have only has an API in Java. How can I combine all these elements together, to take advantage of their relative strengths?
Clearly, I cannot compile these various elements into one single executable. So I need to create and run them seperately, and give them a means to communicate. The most common way to do this seems to be using IPC (Inter Process Communication), eg shared memory or sockets. I prefer the idea of sockets, as the programs could potentially run on seperate machines on a network.
So I decide to create a local client / server system, with a custom API, to allow these elements to communicate. For example, the Air application will receive a message from the C application, telling it to update it's UI. The USB application running in Java will use the sockets to stream audio from the USB hardware, into the C application.
My question : is using local sockets in this way a typical way to design such a system?
Will the performance be much worse than a truly native application (e.g. everything in Java or C, in a single executable) ? It also seems likely that such an approach would be prone to bugs, and difficult to maintain?
I frequently find myself coming up against the limits of existing software libraries (e.g. a graphics library with a pretty, flexible UI but no way to access low-level hardware, or a media library that can mix many audio streams, but has no support for video playback), and find it very frustrating. If anyone could advise the best way to combine arbitrary software libraries like this, I would really appreciate it.
Thanks in advance!
As you have correctly identified, combining libraries from different language or platforms is hard. There are several ways to do it, but none are ideal. Examples:
Native call interfaces (e.g. JNI / JNA) - very fast but tricky to make work correctly, and you have the problem that the data types used typically don't map cleanly across different platforms. Adds native dependencies.
Socket based IPC with text protocol (XML, JSON, etc) - works OK and common formats are likely to be supported at both ends, but adds a lot of overhead. Can be a pain to maintain custom schema mappings etc.
Socket based IPC with binary protocol (e.g. Google protocol buffers) - quite efficient, needs a lot of work to get a custom protocol working correctly on both ends
Communication via a 3rd system (e.g. database, message queue, filesystem) - lots of overhead, can get fragile, introduces a major dependency on a 3rd system.
In my experience, it usually isn't worth integrating a new language / platform just to get one specific library or feature. Take your user interface example - no matter how nice Adobe Air looks, I doubt it is worth trying to integrate it with an existing C/C++ application.
Even if you get it to work, it will significantly complicate the future maintenance and devlopment of your application. Builds become more complex. You need to maintain additional communication / "glue" code. You need to manage more dependencies. Your users will get hit by many more configuration issues. Testing becomes more difficult. It becomes harder to teach someone new about how the whole system works. You need to maintain your skills in more languages / frameworks etc.
I'd recommend the following strategy:
Pick a primary platform
Whenever you need a new library or feature, look for something on your primary platform first. Hopefully (usually?) there is something good available - but even if not then it might be worth coding something yourself if the requirement is quite small.
Only if there is no reasonable option on the primary platform, then you can start to think about integrating a new language/platform
In terms of primary platform, I'd normally suggest a JVM language like Java, Scala or Clojure since the JVM is very well engineered, offers great performance, is highly portable and has the largest / most cohesive library ecosystem (most of which is open source). The JVM is therefore probably the best "general purpose" choice unless you have some very specific requirement which is unlikely to be possible on the JVM, e.g.:
If you are doing lots of embedded / realtime / systems programming wthat requires hardware access you probably need to go for C/C++
If you are coding purely for web-based clients, you probably want to use JavaScript (if you are also writing code on the server side you can consider JavaScript code generation frameworks/libraries that can work on the JVM, e.g. Vaadin or ClojureScript)
the answer is pretty much depends on the technologies you're using and there is no silver-bullet solution for this.
In general, this solutions will fall into one of the following categories:
Some interprocess communication techniques
Integrations provided by the language/platform itself
Database/some common storage (even files :) )
Example of the first:
Sockets/pipes/whatever you operating system allows.
CORBA - allows to write distributed code in different languages.
Google protobuf - allows serialization/deserialization of data-objects and its language agnostic
For the second it really depends on language/ecosystem you're using.
Examples for java:
JNI - Java Native interface - allow to execute code (dlls/so) outside the JVM.
JCA - if you're in the enterprise environment - you can write the integration with the legacy systems in this.
For languages that are compiled into the native code its less tricky - you can write and compile some code, say in Pascal, and then use the DLL in C.
Sometimes when we're talking about Java there is a plethora of languages that have their own syntax and compiler, but their compiler compiles into java binary code that can be run inside the jvm. So if your solution is based on these languages the integration will be easier. Languages like Scala, Groovy, Closure, Jython and so on are falling into this category.
The last but not the least technology to be mentioned is Web Services. This is a very popular tool for integration of different system, although its more used in enterprise environment.
Basically its an abstraction over the sockets layer that allows to send data objects in XML/JSON format between the processes/servers. Both of XML and JSON are language agnostic, so its not an issue to create an XML in a program written in C++ and then consume it in JAVA.
Hope this helps

How do I isolate untrusted native code in Java?

I have a piece of C library that I don't trust (in the sense that it might crash frequently). I am calling this from a Java process.
To prevent the crash in C library bringing the whole Java app. down, I figured it will be best if I spawn a dedicated java processes for this library, and let it interface with the Java app. through socket programming or RMI. Then, if a crash happens, I can just spawn another one and continue processing.
Is ProcessBuilder the way to go? Or are there any other easier ways?
Thanks!
Yes, hosting the native code in a separate Java process is the only way to protect your application from native code.
As for easier ways, just minor implementation differences. For example, not spawning the code from your Java application and wrapping the native code in a native wrapper that is configured to auto-start. This would simplify the solution, if you have knowledge of C and sockets. In this approach, RMI wouldn't be the best choice.
Even if you wrap the native code in Java, I still wouldn't pick RMI. I have run into networking problems with Windows on WANs. I would keep the communication simple if possible. If the data is too complicated, maybe a basic serialization library. There are a few choices if you go down the XML route. It's overkill, but you could also embed an http server and web services layer. I don't know your system requirements, bu
Recovery is going to create a variety of challenges. If it stops responding, do you just spawn another process...how many times are you willing to do that... Process management from Java, leaves a lot to be desired.
I don't know of an easier way.
For the interaction between the parent and the child, i wouldn't use RMI or sockets - i'd use the child's standard input and output streams, accessible through the Process object. This is simple, efficient, and private. You can use the streams exactly as you would socket streams, although without any considerations of identity, addresses, authentication, and so on. You can write a protocol yourself, or use something like Thrift or Protocol Buffers to build a protocol from entity definitions.
If performance isn't an issue and if there is a possibility of other applications hitting your "native" service, I'd go the RESTful or some other sort of web service oriented way. As far as re-spawning on crashes are concerned, as others have mentioned, just spawn the process as a service and you should be good to go.
If your application is the only entity which would be hitting this native service, then I'd prefer to go the RMI way as opposed to the pure socket way. IMO, RMI is a natural fit for inter-process communication (where the processes are Java processes). RMI has the concept of an "activatable" remote object which would be a natural fit given your requirements (auto-spawn on crash). Also, if using RMI, your application would speak with the native process through well defined Java interfaces rather than ad-hoc protocol contracts (which can be achieved using other high level solutions like web services but a real pain when it comes to raw sockets).
BTW, JFTR, we are using this strategy with our production app and it is working out quite well, YMMV. :-)

Which Java RMI/RPC/IPC technology should I use?

I'm developing a Java application that consists of a server and a client (possibly multiple clients in future) which may run on different hosts.
For communication between these two I currently use a custom protocol which consists of JSON messages that are sent over network sockets and that are converted back to Java Bean objects on both sides. However the more complex the application gets I notice that this method doesn't meet my standards and is too complex.
I'm looking for a well established, possibly standardized alternative.
I've looked at Remote Method Invocation (RMI) but read that the protocol is slow (big network overhead).
The technology I'm looking for should be lightweight (protocol and library wise), robust, maybe support compression (big plus if it does!), maybe support encryption, well document and well established (e.g. an Apache project). It should be as easy as calling a method on a remote object with RMI but without its disadvantages.
What can you recommend?
Avro is an Apache project that is designed for cross-language RPC (see Thrift for its spiritual predecessor). It is fairly new (less than two years old), so it isn't as well-established as RMI, for example. You should still give it a chance, though; large projects like Cassandra are moving to Avro. Avro is also a sub-project under Hadoop and has been receiving healthy support from that community.
It designed to be fast and support multiple languages, so you will probably need to introduce another step during compilation in which you translate an Avro IDL file into Java, although it isn't strictly necessary. The rest is typical RPC.
One nice thing about Avro is that its transport layers are independent of how data is represented. For example, it comes with various "transceivers" (their base communication class) for raw sockets, HTTP, and even local intra-process calls. HTTPS and SASL transceivers can provide security.
For representing data, there are encoders and decoders of various types, although the default BinaryEncoder generally suffices since Hadoop, Cassandra, etc... focus on efficiency. There is also a JsonEncoder in case you find that useful.
This really all depends on what kind of compatibility you require between client and server. CORBA is a well established and standardized way of communicating between different languages, but it requires a bit more effort to use than Java RMI. If the clients are running from some external, untrusted source, then an HTTP based protocol makes more sense. If you follow a REST approach, then it becomes easier to scale out later as you need to add more servers.
If both client and server are Java, and they are running within a trusted network, RMI meets your requirements for being "well established". Performance overhead of RMI is exaggerated, but very early versions did not pool connections.
If you're willing to toss away both "well established" and "standardized", you can use Dirmi as a substitute for RMI. It's faster, easier, has more features, and it doesn't have the firewall problems RMI has. Like RMI, it supports TLS (encryption), but neither supports built-in compression.
Whatever you choose, beware of lock-in. Try to design your server such that the remote access layer is a thin layer over the core code. This allows you to easily support multiple protocols, perhaps at the same time.
Mybe CORBA?
Would you consider HTTP/REST?
If so, you can leverage something like a Tomcat/Spring, and still support all the requirements you listed ( robust, lightweight, well documented, well established )
The RPC based protocols are simply antiquated.
Seriously, unless you're doing a web app that already requires the web baggage, you really do want RMI or, even better, CORBA. I recommend JacORB (www.jacorb.org).
Ignore general claims of slow/fast and perform your own performance tests.
Keep in mind that a software project is successful because it performs the useful function for which it was designed and intended, not because it uses the latest cool buzzword tech.
Good luck.
Apache MINA library for client-server communication and EJB3 will suit best

How can I call a method in an object from outside the JVM?

I have a really simple Java class that effectively decorates a Map with input validation, with the obvious void set() and String get() methods.
I'd like to be able to effectively call those methods and handle return values and exceptions from outside the JVM, but still on the same machine Update: the caller I have in mind is not another JVM; thanks #Dave Ray
My implementation considerations are typical
performance
ease of implementation and maintenance (simplicity?)
reliability
flexibility (i.e. can I call from a remote machine, etc.)
Is there a 'right way?' If not, what are my options, and what are the pro/cons for each?
(Stuff people have actually done and can provide real-life feedback on would be great!)
Ok. Here's another try now that I know the client is not Java. Since you want out-of-process access and possibly remote machine access, I don't think JNI is what you want since that's strictly in-process (and a total hassle). Here are some other options:
Raw Sockets : just set up a listener socket in Java and accept connections. When you get a connection read the request and send back a response. Almost every language can use sockets so this is a pretty universal solution. However, you'll have to define your own marshalling scheme, parsing, etc.
XML-RPC : this isn't as hip these days, but it's simple and effective. There are Java libraries as well as libraries in most other languages.
CORBA : as mentioned above, CORBA is an option, but it's pretty complicated and experts are getting harder to come by.
Web Server : set up an embedded web server in your app and handle reqests. I've heard good things about Jetty or you can use the one provided with Java. I've used the latter successfully to server KML files to Google Earth from a simulation written in Java. Most other languages have libraries for making HTTP requests. How you encode the data (XML, text, etc) is up to you.
Web Services : This would be more complicated I think, but you could use JAX-WS to expose you objects as web services. NetBeans has pretty nice tools for building Web Services, but this may be overkill.
Will you be calling from another JVM-based system, or is the client language arbitrary? If you're calling from another JVM, one of the simplest approaches is to expose your object as an MBean through JMX. The canonical Hello World MBean is shown here. The pros are:
Really easy to implement
Really easy to call from other JVMs
Support for remote machines
jconsole allows you to manually test your MBean without writing a client
Cons:
Client has to be on a JVM (I think)
Not great for more complicated data structures and interactions. For example, I don't think an MBean can return a reference to another MBean. It will serialize and return a copy.
Since your callers are not Java apps and you're already foreseeing networked callers, RMI-IIOP (CORBA) might be an option. Though it's definitely not easy to implement, it has the advantage of being a widely-recognized standard.
Since your caller is not JVM-based, this is a question of inter-process communication with JVM. The options I have in mind are:
Communicate over a socket: make your JVM listen to incoming connections and caller send commands
Communicate using shared files (caller writes to file, JVM polls and updates)
Using JNI, start JVM inside a callers process and then use RMI/MBeans to communicate with the first ("server") JVM. Caller will have access to results using JNI
Option 3 IMO is the most "Java" way of doing this, and is the most complex/error-prone.
Option 2 is ugly but simple
Option 1 is moderately easy (java part) and otherwise ok.
For ease of use, I would use Spring Remoting. If you are already using Spring in your project, that's a no brainer. If you arent ... well you should have a look anyway.
Spring provides an abstraction that allow you to switch remoting protocols easily. It supports the most widely deployed protocols (SOAP, Hessian, Burlap, RMI, ...). If you are calling from non Java code, Hessian has support in a number of other languages, is known to be more efficient than SOAP and easier than CORBA.
Beanshell is a shell-like java interpreter that can be exposed over a network socket. Basically you do this from java:
i = new bsh.Interpreter();
i.set( "myapp", this ); // Provide a reference to your app
i.eval("server(7000)");
and then you do this from anywhere else:
telnet localhost 7001
myapp.someMethod();
This little utility does remote java invocations much more easily than JNI or RMI ever has.
For more, start at: http://www.beanshell.org/manual/remotemode.html
JNI (Java Native Interface) allows access to java code from C or C++.
I have an Inno Setup script (installing a Java program) which calls some Java methods to perform some operations or check some conditions.
I (actually my predecessor) just instanciate java.exe on each call. Which is, obviously, costly, although not critical in my case (and the Windows cache kicks in, I suppose).
An alternative is to use some inter-language communication/messaging, your Java program acting as a server. Corba comes to mind, as it is language agnostic. But a bit heavy, perhaps. You can use sockets. RPC is another buzzword too, but I haven't much experience in the field.
What you want is the Java Native Interface (JNI), despite the difficulties that it may present. There is no other equivalent technology that will be as easy to implement.
As mentioned in the comments for the preceding answer, the JNI is optimized for calling native code from Java, but it can also be used for the reverse with a little work. In your native code you'll need to implement the JNI entry point--something like SetMapPointer()--then call that function from the Java code once the Map is built. The implementation of SetMapPointer() should save the Java object pointer someplace accessible, then the native code can invoke Java methods on it as needed.
You'll need to make sure that this happens in the right order (i.e. the native code doesn't try to access the Map before it's been built and passed to native code), but that shouldn't be an especially hard problem.
Another alternative to consider if the other process will be on the same machine and the OS is POSIX-compliant (not Windows) is Named Pipes.
The outside process writes the operations, as strings or some other agreed-upon byte encoding, to the named pipe while the Java application is reading from the pipe, parsing up the incoming operations and executing them against your object.
This is the same strategy that you would use for socket connections, just instead of a SocketInputStream you'd be reading from a FileInputStream that is attached to a named pipe.
An alternative to CORBA is ICE, unless the licence is a problem (it's GPL, but you can also buy a commercial licence).
It has pretty much all the benefits of CORBA, but ZeroC, the vendor, provides bindings for many different languages. CORBA vendors tend to only provide one or two language bindings, and then you start finding compatibility problems.
The documentation is also excellent. I wouldn't have said it was particularly easy to pick up, but probably easier than CORBA.
Otherwise, another option I don't think has been mentioned is the new middleware/RPC framework developed by Cisco, now donated to Apache, called Etch. It's still pretty new though, and documentation is sparse.

Categories

Resources