Archived

This topic is now archived and is closed to further replies.

Krumble

Java/C++ Integration

Recommended Posts

Krumble    151
Hello, I''ve been messing around with the idea of using a C++/Java conglomerate in my next big project. The idea is using C++ for the processor intensive stuff, and Java for the rest. Basically, my C++ program spawns a JVM and interfaces with it through the JNI interface. Anyway, I was wondering if anyone had any resources to the JNI stuff other than what''s on SUN''s site. I can''t seem to find anything solid as far as spawning a JVM inside a C++ program, just little tidbits here and there. One thing that''s really bothering me so far, is that I couldn''t find the library for my little test program to link against. By trial and error I found that linking with libgcj worked as expected, but I don''t think this is the way that it''s meant to be. Just so it''s clear what I''m taking about, here''s a paste of my little test program. Thanks, Kevin
//C++ program that uses a Java program to calculate the pth prime for all primes less than 60000

javaincpp.cpp
#include <iostream>
#include <jni.h>

using namespace std;

int main() {
  JavaVM *jvm;
  JNIEnv *env;
  
  if (JNI_CreateJavaVM(&jvm, (void**)&env, 0) == JNI_ERR) {
    cout << "Error creating java vm" << endl;
  } else {
    jclass cls = env->FindClass("Test");
    jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)I");
    cout << "What prime would you like ";
    int p;
    cin >> p;
    cout << "The " << p << "th prime is: " 
	 << env->CallStaticIntMethod(cls, mid, p)
	 << endl;
  
    jvm->DestroyJavaVM();
  }
}

Test.java
import java.util.*;

public class Test {
    public static int test(int pr) {
	int[] primes = new int[60000];
	for(int j=0; j<60000; ++j)
	    primes[j] = j % 2;
	primes[2] = 1;
	for(int j=3; j<60000; j+=2)
	    if (primes[j] == 1)
		for(int k=j+j; k<60000; k+=j)
		    primes[k] = 0;
	for(int j=0, cnt=0; j<60000; ++j)
	    if (primes[j] == 1)
		if (cnt == pr)
		    return j;
	        else
		    ++cnt;
	return 0;
    }
}

Makefile
all:
	javac Test.java
	g++ -o javaincpp javaincpp.cpp -Wall -O2 -lgcj # I shouldn''t have to link against libgcj should I?

clean:
	rm -f javaincpp Test.class

Share this post


Link to post
Share on other sites
markr    1692
I think you have to link against libjava; it''s in the SDK somewhere.

libgcj is the gnu compiler for Java. It includes a JVM which can run bytecode too (dunno if it has a JIT; it definitely has an interpreter).

gcj is the gnu compiler for Java - it makes .java files into native code. There is a class library too (although it''s incomplete at best).

People who think that Java runs too slowly often cite gcj as being better than existing JVMs - because it compiles to native code. This is usually because they measure it by its startup time rather than it actual runtime performance.

Unfortunately, code made with gcj actually runs rather slower than modern JVMs JIT. This is because the JIT actually makes good native code, and gcj does not.

As far as I''m aware, either the library that gcj relies on, or gcj itself, is Unix-specific (that''s to say, there is no Windows port of it).

Mark

Share this post


Link to post
Share on other sites
markr    1692
Having said that, I seem to recall that gcj provides the "Java is just another programming language" idiom. There is some way which you can call C++ classes from Java (and vice versa) without having to jump through JNI hoops.

JNI is clumsy and error-prone. I don''t like it.

Mark

Share this post


Link to post
Share on other sites