Calling Java from C program - java

How to call Java methods from C program? I.e. is it possible to embed java (not necessary Sun/Oracle JVM) in other language?

A full Oracle JVM is a very large chunk to pull into your existing program, but it is perfectly doable but I would recommend against it if any of the following apply:
You need to pull a lot of data in and out of the JVM on a frequent basis. This is expensive.
You are not in full control of the operating system and JVM to use.
You are not an experienced C programmer. Debugging these things can be hard.
You might find jamvm - http://jamvm.sourceforge.net/ - an interesting alternative. It is a very small interpreter written in C, which may be a lot easier to handle. I have not tried embedding it.

Related

Why operating systems are not written in java?

All the operating systems till date have been written in C/C++ while there is none in Java. There are tonnes of Java applications but not an OS. Why?
Because we have operating systems already, mainly. Java isn't designed to run on bare metal, but that's not as big of a hurdle as it might seem at first. As C compilers provide intrinsic functions that compile to specific instructions, a Java compiler (or JIT, the distinction isn't meaningful in this context) could do the same thing. Handling the interaction of GC and the memory manager would be somewhat tricky also. But it could be done. The result is a kernel that's 95% Java and ready to run jars. What's next?
Now it's time to write an operating system. Device drivers, a filesystem, a network stack, all the other components that make it possible to do things with a computer. The Java standard library normally leans heavily on system calls to do the heavy lifting, both because it has to and because running a computer is a pain in the ass. Writing a file, for example, involves the following layers (at least, I'm not an OS guy so I've surely missed stuff):
The filesystem, which has to find space for the file, update its directory structure, handle journaling, and finally decide what disk blocks need to be written and in what order.
The block layer, which has to schedule concurrent writes and reads to maximize throughput while maximizing fairness.
The device driver, which has to keep the device happy and poke it in the right places to make things happen. And of course every device is broken in its own special way, requiring its own driver.
And all this has to work fine and remain performant with a dozen threads accessing the disk, because a disk is essentially an enormous pile of shared mutable state.
At the end, you've got Linux, except it doesn't work as well because it doesn't have near as much effort invested into functionality and performance, and it only runs Java. Possibly you gain performance from having a single address space and no kernel/userspace distinction, but the gain isn't worth the effort involved.
There is one place where a language-specific OS makes sense: VMs. Let the underlying OS handle the hard parts of running a computer, and the tenant OS handles turning a VM into an execution environment. BareMetal and MirageOS follow this model. Why would you bother doing this instead of using Docker? That's a good question.
Indeed there is a JavaOS http://en.wikipedia.org/wiki/JavaOS
And here is discuss about why there is not many OS written in java Is it possible to make an operating system using java?
In short, Java need to run on JVM. JVM need to run on an OS. writing an OS using Java is not a good choice.
OS needs to deal with hardware which is not doable using java (except using JNI). And that is because JVM only provided limited commands which can be used in Java. These command including add, call a method and so on. But deal with hardware need command to operate reg, memory, CPU, hardware drivers directly. These are not supported directly in JVM so JNI is needed. That is back to the start - it is still needed to write an OS using C/assembly.
Hope this helps.
One of the main benefits of using Java is that abstracts away a lot of low level details that you usually don't really need to care about. It's those details which are required when you build an OS. So while you could work around this to write an OS in Java, it would have a lot of limitations, and you'd spend a lot of time fighting with the language and its initial design principles.
For operating systems you need to work really low-level. And that is a pain in Java. You do need e.g. unsigned data types, and Java only has signed data types. You need struct objects that have exactly the memory alignment the driver expects (and no object header like Java adds to every object).
Even key components of Java itself are no longer written in Java.
And this is -by no means- a temporary thing. More and more does get rewritten in native code to get better performance. The HotSpot VM adds "intrinsics" for performance critical native code, and there is work underway to reduce the overall cost of native calls.
For example JavaFX: The reason why it is much faster than AWT/Swing ever were is because it contains/uses a huge amount of native code. It relies on native code for rendering, and e.g. if you add the "webview" browser component it is actually using the webkit C library to provide the browser.
There is a number of things Java does really well. It is a nicely structured language with a fantastic toolchain. Python is much more compact to write, but its toolchain is a mess, e.g. refactoring tools are disappointing. And where Java shines is at optimizing polymorphism at run-time. Where C++ compilers would need to do expensive virtual calls - because at compile time it is not known which implementation will be used - there Hotspot can aggressively inline code to get better performance. But for operating systems, you do not need this much. You can afford to manually optimize call sites and inlining.
This answer does not mean to be exhaustive in any way, but I'd like to share my thoughts on the (very vast) topic.
Although it is theoretically possible to write some OS in pure java, there are practical matters that make this task really difficult. The main problem is that there is no (currently up to date and reliable) java compiler able to compile java to byte code. So there is no existing tool to make writing a whole OS from the ground up feasible in java, at least as far as my knowledge goes.
Java was designed to run in some implementation of the java virtual machine. There exist implementations for Windows, Mac, Linux, Android, etc. The design of the language is strongly based on the assumption that the JVM exists and will do some magic for you at runtime (think garbage collection, JIT compiler, reflection, etc.). This is most likely part of the reason why such a compiler does not exist: where would all these functionality go? Compiled down to byte code? It's possible but at this point I believe it would be difficult to do. Even Android, whose SDK is purely java based, runs Dalvik (a version of the JVM that supports a subset of the language) on a Linux Kernel.

OpenCV (JavaCV) vs OpenCV (C/C++ interfaces)

I am just wondering whether there would be a significant speed performance advantage relatively on a given set of machines when using JavaCV as opposed to the C/C++ implementation of OpenCV.
Please correct me if I am wrong, but my understanding is that the c/c++ implementation of opencv is closer to the machine where as the Java implementation of OpenCV, JavaC, would have a slight speed performance disadvantage (in milliseconds) as there would be a virtual machine converting your source code to bytecode which then gets converted to machine code. Whereas, with c/c++, it gets converted straight to machine code and thus doesn't carry that intermediary step of the virtual machine overhead.
Please don't kill me here if I made mistakes; I am just learning and would welcome constructive criticism.
Thank you
I'd like to add a couple of things to #ejbs's answer.
First of all, you concerned 2 separate issues:
Java vs. C++ performance
OpenCV vs JavaCV
Java vs. C++ performance is a long, long story. On one hand, C++ programs are compiled to a highly optimized native code. They start quickly and run fast all the time without pausing for garbage collection or other VM duties (as Java do). On other hand, once compiled, program in C++ can't change, no matter on what machine they are run, while Java bytecode is compiled "just-in-time" and is always optimized for processor architecture they run on. In modern world, with so many different devices (and processor architectures) this may be really significant. Moreover, some JVMs (e.g. Oracle Hotspot) can optimize even the code that is already compiled to native code! VM collect data about program execution and from time to time tries to rewrite code in such a way that it is optimized for this specific execution. So in such complicated circumstances the only real way to compare performance of implementations in different programming languages is to just run them and see the result.
OpenCV vs. JavaCV is another story. First you need to understand stack of technologies behind these libraries.
OpenCV was originally created in 1999 in Intel research labs and was written in C. Since that time, it changed the maintainer several times, became open source and reached 3rd version (upcoming release). At the moment, core of the library is written in C++ with popular interface in Python and a number of wrappers in other programming languages.
JavaCV is one of such wrappers. So in most cases when you run program with JavaCV you actually use OpenCV too, just call it via another interface. But JavaCV provides more than just one-to-one wrapper around OpenCV. In fact, it bundles the whole number of image processing libraries, including FFmpeg, OpenKinect and others. (Note, that in C++ you can bind these libraries too).
So, in general it doesn't matter what you are using - OpenCV or JavaCV, you will get just about same performance. It more depends on your main task - is it Java or C++ which is better suited for your needs.
There's one more important point about performance. Using OpenCV (directly or via wrapper) you will sometimes find that OpenCV functions overcome other implementations by several orders. This is because of heavy use of low-level optimizations in its core. For example, OpenCV's filter2D function is SIMD-accelerated and thus can process several sets of data in parallel. And when it comes to computer vision, such optimizations of common functions may easily lead to significant speedup.
JavaCV interfaces to OpenCV, so when you call something OpenCV related there would be some overhead but in general most of the heavy work will still be on the C++ side and therefore there won't be a very large performance penalty.
You would have to do performance benchmarks to find out more.
PS. I'm pretty new here but I'm rather sure that this is not a suitable question for StackOverflow.
i would like to add a few more insights on java as an interface to c++ libraries...
A)developing:
1)while java may be easier to manage large scale projects and compiles extremely fast, it is very very hard, and next to impossible to debug native code from java...
when code crush on native side...or memory leaks( something that happens a lot... ) you feel kind of helpless...
2)unless you build the bindings yourself( not an easy task even with using swig or whatever... ) you are dependent on the good will/health/time of the bindings builder....
so in this case i would prefer the official "desktop java " bindings over javacv...
B)performance.
1) while bindings may be optimized( memory transfer using neobuffer ) as in the javacv case there is still a very very small jni overhead for each native function call -
this is meaningless in our case since most opencv functions consume X100000++ cpu cycles compared to this jni overhead...
2) The BIG-PROBLEM ---- stop the world GARBAGE COLLECTIOR( GC )
java uses a garbage collector that halts all cpu's threads making it UNSUITABLE for REAL-TIME application's , there are work-around's iv'e heard of like redesigning your app not to produce garbage, use a spaciel gc, or use realtime java( cost money... ) they all seem to be extra-work( and all you wanted is a nice easy path to opencv.... )
conclusion - if you want to create a professional real time app - then go with c++
unless you have a huge modular project to manage - just stick with c++ and precompiled headers( make things compile faster... )
while java is a pleasure to work with , when it comes to native binding's HELL breaks loose...i know iv'e been there....

Mapping a Java program to an Operating System process

I am wondering how this happens: how is a Java program mapped to an OS process (like the one shown for Linux below):
In C, it's a straightforward association in how a program is written and how the whole call stack proceeds in the OS. I was wondering how is the mapping achieved in Java? Does a method meth(), called on an object: obj, just translate to locating the address of obj.meth() & from then on stack is used the way it is in C?
Thanks in advance!
Edit: I'd also be curious to know the model that other OOP languages use in general (C++, Python etc).
That's a pretty complex problem. Here is a pretty good article about this topic. In short, Java got two execution modes which hugely affects memory layout.
Some code is executed by intepreter
Some code are compiled to native code for better performance.
See this wiki page: http://en.wikipedia.org/wiki/Just-in-time_compilation.
And JVM got more type of memory region, like perm-gen, memory for JIT, etc.
This is well-discussed in other threads:
java and memory layout
jdk1.6 memory layout
Most Java JVMs are plain C programs. So the picture will be the same write up to the first class file being interpreted/executed.
After that it depends on the JVM implementation. Typically they would use the stack storage to keep track of control type information such as which classes are loaded, which threads are running etc. For the actual "program" storage the interpreter and garbage collector will use plain "malloc"/"mfree" to allocatate and free memory plus some fairly complex control structures to enable the garbage collector to function.

Can kernel be written in other than assembly language?

I never did kernel programming. I am a good programmer in the Java language and frequently use it. Now i feel to do something interesting with kernels. A kernel resides between hardware and OS. It communicates with hardware using system calls. Every programming language require a compiler to compile the code written in high level language and then it generate low level code, which is generally assembly language code. Here comes my doubt, if we have kernel written in C, then should we have a C compiler installed on the machine? At the end, when kernel interacts with hardware it uses assembly language, can i create kernel in Java language? If yes, then what are the requirements for the same? Thank you.
A kernel resides between hardware and OS
Usually, the kernel is considered to be part of the operating system.
It communicates with hardware using system calls
System calls are the interface that is provided by the OS to user applications. The operating system communicates with the hardware through other mechanisms (for example interrupts or memory-mapped registers).
Every programming language require a compiler to compile the code written in high level language and then it generate low level code, which is generally assembly language code.
The compiler output is typically either native machine code or a language-specific bytecode (like in the case of Java). Sometimes, compilers also target another programming language such as C or Javascript (transpilation).
Here comes my doubt, if we have kernel written in C, then should we have a C compiler installed on the machine?
That's not necessary. The C compiler produces output that can execute directly on the hardware without interpretation.
At the end, when kernel interacts with hardware it uses assembly language
The CPU doesn't understand assembly. It understands machine code.
can i create kernel in Java language?
It has been done.
If yes, then what are the requirements for the same?
If you want to write a kernel in Java, then you either have to
compile your entire Java codebase to machine code
get yourself a CPU that can execute Java bytecode
find or build a Java VM and runtime that can run on bare metal and run your Java code in it (if you do it cleverly, you can write much of the runtime and maybe also parts of the VM in Java itself).
Now to the unspoken, almost rhethorical question:
Is this a good idea?
Probably not. Why? First of all, because it would take ages to set up. Second, because you couldn't just code the way you develop an average business application. You'd have to think about performance of very time-critical code (e.g. context switching, which often requires hand-tuned assembly to be fast enough), manual memory management (as in: your MRU might expect you to give it the physical address where the page table lies), system-/hardware-specific mechanisms (how to access a XYZ controller on this particular architecture?), ...
So you would lose many of the advantages that Java has over a low-level language like C in the first place.
Yes a kernel can be written in Java, see the JNode. It would have the advantage of having no problems with: dangling pointers, mix up of pointers and array addresses, unitialised data, and many more features of C.

How does C differ from Java's compilation model?

What the differences between classical compilation model (C, C++, etc.) and the Java compilation model?
A proper answer to your question could take several hundred pages to answer, but I'll try to sum it up in a few paragraphs.
Basically, the "classic compilation model" you refer to takes as input human-written source code and emits machine code, which can be loaded and run without further translation of the machine code. One ramification of this is that the resulting machine code can only be run on compatible hardware and can only be run within a compatible operating system.
The Java compilation model takes human-written source code as input and emits not machine code, but so-called "byte code". Byte code cannot be directly executed on a machine. Instead, it needs to be translated once again by another compiler to machine code, or interpreted on-the-fly by a device that executes instructions on the machine that correspond to the instructions in the byte code. The latter device is often referred to as a Virtual Machine. One ramification of this model is that the byte code can be "run" on any platform that has either a byte code compiler or virtual machine written for it. This gives Java the appearance and effect of complete portability, where there is no such portability implied by the machine code emitted by a C++ compiler stack.
Two aspects play into the C (and C++) compilation model. One is its longer history than Java, meaning that it caters to very low-powered compilers and machines. The second is the compilation target, which is usually low-level machine code.
To target low-memory compiler environments, C code must be readable from top to bottom, with no backtracking. This means that you have to follow a strict discipline for the order of declarations. (C++ relaxes this a little bit for class definitions.) Further more, each source file must be compilable as an independent translation unit which need not know anything about other source files.
Second, because C targets low-level machine code, this means that each translation unit contains essentially no metadata, in stark contrast to Java class files. This necessitates a stronger coding discipline in which each translation unit must be provided with the necessary declarations. The compiler cannot just scan all the other files in order to get the required information; it is up to the user to supply it. (C++ enforces this more rigidly, in C you can get away with nasty errors by forgetting a declaration.)
Bear in mind that a C program has to be fully compiled and linked at compile time, so a lot of information has to be available already at that point. Java programs can load classes at runtime, and Java execution generally performs more "fitting" operations (casting, essentially, as opposed to static linking in C) at runtime. The more sophisticated runtime environment of Java allows for a more flexible and modular compilation model.
I am going to be brave and compare performance. ;)
The Java compiler javac does little optimisation preferring to syntax check code. It does all the reasonable checks required to ensure it will run on a JVM, and some constant evaluation and that's about it.
Most of the smart compilation is done by the JIT which can perform dynamic complication based on how the program is used. This allows it to inline "virtual" methods, for example, even if the caller and callee are in different libraries.
The C/C++ compiler performs significant static analysis up front. This means a program will run at almost full speed right from the start. The CPU performs some dynamic optimisation with instruction re-ordering and branch prediction. While C/C++ lacks dynamic optimisation, it gains from by making low level access to the system much easier. (Its usually not impossible in Java, but low level operations which are trivial in C/C++ can be complex and obscure in Java) It also provides more ways to do the same thing allowing you to choose the optimal solution to your problem.
When Java is likely to be faster.
If your style of programming suits Java and you only use the sort of features Java supports, Java is likely to be marginally faster (due to dynamic compilation) i.e. you wouldn't use C/C++ to their full potential anyway.
If your code contains lots of dead code (possibly only known to be dead at run time) Java does a good job at eliminating this. (IMHO A high percentage of micro-benchmarks which suggest Java is faster than C++ are of this type)
You have a very limited time and/or resources to implement your application. (In which case an even higher level language might be better) i.e. You don't have time to optimise your code much and you need to write safe abstracted code.
When C/C++ is likely to be faster.
If you use most of the functionality C/C++ provides. Something more advanced programmers tend to do.
If startup time matters.
If you need to be creative about algorithms or data structures.
If you can exploit a low level hardware feature, like direct access to devices.
For short, "classical" compilation (which is a temp term provided by the material because they don't have a real word for it), is basically compiling against a real device (in our case a machine with a physical processor). Instead, Java compiles to code against a virtual device, which is software installed on a machine. The virtual device is what changes and targets the real machine.
In this way your hardware is abstracted. This is why Java can work on "any" machine.
Basically, there are two kinds of magic. Machine magic is only understood by certain wizards. JVM Bytecode magic is understood by a special kind of wizard that you have to hire in order to make the machine wizard able to cast spells that make your computer do things. C and C++ compilers generally emit the machine kind, whereas Java compilers emit JVM Bytecode.
C/C++ gets compiled before execution.
Java gets compiled while executing.
Of course, neither language mandates a certain way of being compiled.
There is no difference. Both convert source code that a human understands, to a machine code that some machine understands. In Java's case it targets a virtual machine, i.e. a program instead of a piece of silicon.
Of course there's nothing to prevent a piece of silicon from understanding JVM byte code (in which case you could rename it from 'byte code' to 'machine code'). And conversely, there's nothing to prevent a compiler from converting C/C++ code to JVM byte code.
Both have a runtime and both require you to tell it which parts of the runtime you intend to use.
I really think you intended to ask a different question.

Categories

Resources