From what I understand, SWIG is to wrap C++/C to make it appear in Java, and javah is to implement certain java functions in C++ ( aka native functions ).
Is there a tool which can create a C++ wrapper over a java class, so that the caller. of this c++
wrapper doesn't have to worry about java, for example
Input Java is
class hw {
public void hi() {
System.out.println("Hello World");
}
}
Tools outputs hw.hh ( and some. c++ files ), which can be used as:
hw *h = new hw(/*JEnv */ env);
h->hi();
Is there a tool available which can do this ?
Options include, the following, in ascending order of expense to you.
Hand-written JNI code written by clients of your Java class.
Hand-written, JNI-driven wrappers written by you for clients of your class.
JACE-generated wrappers. JACE is a free tool. Last version was in 2008; not sure if development is continuing.
JunC++ion-generated wrappers. This commercial library produces the best results with the least development effort. It supports Java callbacks, with C++ classes implementing Java interfaces. The author is very responsive and a very nice guy. However, there is a price tag, and you'll want to be sure about deployment costs.
I used this product a long time ago, http://www.codemesh.com/products/junction/
It will do exactly what you want.
Just a disclaimer, I used it almost 6 years ago. I am not affliated with this product.
Related
I am quite new to python and am trying to call python's function from java.
My primary requirements are these:
call should be transparent, in the sense that it should not require modifying .py file simply to enable it to be called from java. I might be given any python file with some functions inside it. I should be able to call any of these functions without requiring to modify .py file.
I want to be able to send arguments of both primitive types (int, String, floats etc.) or non primitive types (HashMap,ArrayList) from java to python function and receive back the returned object (which may of primitive types or non-primitive types) from python to java. I am also using pandas DataFrame and numpy ndarray and hence also want to be able to send and receive corresponding objects to and from java.
I preferably want to stick to CPython instead of Jython because I might need to use newer libraries that might not be available in Jython.
There are several options that I found online. Few are:
Use Jython's PythonInterpreter with which I am able to invoke python function without requiring any changes to .py script file:
py1.py
def square2(list):
squares = []
for i in list:
squares.append(i*i)
return squares
JythonTest.groovy
import org.python.util.PythonInterpreter
import org.python.core.*;
class JythonTest
{
static main(def args)
{
PythonInterpreter pi = new PythonInterpreter()
pi.exec("from py1 import square2")
PyFunction pf = (PyFunction)pi.get("square2")
println pf.__call__(new PyList([1,2,3,4]))[2] //9
}
}
I am very well able to satisfy my needs. But its not CPython.
Use ScriptEngine: This is very similar to PythonInterpreter. But agains its Jython. Also, unlike PythonInterpreter, we cannot work with Jython 2.5+ and cannot directly access PyObjects. So this option can be very well closed.
Use py4j: Cant find example which is as minimal as in case of Jython PythonInterpreter
Use java2python. But not much information is given about calling python from java so that I can conclude whether my above requirements can be satisfied. Can anyone shed more light on this? More specifically if we can write the code as minimal as the one in Jython PythonInterpreter.
Use JPype: However after quick go through I feel I will not be able to write as minimal code as in case of Jython PythonInterpreter. Also I felt the project somewhat not under developement. Is it?
It seems that Jython PythonInterpreter is the best choice if I have understood all above approaches correctly. Have I made mistakes while grasping them? Also is there any other better option?
#Mahesha999, regarding the ability to stick with CPython which seems important now from your last comment:
Jep is a good option to be able to run python code which uses calls to native, like pandas that you mentionned.
You'll need to write some wrapping code because Jep only implements automatic conversion between Java and Python between the most used types, which pandas.DataFrame is not.
However if your use case is not to complex, you can access your pandas objects as numpy.NDArray object by calling DataFrame.values on your dataframe instance, and Jep implement conversion to the Java class it embeds for NDArray.
You can get back to Java values from python code you execute by using Jep.getValue(String pythonVariableName, Class clazz)
For example
Jep jep = new Jep();
jep.eval("import my_script");
jep.eval("df = my_script.function_returning_a_dataframe()");
jep.eval("col = df.a_column.values");
NDArray myCol = jep.getValue("col", NDArray.class);
I do so on a project I coded in Python that I need to integrate as a plugin in a Java application, so far it works.
There is no current answer to this problem. Using CPython relies on the execution of Python bytecodes, which in turn requires that the Python interpreter be embedded in the execution environment. Since no Java runtime comes with an embedded Python interpreter, it really does look as though Jython is the best answer.
Sometimes the answer you want just isn't available!
I want to call Rust code from Java / Android, and I've found 3 variants to do so:
JNI
JNA
JNR FFI
JNI looks good and powerful enough, but you have to
write too much code by hand.
JNA, if not taking into consideration that it crashes on my machine, requires writing Rust struct data type description in Java by hand,
the same problem with JNR FFI.
So I wonder how difficult will be generate JNI code
for traits and struct with macros or a compiler plugin?
This compiler should match traits implementations for concrete struct,
and also struct
#[JNI]
struct Foo {
a: i32,
}
trait Boo {
fn f(&self, b: f64) -> f64;
}
#[JNI]
impl Boo for Foo {
fn f(&self, b: f64) -> f64 {
0f64
}
}
and create Java classes for struct and Java classes with native functions, plus generate pub no_mangle functions that wrap traits functions.
In order to provide #[jni] annotations that work like that you'd need to use a compiler plugin. It would be an awesome tool, but it doesn't exist yet, as far as I know.
There are bits and pieces of tooling lying around that might be helpful, if you want to create a project that does this.
Plugins are currently unstable, and don't work on non-nightly rust; you would probably want to use syntex, which provides a stable interface to compiler plugins. You could also write a raw plugin (see here for the API for those), but most people won't be able to use it.
There's rusty-cheddar, which generates c header files; you could take a look at that to see how it works. The author of that also seems to be working on a more general bindings-generation framework, but I don't know if it's active. You might be able to hook the output of cheddar up to something like JNAerator, but it probably won't create the prettiest interfaces on the java side.
There's also rust-bindgen and corrode, which work in the other direction; they translate c headers and arbitrary c code to rust respectively. I don't know if that's actually helpful.
JNI-sys provides low-level JNI bindings; rust-on-mobile is a small project that uses it. Also see First steps with Rust and Java, a blog post that shows some rudiments of getting things hooked up.
Finally, there's cbox, which lets you work around awkwardness with ownership and FFI.
Finally I created such project (link to github repository) to automate
binding creation.
You can use jnaerator to auto-generate your structure mappings for JNA.
Alternatively, if you want to use JNI (and compile some more native code) you should go with SWIG.
I am creating a GUI using Jython. I want to program my logic in C. How could I can call a C Function from my Python Code. Sorry if this a newbie question, but I have never worked with linking files except Sparc Assembly from C.
Jython cannot use ctypes, or C extension modules (whether built manually, or with Cython, or otherwise).
The way to do this is the same way as in Java: Through a JNI bridge.
First, you write a C++ wrapper that talks to the so, and uses functions from <jni.h> to implement functions like this:
JNIEXPORT void JNICALL _PACKAGE(bar)(JNIEnv *env, jclass cls, jint i) {
if (bar(i)) {
throwPyFromErrno(env, OSError);
}
}
Next, in Java, you define a public class full of Java wrappers around those C++ wrappers, like this:
public class foo implements InitModule {
public final static native void bar(int i);
}
Finally, in Jython, you can just import the class (which acts like a Python module) from its Java module and use it like any other module:
try:
foo.bar(3)
except OSError as e:
print "Failed:", e
Most of this is standard JNI, but you also have to know things like how to create Jython objects. Ideally, you'll use wrappers for that, so you can just write makePyInteger(env, value) or throwPyFromErrno(env, exctype) instead of doing all the FindClass, GetStaticMethodID, etc. stuff manually.
I don't have any tutorials to recommend. But see jnios for a nice-sized example. The O'Reilly book's Chapter 25. Extending and Embedding Jython seems like it might be a decent primer (although I haven't read it). You'll probably want to read a tutorial on using JNI for Java before trying to tackle Jython.
A different way to solve this problem is to break your single program into two pieces.
The GUI program runs in Jython. When it needs to call the C code, it does that by running a worker program.
The worker program runs in CPython or PyPy, so it can use any of the usual techniques for talking to C libraries: ctypes, cffi, a custom C extension module (maybe using Cython, Boost.Python, SWIG, SIP, …), Weave, etc.
For a simple case, where you just need to call one function, pass it a few strings, and get back a string, it's as trivial as this:
import subprocess
def my_function(*args):
return subprocess.check_output(['python',
'/path/to/worker/script.py'] + args)
(Note that there are a few bugs with subprocess in older versions of Jython, especially on OS X and Windows. If you run into a problem, 2.5.4 and 2.7.0, which are currently in RC and beta stages, respectively, have probably fixed it.)
If you need to make lots of calls one at a time throughout the life of your program, you'll probably want to keep the worker script running in the background, and use some form of RPC to talk to it. This blog post shows how to do it using the bjsonrpc library.
What is the common way (or best practice) to optionally use JNI?
E.g. I have a Java class and this class is 100% pure Java, so it can run on all platforms. However, on some platforms I'd like to speed up some heavy calculations using JNI - which works fine. Unfortunately I cannot support any existing Java platform in the world. So I guess it is fine to initially only support the big three: Linux, Windows, Mac OS X.
So what I'd like to do is to use JNI on those three platforms and use the 100% pure Java version on all other platforms. Now I can think of various ways how to do that (loading class dynamically for example and either loading the JNI class or the pure Java one), but thinking that this is a common issue that thousands of projects had to solve in the past for sure, I'm really surprised to not find any documentation or references to the question how to solve this most elegantly or effectively.
If it really makes sense to supply two different versions you could do the following:
Create an interface for the class
Implement the interface in a class in pure Java
Implement the interface in a class that uses JNI
Then you can write a factory method that instantiates the correct class:
public static SomeInterface getInterface()
{
SomeInterface res = new JavaSomeInterfaceImpl();
if (System.getProperty("os.name").matches(".*Windows.*"))
{
File library = new File("mylibrary.dll");
System.load(library.getAbsolutePath());
res = new NativeSomeInterfaceImpl();
}
return res;
}
Your platform dependant code should be in a platform dependant class ;-)
Suppose you have a main "Algorithm" class (or better, interface).
This interface is implemented by a WindowsAlgorithm using JNI and a HaikuAlgorithm not doing so (it's only for the sake of example). The only thing you have to do now is to load the right one depending upon your client OS, which I think is rather mundane to do.
I have a Python interface of a graph library written in C - igraph (the name of library). My need is to invoke the python modules pertaining to this graph library from Java code. It goes like this, the core of library is in c. This core has been imported into Python and interfaces to the functions embedded in core are available in Python. My project's rest of the code is in Java and hence I would like to call the graph functions by Java as well.
Jython - which lets you invoke python modules with in Java was an option.I went on trying Jython to discover that it will not work in my case as the core code is in C and Jython wont support anything that is imported as a c dll in python code.I also thought of opting for the approach of calling graph routines directly in c. That is without passing through Python code. I am assuming there must be something which lets you call c code from Java, how ever I am not good in C hence I did not go for it.
My last resort seems to execute Python interpreter from command line using Java. But that is a dirty and shameless. Also to deal with the results produced by Python code I will have to write the results in a file and read it back in java. Again dirty way.
Is there something that any one can suggest me? Thanks to every one giving time.
Thanks Igal for answering. I had a look at it. At first glance it appears as if it is simply calling the python script.
Jep jep = new Jep(false, SCRIPT_PATH, cl);
jep.set("query", query);
jep.runScript(SCRIPT_PATH + file);
jep.close();
Isnt it very similar to what we would do if called the python interpreter from command line through a Java code.
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("python test.py");
Concern is how do I use the results generated by Python script. The naive way is to write them to file and read it back in Java. I am searching for a smarter approach.Thanks for suggestion anyway.
Never tried it. But I recently stumbled on a project named Jepp that may be of interest to you.
Jepp embeds CPython in Java. It is safe to use in a heavily threaded environment, it is quite fast and its stability is a main feature and goal.
If you want to call C functions from Java, JNA (Java Native Access) is probably the way to go. JNA allows you to call functions in native libraries without having to write the C glue code (as you would have to when using JNI), and automatically maps between primitive data types in Java and C. A simple example might look like this:
import com.sun.jna.Native;
import com.sun.jna.Library;
public class PrintfWrapper {
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary)Native.loadLibrary("c", CLibrary.class);
void printf(String formatString, Object... args);
}
public static void main(String[] args) {
CLibrary.INSTANCE.printf("Hello, world\n");
}
}
However, things will get complicated with igraph because igraph uses many data structures that cannot be mapped directly into their Java counterparts. There is a project called JNAerator which should be able to generate the JNA source from igraph's header files, but I have never tried it and chances are that the results will still need some manual tweaking.
Also note that a Java interface for igraph is being developed slowly but steadily and it might become useful in a few months or so.
You can use jep.getValue() to retrieve a value from script's global dictionary.
There are caveats to that concerning scope levels in Python, so most people find it clearer to pass a Java class to python and set the return value in that instance in Python. After the script completes, the Java code will then have the result.
For example:
==> Java
class ReturnValueClass {
public int scriptResult;
};
ReturnValueClass value = new ReturnValueClass();
jep.set("retval", value);
==> Python
# do something
pass
# write the return value
retval.scriptResult = some_python_value
==> Java
System.out.println(value.scriptResult);
Hope that helps,
Mike (I wrote Jep)