17

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?

  • Your general problem can't easily be solved; converting each C++ class one at a time into Java classes through JNI is quite difficult. Why do you want to use these C++ classes in Java? Is there a reason you must use Java but want the existing functionality? – templatetypedef Jan 12 '11 at 02:47
  • I do not want to lose the functionality of my c++. It does certain functions that Java cant do by itself and I do not know much how to do it everything in Java. So I would like to integrate my c++ inside Java. :-) :-) –  Jan 12 '11 at 02:52
  • 3
    "...It does certain functions that Java cant do by itself..." - I'd sincerely question this statement. "Can't do"? Evidence, please. – duffymo Jan 12 '11 at 02:57
  • What's wrong with just keeping it in C++? – jamesmortensen Jan 12 '11 at 03:05
  • @duffymo, perhaps some OS specific system calls? – Charles Salvia Jan 12 '11 at 03:05
  • @Charles, in that case (imo), the OS specific calls should be isolated and written via JNI, but you don't need a whole class to implement those calls. If you're doing Java, you gotta' follow Java's rules :P – David Titarenco Jan 12 '11 at 03:16
  • You can't do OS specific calls with Runtime.exec or Process? Sorry, I'd prefer that to JNI. – duffymo Jan 12 '11 at 11:39
  • I have an interest in this question because we have some legacy c/c++ code that executes a very complex algorithm that was written by someone else two decades ago for use in a fat-client application. We intend to web-enable the application but it will be a nightmare to rewrite the algorithm in Java, mainly because nobody can understand the logic. It would much simpler to wrap it up as it is and include it in the application. – GeraldScott Jan 05 '18 at 14:27

8 Answers8

21

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.

Community
  • 1
  • 1
Greg Mattes
  • 33,090
  • 15
  • 73
  • 105
  • Thanks for your answer. Well, my architectural skills is not soo good.. But I must write the app as you mentioned (separate them to 2 processes), I must consider this advice. Will take time for me to get back to you with few questions. Thanks, again.. –  Mar 03 '11 at 05:53
12

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.

Tushar
  • 8,019
  • 31
  • 38
duffymo
  • 305,152
  • 44
  • 369
  • 561
  • 1
    I have everything ready in my C++ to garbage collect from all parts of code. I would feel great for you if you could post me a minimal example on using JNI. :-) –  Jan 12 '11 at 02:53
  • That's what the tutorial in the link is for. – duffymo Jan 12 '11 at 02:56
  • 3
    1+ for "Maybe you'd be better served by learning to write 100% Java and leaving C++ behind" – Fingolfin Jun 02 '12 at 19:07
  • 69
    -1 for "Maybe you'd be better served by learning to write 100% Java and leaving C++ behind." – derpface May 20 '14 at 13:15
  • 13
    Maybe he wants to use a library written in C or C++. That's the usual reason why people do this sort of thing. It has nothing to do with people being too lazy to learn Java. – John Nov 19 '14 at 16:30
5

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.

J-16 SDiZ
  • 26,473
  • 4
  • 65
  • 84
  • SWIG is nice if you want to write multiple bindings between several languages. Write the mapping once and just generate ports. But it's still too much work to redefine all the data structures to map everything even in SWIG. It's better than writing JNI. But there are better alternatives ala JNA. – chubbsondubs Jan 12 '11 at 03:01
3

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.

David Titarenco
  • 32,662
  • 13
  • 66
  • 111
1

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.

chubbsondubs
  • 37,646
  • 24
  • 106
  • 138
1

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.

Luther
  • 1,786
  • 3
  • 21
  • 38
0

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.

9dan
  • 4,222
  • 2
  • 29
  • 44
0

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++.

zOlive
  • 1,768
  • 13
  • 11