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?
Related
I have a large programme written in C++ that needs to use a specific Java library. Ideally I would like to create an equivalent C++ library that wraps this existing Java code. As such I have been looking into the JNI invocation API.
Since I am not a very experienced programmer, and I am also inexperienced with JNI and multi-language programming, I would greatly appreciate some general pointers/tips/advice as to how to tackle this problem.
Things I would be especially interested to know:
Should each Java class in the Java lib map to to an associated C++
class? I.e. in my C++ library, will I have a class each invoking a
JVM for a particular Java class? Or will I have a singular JVM through which everything is accessed? What is the best way to do this and why?
What will be the basic process and architecture for doing this?
Are there any specific resources for creating a C++ lib from Java lib using the invocation API?
Thanks a lot!
I've done this before, but it's not for the faint-hearted especially if your interface between the 2 languages is hard. Debugging can also be a pain in this situation.
To answer your points:
You should start by deciding on what functionality from the Java library you need to access in your C++ program. Is it just a few tasks? Try making a very simple interface from C++ to Java in this case. Is it complicated? Then you're gonna have to start mapping Java classes to C++, and the more you need then the more work it's gonna be.
The end of q1 is sorta q2 really. Your C++ program will start a single JVM which will run as part of your program. When you make calls across the C++ data will be transferred into the JVM, and then the Java code executed, and then the return values transferred back. This incurs a performance cost so calling small functions like add(int,int) through JNI would be more expensive than just doing it in C++.
There's a lot of basic guides you can Google to get started. Just managing to start a basic JVM from C++ and making a call is actually a bit of work since you need to get the paths to the JVM libs correct or it doesn't work (unless they've improved this, it's been years since I tried). So you might want to check that out first before asking more specific questions about JNI and mapping functions.
An alternative option (which may or may-not be possible depending on your library and use-case) is to just write some kind of wrapper service around your library, actually in Java. And then send requests to it via JSON-HTTP or some messaging system.
An even-more alternative option, rewrite whatever the library is doing in C++.
You can use scapix::link::java C++ JNI library to generate C++ headers for any Java code, then easily access this Java code from C++. Here is an example:
#include <scapix/java_api/java/lang/System.h>
#include <scapix/java_api/java/util/Locale.h>
#include <scapix/java_api/java/text/DateFormatSymbols.h>
using namespace scapix::link::java;
using namespace scapix::java_api;
void test1()
{
// C++ objects are automatically converted to and from corresponding Java types.
// This works for any type supported by scapix::link::java::convert() interface,
// which supports many STL types and can be extended for your own types.
std::string version = java::lang::System::getProperty("java.version");
std::vector<std::string> languages = java::util::Locale::getISOLanguages();
std::vector<std::vector<std::string>> zone_strings = java::text::DateFormatSymbols::getInstance()->getZoneStrings();
std::map<std::string, std::string> properties = java::lang::System::getProperties();
}
Can we create a class in say C# which can be used in other high-level languages like Java.?
To be more specific say, I have defined a function in c#. Now can I use the same function in other languages like Java without re-writing it and by using reference or anything else to the class in c# ?
The question here is not strictly limited to any particular language? Question here is that Can we create a class in one language which can be used in other language.
Can we create a class in say C# which can be used in other high-level
languages like Java.?
NOPE.
Yes you can use such a construct. A web service is language independent or you can call(a executable programme) with a cmd command.
OP:
Can we create a class in say C# which can be used in other high-level languages like Java.?
I have defined a function in c#. Now can I use the same function in other languages like Java without re-writing it
Yes it can be done.
You can generate Java proxy classes for invoking c# by using the tool jni4net.
bridge between Java and .NET (intraprocess, fast, object oriented, open-source)
This is what they have to say on the tool:
Using reflection we grab public method signatures for core classes of .NET and Java and generated proxy classes for the other side.
We have .NET version of JNI API.
We use JNI to forward the call from .NET proxies to methods on real Java objects. (explanation)
We use JNI to register .NET implementation of native methods of Java proxies to forward call to methods on real .NET objects More...
Source and binaries are available here
But wait there's more!
Though not a requirement, you can use jni4net to call Java from .NET.
See also
How calling from Java to .NET works in jni4net
Generally spoken: No
As some answers stated: For many languages there is a way of invoking methods/functionality of compiled compiler-output, but IMO the only szenarios I can think of it beeing useful is when it comes to legacy-software or not language-independent APIs (eg. not using rest). An Example could be calling a Method of a legacy-C#-class from a Java program for the sake of downward comnpatibility or because it was meant to work with .NET only. But you must be aware that there is no general approach of doing that which would work for any language-combination and IMO this is not using a class/method, its just invoking it.
When it comes to green-field projects, I would avoid using (to many) different languages (polyglot-programming). Maintainability suffers heaviliy because Developers need to know all used languages, use different IDEs etc. Also, debugging becomes a pain.
Using the same language for different parts of a system has the huge advantage of beeing able to use classes of some kind of shared libraries which are developed/tested independently.
However: if you are forced to use different languages for some reason, I would suggest to try and recreate the required shared functionality twice for each language (it sucks I know) and pass objects around by (de-)serializing them. This way, your projects remain testable and debuggable.
I know three is some questions about this, but I've not found the exact response.
We have a .Net dll (C#) with no dependencies or p/Invoke. So it's a full .net platform library.
One of our clientes wants to use it in a Java Application.
What's the best choice?
I've been looking at jni4net wich could be a perfect solution, but it seems don't support generics in .Net (our dll uses lot of generics dictionaries and collections)
It's JNA the best choice?
Thanks in advance
I had a similar problem several years ago. I had a dll written in Delphi. (Delphi was a Pascal-based Windows app development tool sold by Borland.) I needed to call the dll from Java, but some of the dll functionss had parameters and return types that that were incompatible with Java. (As an interesting, if irrelevant, aside, Anders Hejlsberg, who invented C# for Microsoft, also invented Delphi for Borland.) Here is how I solved the problem.
1) I did use jni to allow my Java code to call a dll.
2) I wrote a thin wrapper dll in Delphi that was the actual dll called by my Java jni code. For those functions that were completely compatible with Java, the wrapper dll simply acted as a pass though, directly calling the actual dll functions and returning the return value. For those functions that were not compatible, the wrapper dll defined corresponding methods that were compatible with Java and did the appropriate translation from Java to Delphi before calling the actual dll.
3) I also wrote a thin wrapper object above my jni calls. Again, for the most part, the java wrapper directly made jni calls for those functions that were completely compatible between Java and Delphi. However, in my case, a few functions required that I pass in Delphi objects. So, what I did was define corresponding Java objects. The main purpose of my Java wrapper object was to take these Java objects, translate them into parameters that were compatible with my Delphi wrapper dll, and then make the apprropriate jni call. Also, for those dll functions which passed back an object, my java wrapper took the java-compatible return value from the jni call, and created and asssembled the appropriate object.
This may sound like a lot of work, but it really was not (and my dll had over 100 methods, and a dozen or so Delphi object types). When I was done, writing the Java application code that actually used the dll was very straight forward.
Regarding the generics, that could be a problem. But, if in real life, the number of object types you support is relatively small (and it often is), you can just write separate calls for each object type in your wrapper. (That is what those of us who remember Java 2 used to do before they invented generics and it worked just fine, even if it was a bit less elegant.) Your application Java code could stll use generics; the wrapper would make the appropriate call based on the actual type that was passed in.
Hopefully this will give you some ideas on how you might proceed.
To use .NET DLL in JAVA I would say that the best choice is to go with native bridge like Javonet. With such bridge all you have to do is just copy .NET dll to your JAVA project folder and load it with one method call and use the .NET objects like they were JAVA objects. You skip the whole native part and get a lot of built-in tools for data types conversion, subscribing events, garbage collector, exceptions and many others.
Sample code to use "Your.dll" could look like this:
Javonet.addReference("Your.dll");
NObject yourDotNetObject = Javonet.New("MyDotNetClass");
yourDotNetObject.invoke("FooMethod", arg1, arg2);
//out of the box you get also support for all types, arrays, generics etc
yourDotNetObject.generic(Javonet.getType("String")).invoke("Foo", "sample");
//such code could call following .NET method passing String as T
//void Foo<T>(T arg);
So as you see with semi-reflection syntax you get access to whole .NET world including any custom DLL or .NET framework classes. Manual solution is good but rather for learning then using in real project as it could take more time to solve all issue then your whole project needs ;)
For more samples check this:
http://www.javonet.com/quick-start-guide/
I am wondering if it is possible to call Python functions from Java code using Jython, or is it only for calling Java code from Python?
Jython: Python for the Java Platform - http://www.jython.org/index.html
You can easily call python functions from Java code with Jython. That is as long as your python code itself runs under jython, i.e. doesn't use some c-extensions that aren't supported.
If that works for you, it's certainly the simplest solution you can get. Otherwise you can use org.python.util.PythonInterpreter from the new Java6 interpreter support.
A simple example from the top of my head - but should work I hope: (no error checking done for brevity)
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("import sys\nsys.path.append('pathToModules if they are not there by default')\nimport yourModule");
// execute a function that takes a string and returns a string
PyObject someFunc = interpreter.get("funcName");
PyObject result = someFunc.__call__(new PyString("Test!"));
String realResult = (String) result.__tojava__(String.class);
As of 2021, Jython does not support Python 3.x
I think there are some important things to consider first with how strong you wish to have the linking between java and python.
Firstly Do you only want to call functions or do you actually want python code to change the data in your java objects? This is very important. If you only want to call some python code with or without arguments, then that is not very difficult. If your arguments are primitives it makes it even more easy. However if you want to have java class implement member functions in python, which change the data of the java object, then this is not so easy or straight forward.
Secondly are we talking cpython or will jython do? I would say cpython is where its at! I would advocate this is why python is so kool! Having such high abstractions however access to c,c++ when needed. Imagine if you could have that in java. This question is not even worth asking if jython is ok because then it is easy anyway.
So I have played with the following methods, and listed them from easy to difficult:
Java to Jython
Advantages: Trivially easy. Have actual references to java objects
Disadvantages: No CPython, Extremely Slow!
Jython from java is so easy, and if this is really enough then great. However it is very slow and no cpython! Is life worth living without cpython I don't think so! You can easily have python code implementing your member functions for you java objects.
Java to Jython to CPython via Pyro
Pyro is the remote object module for python. You have some object on a cpython interpreter, and you can send it objects which are transferred via serialization and it can also return objects via this method. Note that if you send a serialized python object from jython and then call some functions which change the data in its members, then you will not see those changes in java. You just need to remember to send back the data which you want from pyro. This I believe is the easiest way to get to cpython! You do not need any jni or jna or swig or .... You don't need to know any c, or c++. kool huh?
Advantages: Access to cpython, not as difficult as following methods
Disadvantages: Cannot change the member data of java objects directly from python. Is somewhat indirect, (jython is middle man).
Java to C/C++ via JNI/JNA/SWIG to Python via Embedded interpreter (maybe using BOOST Libraries?)
OMG this method is not for the faint of heart. And I can tell you it has taken me very long to achieve this in with a decent method. Main reason you would want to do this is so that you can run cpython code which as full rein over you java object. There are major major things to consider before deciding to try and bread java (which is like a chimp) with python (which is like a horse). Firstly if you crash the interpreter that's lights out for you program! And don't get me started on concurrency issues! In addition, there is allot allot of boiler, I believe I have found the best configuration to minimize this boiler but still it is allot! So how to go about this:
Consider that C++ is your middle man, your objects are actually c++ objects! Good that you know that now. Just write your object as if your program as in cpp not java, with the data you want to access from both worlds. Then you can use the wrapper generator called swig (http://www.swig.org/Doc1.3/Java.html) to make this accessible to java and compile a dll which you call System.load(dll name here) in java. Get this working first, then move on to the hard part!
To get to python you need to embed an interpreter. Firstly I suggest doing some hello interpreter programs or this tutorial Embedding python in C/C. Once you have that working, its time to make the horse and the monkey dance! You can send you c++ object to python via [boost][3] . I know I have not given you the fish, merely told you where to find the fish. Some pointers to note for this when compiling.
When you compile boost you will need to compile a shared library. And you need to include and link to the stuff you need from jdk, ie jawt.lib, jvm.lib, (you will also need the client jvm.dll in your path when launching the application) As well as the python27.lib or whatever and the boost_python-vc100-mt-1_55.lib.
Then include Python/include, jdk/include, boost and only use shared libraries (dlls) otherwise boost has a teary. And yeah full on I know. There are so many ways in which this can go sour. So make sure you get each thing done block by block. Then put them together.
It's not smart to have python code inside java. Wrap your python code with flask or another web framework to make it a microservice. This makes your java program able to call this microservice (e.g. via REST).
This approach is simple and it will save you tons of issues. And the codes are loosely coupled so they are scalable.
Updated on Mar 24th 2020:
According to #stx's comment, the above approach is not suitable for massive data transfer between client and server.
Here is another approach I recommended:
Connecting Python and Java with Rust(C/C++ also ok).
https://medium.com/#shmulikamar/https-medium-com-shmulikamar-connecting-python-and-java-with-rust-11c256a1dfb0
Several of the answers mention that you can use JNI or JNA to access cpython but I would not recommend starting from scratch because there are already open source libraries for accessing cpython from java. For example:
JEP
JPY
GraalVM is a good choice. I've done Java+Javascript combination with GraalVM for microservice design (Java with Javascript reflection). They recently added support for python, I'd give it a try especially with how big its community has grown over the years.
UPDATE June 2021
https://www.graalvm.org/reference-manual/python/ says
GraalVM provides a Python 3.8 compliant runtime. A primary goal of the GraalVM Python runtime is to support SciPy and its constituent libraries, as well as to work with other data science and machine learning libraries from the rich Python ecosystem. At this point, the Python runtime is made available for experimentation and curious end-users.
Here a library that lets you write your python scripts once and decide which integration method (Jython, CPython/PyPy via Jep and Py4j) to use at runtime:
https://github.com/subes/invesdwin-context-python
Since each method has its own benefits/drawbacks as explained in the link.
(3 modules: jep, Py4J, jython )
It depends on what do you mean by python functions? if they were written in cpython you can not directly call them you will have to use JNI, but if they were written in Jython you can easily call them from java, as jython ultimately generates java byte code.
Now when I say written in cpython or jython it doesn't make much sense because python is python and most code will run on both implementations unless you are using specific libraries which relies on cpython or java.
see here how to use Python interpreter in Java.
Depending on your requirements, options like XML-RPC could be useful, which can be used to remotely call functions virtually in any language supporting the protocol.
Jython has some limitations:
There are a number of differences. First, Jython programs cannot use CPython
extension modules written in C. These modules usually have files with the
extension .so, .pyd or .dll. If you want to use such a module, you should look
for an equivalent written in pure Python or Java. Although it is technically
feasible to support such extensions - IronPython does so - there are no plans
to do so in Jython.
Distributing my Python scripts as JAR files with Jython?
you can simply call python scripts (or bash or Perl scripts) from Java using Runtime or ProcessBuilder and pass output back to Java:
Running a bash shell script in java
Running Command Line in Java
java runtime.getruntime() getting output from executing a command line program
You can call any language from java using Java Native Interface
This gives a pretty good overview over the current options. Some of which are named in other answers. Jython is not usable until they decide to not implement Python 3. Many of the other projects are coming from the python side and want to access java. But there are a few options still, to name something which has not been named yet: gRPC
I have similar requirement, I think best solution is thrift for me(also a rpc solution), just run test passed successfully right now, and can use thrift-generator to gen thrift file from java interface, then gen python files and java client files from the thrift file
Just out of interest , is it possible to call a C module from a java module ? If so , how to do that ?
yes you can use Java Native Interface to do this:
Yes, you can do it. Whether you should do it is another matter.
On the pro side:
Calling C libraries from Java will avoid the need to recode the libraries in Java (but see below).
For some computational intensive algorithms, a well-written C implementation may be faster than an equivalently well-written Java version.
Some operating system specific operations cannot be implemented in pure Java.
On the con side:
There is a greater overhead in making a JNI call versus a simple Java method call.
If your C library is not thread-safe, you have to be really careful calling it from Java. And as a rule, C libraries are not implemented with thread safety in mind.
If your C library has memory management issues, it may destabilize the Java platform resulting in JVM crashes.
Calling native libraries immediately means that your application is harder to port, and requires a more complicated build process.
Yes, you call C/C++ from Java using the Java Native Interface (JNI) from this purpose.
Java Native Interface: Programmer's Guide and Specification
You can also use SWIG for this purpose:
SWIG Tutorial
Look into JNI (Java Native Interface).
Yes. As others have already mentioned, JNI or Java Native Interface is Sun's preferred way of doing this. If you feel you'll need to call the C code from other languages as well as Java, I'd look into SWIG, which will transparently generate the JNI code for you, but also allow you to do similar things with, for example, Python.
There are a number of C to (Java) bytecode compilers, which may be able to turn your C code into a .jar of portable Java classes you can call directly from Java.
Detriments versus JNI:
There is a noticeable performance penalty, typically at least 100%.
Benefits versus JNI:
Just like running pure Java code, it is safe, does not require special privileges to load, and does not require recompiling for every target platform.
(When I say "JNI" I really mean all Java interfaces to native code. For example, the same applies to CNI.)