I'm looking for a way to implement RPC between Java and C. What are the options to do this?
Best Wishes
p.s I have web java application which is hosted on Glassfish server and C daemon. I need to directly call functions from bought sides.
The whole point of RPC is to let two opaque processes on different systems talk to each other over a network. The languages used are irrelevant, except that you have to learn the corresponding RPC libraries for both languages.
Google Protocol Buffers address some of the difficulties with serialization, and provide a "RPC service" abstraction. You'll need to implement the "remote" part -- sending the data across, etc. -- but it'll give you cross-language compatible serialization.
The Google implementation doesn't natively support C -- only C++ -- but it looks like C is one of the languages for which there is an add-on.
Another option is the open source "thrift" library (originally from facebook). It also supports generating local stubs in a multiple of languages. Though I suspect the protocol buffer library as suggested by #Louis Wasserman is higher quality than thrift.
There are couple of java libraries implementing oncrpc:
http://code.google.com/p/nio-jrpc/ and
http://sourceforge.net/apps/trac/remotetea/wiki/WikiStart.
Related
It is not entirely obvious how to go about using RProtoBuf for communicating between R and other languages (Java, in my case).
The RprotoBuf Developers developed something that is still here - https://r-forge.r-project.org/scm/viewvc.php/java/?root=rprotobuf, but it seems very outdated. I am not sure if this is the way to go. Here are two conversations between the authors of RProtoBuf that might help with understanding the code -
http://lists.r-forge.r-project.org/pipermail/rprotobuf-yada/2009-December/000116.html
http://lists.r-forge.r-project.org/pipermail/rprotobuf-yada/2009-December/000119.html
It seems that they started work with Java and then abandoned it in C++'s favour!
Is there anyone using R-RProtoBuf-Java combination? How do you do it? Is there a tutorial or example available?
My exposure to Java is very very limited. I want to use a few programs written in Java.
Edit :
To clarify, I suppose I want to see an example of an R rpc client being used with RProtobuf. Pointers towards Java RPC servers would be welcome.
Edit2 :
The first link actually points to some documentation generator code, as Dirk pointed out.
I don't know about RProtoBuf, but if you just want to call Java from R, then you might be interested in rJava.
It is not outdated and has examples (right on the main page, see the link).
We have recently published a preprint on arXiv of a JSS paper we wrote with more examples of using RProtoBuf, including sending RPC requests to remote web services. For more exposition of sharing data between R and other languages with RProtoBuf, see RProtoBuf: Efficient Cross-Language Data Serialization in R.
You can use RProtoBuf with any transport mechanism, as explained in the article -- You can save serialized protocol buffers to files to be read by other applications written in other languages, or you can send them over connections/sockets or other higher level RPC systems. Protocol Buffers are widely used in everything from Sony Playstations to large scale web services, but they do not include an RPC system -- you use them as your serialization format with whatever transport system you are already using.
What is the "official" Java API for client/server or P2P communication? Java RMI? Some other networking API??
Is this official networking API the standard for both SE and EE?
I'm sure the answer is very context-specific, so let's take a look at a few instances:
You have 2 swing clients installed on 2 machines and connected to the same network (or the Internet), and you want either of them to send the other a primitive, such as the integer 4, or some POJO, like a "Widget" object
Same as #1 above, but between a Swing client and a fully-compliant Java EE back-end (implementing managed beans, app servers, the whole nine yards)
I don't have a specific application in mind, I'm just wondering what are the "norms" for client-client and client-server communication in the world of Java.
If being bound by Java isn't a problem, RMI is a pretty abstracted solution when it comes to the client and server solution "exchanging" data (especially when the data is Java classes which might be difficult/too much effort to represent as textual data). Just make sure your object implements Serializable and almost anything can be transmitted over the wire.
If this doesn't fit your bill and you want to drop down the raw networking stuff, the client-server socket framework Netty is a pretty good choice.
There's no such thing as the most official networking API in J2SE, all J2SE APIs are official in the sense they are supported by Sun (now Oracle).
That said, you should choose your API based on following criteria:
Do you (or your team) know how to use particular API;
How simple/complex is this API to use;
What throughput are you aiming for? For performance-sensitive applications you may be forced to use binary protocol. For the rest of cases, you can use text-based protocol.
For example, between two clients simple text-based protocol will suffice for passing POJOs, for example using Apache MINA or Google protocol buffers.
This will work between client and server as well.
Response to Zac's questions in comment:
Binary protocols performance gain comes from the fact you don't need to convert everything to text form and back -- you just can pass binary presentation of you application memory with minimal changes, like, in case of BSD Sockets API, converting from host byte-order to network byte-order. Unfortunately, I don't know details about how RMI/Java serialization processes objects, but I'm sure, it still much faster than passing all data in readable form;
Yes, MINA and protocol buffers have Java APIs. They just not part of Java SE bundle, you have to download them separately. By the way, MINA can use both binary and readable serialization, depending on how you use it.
You should define notion of 'good' somehow, for example, answering to questions I mentioned above. If you want to use objects over network, use RMI. If you don't, Netty or MINA will suffice, whatever you'll find easier to master.
For P2P, Sun at one point pushed JXTA pretty hard.
I wouldn't dare to use RMI for P2P communication.
rmi is pretty much the standard java to java protocol. it's built in and very simple to use. most j2ee backends also communicate using rmi, although that's not the only possibility.
J2SE the most common is probably RMI or raw sockets.
J2EE uses a messaging bus that everyone (servers and clients) subscribes to which is quite different from rmi style solutions (although at the lowest level an implementation may still rely on RMI). It helps automate redundancy and failover. If you need this functionality I believe it can be used in SE as well.
I haven't used J2EE for quite a while now, so this may have changed, but I doubt it. The messaging system was a core component of J2EE.
Is it possible to communicate with non java entity sing RMI protocol
What is special about RMI IIOP?
Thx
It's technically possible. You will need to implement a RMI server on the non-java side.
I would not recommend it though. Try exploring the possibility of using WebServices, which is commonly used for that: communicating entities from (probably) different platforms.
RMI is protocol supposed to be purely used by Java applications. It put some requirements on communicating which depends on Java implementation (e.g. serialization). On the other hand RMI IIOP is protocol which is used by EJB implementation in order to add more functionality to communication (e.g. transaction context propagation).
IIOP is originally from CORBA and could be used to communicate with components written in other languages.
I wouldn't go Web Services route if you do need to use features available to IIOP. Unless, of course you'd use respective WS-* specifications to get them.
Old question but, but answered because of high google ranking
I don't think you could do this easily.
As an alternative to Java-RMI I would recommend XML-RPC.
You can then communicate with Python, C++, Objective-C, Erlang, Groovy, Java, JavaScript, PHP and many more.
On the java side you can use the Apache XML-RPC library.
Pro: many implementations for different languages
Con: XML-RPC does know primitives and base64 encoded binaries. They will not handle your complex Java objects but give you a Map. You need to map them to your Objects by yourself.---
We need to use a Java library from C++ code. An idea that I had is that if we could build a C++ client for Java RMI (ideally using some framework or wizard), than we could run the Java lib as a separate server. This seem cleaner than trying to run Java VM within a C++ application.
Alternatively, if you have any other idea on how to use Java from C++, I'd be glad to hear. We work on Linux.
thanks a lot,
David
RMI is intimately linked with the JVM (and Java serialisation), so that isn't reasonable. Not unless the C++ client includes a JVM.
CORBA is the obvious platform-independent equivalent. It is a bit design-by-committee and is now considered very untrendy. WS-/JAX-WS is kind of the modern equivalent with lots of XML, but may be considered a bad attempt at CORBA. REST is an attempt at a lightweight WS-, but see Joel's Stackoverflow DevDay rant on claimed "simplicity".
You could go old school and just shove byte over TCP/IP (or pipes). Or if local, just exec the C++ program. Or use a native interface: JNI built into the JRE, or JNA a nicer layer over the top.
Don't bother with RMI. If you're willing to take the step of making the Java application a separate server, have your C++ client communicate via JMS (Java Messaging Service). ActiveMQ is a free JMS message broker implementation that provides embedded services as well as C++ client libraries. The JMS protocol is dead simple to use (at least from Java). Its probably not as flexible as doing REST, but it would likely be an easier implementation.
JNI was the intended solution to the problem of C/C++ to Java integration. It's not difficult.
Message Queues are better for larger grained interactions, or remote interactions where the message queue is accessible over the network.
CORBA and RMI were also intended to be network access mechanisms.
From your description you don't want that. You want to consume a Java library in C++, and to do that, you use JNI.
How to start the JVM and invoke a Java method, from C++ (JDK doc)
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.