How do I isolate untrusted native code in Java? - 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. :-)

Related

C++ and Java objects communication

I need to establish a communication model between C++ layer and Java layer in my application. Initially, I planned to use SOAP with XML, but my clients are interested in setting up a database communication channel.
I am new to DB and not sure how to proceed. I would like to take your sincere suggestions on the implementation of communication in terms of objects between C++ and Java layer using database.
Thanks,
Geet
Database as communication? shudder
http://en.wikipedia.org/wiki/Database-as-IPC
This is an anti-pattern. Can you change your clients' minds?
Sockets are easier than a full blown SOAP interface.
If you have 2 different applications communicating, sockets is the way to go. If your C++ layer is more like a library, you could also use JNI (http://en.wikipedia.org/wiki/JNI, google for tutorials).
The choice of communication channel and blocking model is largely application dependent but sockets will probably work best if you don't need to worry about security. SSL/Mutual auth is your next step up.
I rolled my own, but I would use google protocol buffers if I had to do it all again.
http://code.google.com/p/protobuf/
They seem to capture much of what people wanted out of ASN1 (but not all messed up) and let you do what people often try to do with serializing java Properties.

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

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 :)

Fastest(performance-wise) way to share data(not objects) between .Net & Java

I know of at least one post which has same words like this. But this is not exactly same as that post. I'm trying to work a way to "share" data between a .NET and Java application. I'm not concerned about objects, but just plain strings if u like.
I have a .NET application capturing real-time data and a Java application which has capability to analyze and work on this data. I'm looking for ways to re-use this same java app without coding it entirely in .NET.
My problem is that the data is "fairly" REAL-Time (.NET), and so has to be the analysis (Java). I can live with microsecond delays but I can't afford one second delay. WebServices, Queues (as in Messaging Queues), RDBMS are some of the options I can think of. Is there any better way?
Or has anybody got some real performance numbers for the solutions I mentioned above to select one of them? And just to get started: RDBMSs' are not "THAT" good for concurrent (connections doing) insertion/updation/reading, at least with the crude way of doing DBMS stuff. (Deadlocks?)
What are "objects" if not a mechanism for describing "data"? But I digress - I suspect I would look at a TCP socket between the two. If the data is very basic, then fine - just write directly to the stream; if there is any complexity, perhaps use something like "protocol buffers" to provide an easy way of reading/writing dense data to a stream without having to write every last byte yourself.
I think microsecond delays are going to be a challenge for any approach here... will millisecond delays do?
For completeness:
Another possible is to use Named pipes, it should be pretty quick, and I'd imagine (being a java guy I can only imagine) that .NET has native support for them. The down side is that on windows you'll have to either write a JNI extension or use a library like JNA to poke around at the Win32 API from Java.
Sounds like a local socket could do. The latency should be in low ms or less.
Depending on your program you may get some milage out of what #Cowan reports in answer to 'Any Concept of shared memory in java', his answer is: Any concept of shared memory in Java
In summary: he say's that you can use memory mapped files between two processes on the same machine. This in theory could work between .NET and java assuming .NET has some memory mapped file support.
Different machines communicate with each other by sending messages into sockets. Please check the below link for example.
Socket programming in the real world
Answers provided here are great. One idea that might be of interest, but is probably asking for more trouble than it's worth is to load both VMs in a single process (both the JVM and the CLR can be loaded within a native Windows application) and give them access to native code. Java via JNI and .Net via the mapping functions to native code that they allow.
You could also leverage native queue semaphores to wake up a thread on one side or the other when data is updated.
While JNI transitions are expense, they would probably still be faster than the native local socket implementation.
How is your Java application currently deployed? It sounds to me like you're willing to make some modification to it, so I'm assuming you have access to the source code.
I know this is a little out there, but could you compile the Java application in the J# compiler, so that your .NET app has native access to it?
You can convert your compiled java application to .NET by IKVM. After that you can change logic of your .NET application so it will not make data transfers to Java application, but just call data processing code written in Java as it were written and compiled for .NET.
There are a number of JMS servers which support .NET and Java clients. These can perform messages in under a millisecond.
However you might like to try an RPC solution like Hessian RPC or Protobuf RPC. These can achieve lower latencies and can give the appearance of direct calls between platforms. These support .NET and Java as well.

Connect PHP code to Java backend

I am implementing a website using PHP for the front end and a Java service as the back end. The two parts are as follows:
PHP front end listens to http requests and interacts with the database.
The Java back end run continuously and responds to calls from the front end.
More specifically, the back end is a daemon that connects and maintain the link to several IM services (AOL, MSN, Yahoo, Jabber...).
Both of the layers will be deployed on the same system (a CentOS box, I suppose) and introducing a middle layer (for instance: using XML-RPC) will reduce the performance (the resource is also rather limited).
Question: Is there a way to link the two layers directly? (no more web services in between)
Since this is communication between two separate running processes, a "direct" call (as in JNI) is not possible. The easiest ways to do such interprocess communcation are probably named pipes and network sockets. In both cases, you'll have to define a communication protocol and implement it on both sides. Using a standard protocol such as XML-RPC makes this easier, but is not strictly necessary.
There are generally four patterns for application integration:
via Filesystem, ie. one producers writes data to a directory monitored by the consumer
via Database, ie. two applications share a schema or table and use it to swap data
via RMI/RPC/web service/any blocking, sync call from one app to another. For PHP to Java you can pick from the various integration libraries listed above, or use some web services standards like SOAP.
via messaging/any non-blocking, async operation where one app sends a message to another app.
Each of these patterns has pros and cons, but a good rule of thumb is to pick the one with the loosest coupling that you can get away with. For example, if you selected #4 your Java app could crash without also taking down your PHP app.
I'd suggest before looking at specific libraries or technologies listed in the answers here that you pick the right pattern for you, then investigate your specific options.
I have tried PHP-Java bridge(php-java-bridge.sourceforge.net/pjb/) and it works quite well. Basically, we need to run a jar file (JavaBridge.jar) which listens on port(there are several options available like Local socket, 8080 port and so on). Your java class files must be availabe to the JavaBridge in the classpath. You need to include a file Java.inc in your php and you can access the Java classes.
Sure, there are lots of ways, but you said about the limited resource...
IMHO define your own lightweight RPC-like protocol and use sockets on TCP/IP to communicate. Actually in this case there's no need to use full advantages of RPC etc... You need only to define API for this particular case and implement it on both sides. In this case you can serialize your packets to quite small. You can even assign a kind of GUIDs to your remote methods and use them to save the traffic and speed-up your intercommunication.
The advantage of sockets usage is that your solution will be pretty scalable.
You could try the PHP/Java integration.
Also, if the communication is one-way (something like "sendmail for IM"), you could write out the PHP requests to a file and monitor that in your Java app.
I was also faced with this problem recently. The Resin solution above is actually a complete re-write of PHP in Java along the lines of JRuby, Jython and Rhino. It is called Quercus. But I'm guessing for you as it was for me, tossing out your Apache/PHP setup isn't really an option.
And there are more problems with Quercus besides: the free version is GPL, which is tricky if you're developing commercial software (though not as tricky as Resin would like you to believe (but IANAL)) and on top of that the free version doesn't support compiling to byte code, so its basically an interpreter written in Java.
What I decided on in the end was to just exchange simple messages over HTTP. I used PHP's json_encode()/json_decode() and Java's json-lib to encode the messages in JSON (simple, text-based, good match for data model).
Another interesting and light-weight option would be to have Java generate PHP code and then use PHP include() directive to fetch that over HTTP and execute it. I haven't tried this though.
If its the actual HTTP calls you're concerned about (for performance), neither of these solutions will help there. All I can say is that I haven't had problems with the PHP and Java on the same LAN. My feeling is that it won't be a problem for the vast majority of applications as long as you keep your RPC calls fairly course-grained (which you really should do anyway).
Sorry, this is a bit of a quick answer but: i heard the Resin app server has support for integrating java and PHP.
They claim they can smash php and java together: http://www.caucho.com/resin-3.0/quercus/
I've used resin for serving J2ee applications, but not for its PHP support.
I'd be interested to hear of such adventures.
Why not use web service?
Make a Java layer and put a ws access(Axis, SpringWS, etc...) and the Php access the Java layer using one ws client.
I think it's simple and useful.
I've come across this page which introduces a means to link the two layers. However, it still requires a middle layer (TCP/IP). Moreover, other services may exploit the Java service as well because it accepts all incoming connections.
http://www.devx.com/Java/Article/20509
[Researching...]

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