J++ to Java: how to migrate from RNI to JNI? - java

I've inherited a legacy J++ project. I've upgraded this project to standard Sun Java successfully.
However, this project includes a native C++ dll which the Java code talks to via the Microsoft-specific RNI framework.
Needless to say, calling System.loadLibrary("myRniNativeDll") now throws a UnsatisifiedLinkError, saying one of the dependencies couldn't be found.
I'm totally clueless how to migrate a C++ RNI dll to a JNI dll; I've no idea where to begin. I have the C++ source code, but I don't know how to build a JNI dll. Are there any tips/tutorials/online materials you Java experts can point me to?

If the licensing is acceptable (LGPL), Java Native Access provides a rather friendlier FFI than the JNI does; porting may reduce to stripping away the RNI layer and just exposing a simple 'C'-callable API.

Take a look at JNA - it might be possible to access the RNI DLL directly that way; or at least it will make the job of porting it much easier than doing JNI manually.

If possible, I suggest that you consider avoiding the RNI -> JNI porting problem by rewriting the C++ code in pure Java.
Writing JNI code requires a huge amount of care, and places JVM stability at risk if you get it wrong. My advice is to avoid it if you possibly can.

While I have never used Microsoft's RNI, only Sun's JNI, I would expect that you couldn't directly use an RNI-style DLL as if it were a JNI-style DLL. I am also unaware of anything that would automatically convert or bridge RNI to JNI.
You do not mention if you have the source to the C++ RNI DLL, although I'll assume you do since you mention inheriting the project. If you have any C++/C experience, and have a good idea of what functionality the RNI DLL is providing, it should not be too difficult to move it to JNI. The time invested in porting it would likely pay off for maintaining it moving forward.
The link you provided to the JNI entry on Wikipedia has lots of helpful links on coding with JNI. Without a bit more detail, it is hard to give any other advice.

Java Native Interface: Programmer's Guide and Specification is the best resource that I've found for writing JNI code. It doesn't cover RNI -> JNI, but it is a great* starting point for learning how JNI works.
*It's actually very dry, and not particularly fun to read, but it's the best I've been able to find.

Related

Python egg that makes Java calls to a running Java application

I am making a proposal for a Python adapter to the Oracle NoSQL Database. The Oracle NoSQL Database runs as a stand alone java application, and at least in a Java program, you interface with it by telling your program the hostname and port to connect to, and some configuration settings. Then you make java calls off of the "kvstore" object that contains that configuration.
I'd like to make a Python library that essentially exposes Python versions of the java methods Oracle NoSQL has, and converts those to Java to speak with the running Oracle NoSQL application, but I'm not sure what technologies would be best to be able to do that.
Does anyone know what technology I would want to use? I'd rather not use Jython (so the application could run in a standard Python environment) or JNI (as it seems to have some nasty caveats.)
EDIT: The only potentially technology I've found so far is: Jpype
Would it work for me?
Also, here are the ideal requirements the library would have. I would consider using Jython or JNI if one of them really did best match these requirements.
Performance. The main benefits of Oracle NoSQL are performance and scalability, so that would be the most important component for the adapter.
Easy to implement for the Python users. In order for the library to actually be used by Python programmers, it would have to relatively easy for them to use in a natural sort of way.
Reliability. It would need to be possible for it to be trustworthy and bug free, while working on the platforms you naturally expect Python to work on. (This is what made me concerned about JNI. It sounds like it is platform dependent for its implementation, and can be error-prone.)
Development speed. The last point of importance is that it be relatively fast to develop. The team of developers would enjoy learning Python or C, but we know Java better than any other programming langauge right now.
I've tried to answer each point in order, with it's own related notes.
Performance: My opinion is that JNI would be the winner here, but I could be wrong, because Jython could be JITed as well.
Easy to Implement: I am taking this as you mean easy to consume the library? That would depend entirely on how you build the API, 1 to 1 method calls, object handles, etc.
Reliability: Jython is the clear winner here, because there is no room for error when you merely instantiate POJOs/ directly access the API right in the client code.
Development Speed: JNI can be very tedious. You are essentially learning CPython modules, C, Python extensions, JNI and then referencing an existing API built in Java.
All in all, if you can make the jump, I think you'd get more benefit in the short term embedding Jython, mostly because there you can directly manipulate the API. I have personally embedded IronPython in a .NET codebase with good success. Yes you lose native speed, but the tradeoffs are hard to justify with the amount of C coding needed for a working JNI bridge. That said, you may well find projects like the one you listed (Jpype) that can do much of the legwork for you.
I would be asking what features of a native CPython runtime I need that you lose when going to Jython. Is your existing codebase in CPython heavily reliant on CPython native features?
Anyway, there's my attempt at an answer.

Declare function from JNI

Is there any way to create native function from jni without creating dll? I mean like in python http://docs.python.org/2/extending/embedding.html
Section 5.4. Extending Embedded Python
I don't want to use dll exported functions.
Regards
You can embbed VM in a native application, call into Java from C/C++ then callback from Java back into C/C++. See the Invocation API in JNI documentation. This way there is no need for dynamic linking (DLLs). You can also dynamically generate classes in runtime by generating bytecode with native methods (e.g. with ASM) and then registering whatever C/C++ function pointers you need with RegisterNatives.
technically it is possible.
Around 6 or 8 years ago I saw a C++ implementation (it was at codeproject site presented), which created a JVM and did access Java classes. Isn't very popular, for very good reasons, are to many to enumerate here, but is possible.
I would strongly recommend to do the other side, exactly what you don't want: java invoke the dll or so, but to many reasons, but is up to you...
Perhaps JNA does what you want?

How can I leverage C++ code in the JVM?

I'm working with a project that was built in C++. Within this project are public classes that contain public methods that I would like to call from my Java code. What's the best way to make this happen? I imagine I'd want something that would compile the C++ code down to bytecode.
I've seen a couple tools that do something like this, but some of them have not been updated for a very long time, and others seem inappropriate for the task. Are any of these tools mature enough to be used for a professional-grade app? Although open-source is preferable, I'm equally willing to consider commercial tools.
I am currently using a package aptly named javacpp. I believe it is worth taking a look at
There's always the old standby, JNI, known for being slow and very hard to use.
JNA is something I've never used personally but "I've heard good things" and it looks like it might fit your bill.
An alternate and potentially better approach would be to restructure your C++ code as a service that listens on e.g. TCP or UNIX sockets. This would increase the portability, make it possible to connect to it from most languages, and is not Java-specific.
Bridging C++ to Java using JNI (Java Native Interface) is actually pretty easy. Downside is you need to compile the C++ part for the platforms you want the code to work with.
I've got an example of calling Java from C++ in this post Can C++ call Java code? but calling C++ from Java is quite similar.

Wrapping C/C++ inside Java

I develop applications/programs in C/C++. I am more versed in these two languages and love being a C++ developer. I am wondering how to create a Java program that contains all my C++ code.
I mean, I would like to wrap all my C++ code (that is already developed) inside Java class. But clueless how to do it.
Please post your responses or methods/steps on integrating C++ inside Java.
(using JNI is the way, but I could not figure it out on www how to use it)
FYI, I use Eclipse IDE to develop.
How and what packages should I include in my project workspace?
Instead of JNI, or JNI with some assist from an automatic wrapper generator like SWIG, or even JNA, you might consider separating the C/C++ and Java into separate processes and using some form of IPC and/or Java's Process abstraction to call to a program written in C/C++. This approach abandons "wrapping," so in some sense it isn't an answer to this question, but please read on before down-voting. I believe that this is a reasonable answer to the broader issue in some cases.
The reason for such an approach is that when you call C/C++ directly from Java, the JVM is put at risk of any error in the native code. The risk depends somewhat on how much of the native code is yours and how much you link to third party code (and how much access you have to the source code of such third party code).
I've run into a situation where I had to call a C/C++ library from Java and the C/C++ library had bugs that caused the JVM to crash. I didn't have the third party source code, so I couldn't fix the bug(s) in the native code. The eventual solution was to call a separate C/C++ program, linked to the third party library. The Java application then made calls to many ephemeral native processes whenever it needed to call the C/C++ stuff.
If the native code has a problem, you might be able to recover/retry in Java. If the native code is wrapped and called from the JVM process, it could take down the entire JVM.
This approach has performance/resource consumption implications and may not be a good fit for your application, but it is worth considering in certain situations.
Having a separate application that exercises the functionality of the C/C++ code is potentially useful as a stand-alone utility and for testing. And having some clean command-line or IPC interface could ease future integrations with other languages.
As another alternative, you could get into native signal handling to mitigate the risks to the integrity of the JVM process if you like and stick with a wrapping solution.
If you want to call C++ from Java, you'll need to use JNI - Java Native Interface.
Be warned that you lose some of the benefits of the garbage collector, since it can't deal with your C++ objects, and your code won't be portable anymore.
Maybe you'd be better served by learning to write 100% Java and leaving C++ behind, but that's just a suggestion.
You can't "just wrap it", you have to write some C/C++ glue.
For starters, SWIG can do most of the works for you.
There are plenty of tutorials for doing exactly what you want to do. For example, check out: http://www.javamex.com/tutorials/jni/getting_started.shtml
There are also plenty of caveats of using JNI. I've recently started working with it (just for fun, really), and it tends to be a lot less fun than I had first anticipated.
First of all, you have to deal with cryptic code such as:
#include "test_Test.h"
JNIEXPORT jint JNICALL Java_test_Test_getDoubled(JNIEnv *env, jclass clz, jint n) {
return n * 2;
}
Second of all, it tends to downplay one of the primary reasons why you use Java in the first place: WORA (Write Once, Run Anywhere). As duffymo mentioned, there can also be issues with the garbage collector, but I think that in recent years, the JVM has gotten pretty smart about JNI integration.
With that said, to port all of your C++ code to JNI, you'd need to refactor your interfaces (and maybe even do some internal gymnastics). It's not impossible, but it's really not recommended. The ideal solution is just re-writing your code in Java.
With that said, you could also "convert" your code from C/C++ into Java programatically, and there are multitudes of such utilities. But, of course, machines are dumber than people and they are also bound to make mistakes, depending how complex your class is.
I would avoid JNI because it's tedious to write, verbose, and just an altogether pain. Instead I'd use JNA library which makes writing native integration so simple.
https://github.com/twall/jna/
Good luck.
You can write C++ code through JNI but there isn't a direct mapping from C++ classes to Java classes.
I've used JNI to fix problems found in the android SDK (specifically, an incredibly slow FloatBuffer.put implementation) and I may end up using it for some performance critical areas. My advice would be to be use it sparingly and in a duck in, do the performance critical stuff and leave, without doing any memory allocation if you can help it. Also, don't forget to measure your code to see if it really is faster.
Out of interest, what platform are you developing for? The only platform where it would make sense to wrap a lot of C++ code in a light java layer would be Android - on other platforms, just compile in C++ and have done with it.
JNI module is not a Java classes. It's C. Using JNI incur many restrictions and some Java environment doesn't support JNI well.
There is no supported way of "wrap my C++ code inside Java class" (EDIT: I mean, without JNI noway but JNI is problematic.)
You could investigate custom C++ compiler emit Java byte codes, but nobody (include me) will recommend this approach.
BridJ was designed on purpose for that (and it's supported by JNAerator, which will parse your C/C++ headers and spit out the Java bindings for you).
It is a recent alternative to JNA, with support for C++.

Best way to access Java classes from C++? (better than using JNI directly)

I have to integrate a large Java library in a quite large C++ application. A solution is to use JNI but this requires to hand code all the classes. Python has, for example, a wonderful solution with JPype (http://jpype.sourceforge.net/) that automatizes the process (although the same solution cannot be applied to C++ due to C++ and Python different natures).
Thanks,
Das
SWIG is a tool that lets you auto-generate bindings from one language to another. It supports C++ and Java and a dozen other languages.
Seems that my question was not clear enough. Maybe the confusion comes from JNI that allows the access in booth directions ...
What I want to do is to access a Java library FROM C++. That is, someone give me a JAR file that contains a collection od JAVA compiled classes and I must write code in C++ to access it (as I want to integrate the functionality of that Java library into a C++ application).
Hope that this clarifies the direction of access :)
Thanks,
Das
Not sure if this commercial tool makes life any easier, but you might wanna explore -- http://www.teamdev.com/jniwrapper/index.jsf
JNA is not quite what you're looking for, but it does make your life a lot easier. It doesn't require any boilerplate/generated code - you just write an interface for the methods you want to call.
Certainly, there is every reason to use JNA instead of JNI.
I have two suggestions which may or may not work for you:
First, you could try something very simple. Run the Java code in a separate process, and communicate with it with pipes or sockets. This is fairly easy to do, and doesn't require any crazy libraries. The downside is that the communication is somewhat limited (just some simple pipes), you'll need to write your own wrapper around it to send data across
Secondly, what exactly is this library? Perhaps we can suggest alternatives that are not written in Java, that would be much easier to use in your C++ application?

Categories