jni starter question - java

I started looking into JNI and from what I understand is that if a problem occurs with the loaded dll, the jvm is possible to terminate on the spot.
I.e. the process can not be protected e.g. like when catching an exception.
So if my understanding is correct, my question is if there is a standard approach/pattern for this situation when using jni.
Or to state it differently, are processes using jni designed in way to avoid these issues?
Or such problems are not expected to occur?
Thank you.

Yes, the JVM will just terminate which is one of the reasons why JNI code is really hard to debug. If you are using C++ code you can use exceptions and then map them to a Java exception which at least gives you some level of security but doesn't help with things like bad memory access etc.
From an architecture point of view I suggest to decouple you code from JNI as much as possible. Create a class / procedure structure that is entirely testable from C++/ C and let the JNI code do only all the conversion stuff. If the JVM then crashes you at least know where you have to look.

The principles are no different from any multi-threaded C application:
Always check all your input thoroughly.
Always free up temporary memory you allocated.
Make sure your functions are re-entrant.
Don't rely on undefined behaviour.
The Java virtual machine offers you no extra protection for your native code, if it fails or is leaking, your VM will fail or leak.

You can have exactly the same spectrum of error handling in a JNI library as in anything else.
You can use try/catch. If you are on Windows, you can use SEH. If you are on Linux, you can call sigaction.
Still, if you mess up and there's a SIGSEGV, your JVM is probably toast whether you try to catch that signal or not.

Related

How to debug a crash with Java Result: error_code

I have a Java application that uses a C++ DLL via JNA. The C++ DLL is proprietary, therefore, I cannot share the code unless I can make a simplified reproducible example. It is not straight forward to make a reproducible example until I further debug.
The application crashes sporadically with the error message Java Result: -1073740940. I am running the Java application from Netbeans, although it crashes without Netbeans. Since there is no hs_err_.log, I guess crash is in the C++ layer. How can I begin debug this crash?
The "Java Result" output from Netbeans simply tells you the exit code of the java program. You could generate the same with a System.exit(-1073740940);. A successful program exits with a code of 0. Anything else is a failure that requires documentation to interpret.
You have not given us any indication what DLL you are using, so the only information we have to work with is this exit code. Converting that int to hex digits results in 0xc0000374 which you can enter into your favorite search engine and find out is a Heap Corruption Exception. Some examples are provided but in general this means you are accessing non-allocated native memory.
Without having any idea what code you're using, I would guess you're doing something wrong with native memory, invoking native functions, or incorrectly manipulating pointers or handles somewhere in your application.
You should start by looking closely at arguments to native functions. Type mapping could be a problem if the number of bytes is mismatched. Investigate any Pointer-based arguments to native functions, including ByReference arguments. Trace back in the code and find when/how these Pointers were associated with native-allocated memory. If it was never allocated, that's one possibility for the problem. If it was allocated, see if you can find a point where that memory was freed, possibly by a different native function.
The root cause of the crash was heap corruption in the C++ layer. If a random crash occurs due to heap corruption, sometimes, it is complicated to pinpoint the cause of crash because the crash can happen later, when the program tries to manipulate the corrupted memory. Hence, it is also complicated to provide an SSCCE, especially when we work on the proprietary legacy code.
How I debugged this crash:
Reproduction: Try to find a consistent use case for the crash. If the crash is random then try to figure out a set of user actions that always leads to the crash.
Assumption: Guess which feature/component contains the crash.
Validation: Make sure that crash is not happening when you disable this feature/component.
Verification: Skimm through and slice the code. Review the small piece of code.
Documentation: Write everything.
Daniel's answer was very helpful in fixing this crash!

Can Java run directly on hardware?

Can Java run directly on hardware (assuming there's enough memory to include the necessary JRE/JVM? If it can, how does System.out.println work? I'd think there's nowhere for that output to go if it's all just on a cpu.
Directly on hardware? I am assuming you mean to ask if Java can run on a micro-controller? The answer is yes. The JVM is a virtual machine which is essentially its own operating system. The JVM was designed to do exactly what your wondering about. The JVM's two primary functions are to allow Java programs to run on any device or operating system, "Write once, run anywhere" and to optimize memory solutions.
To answer your second question. In order to visually see the output of a System.out.println() call one would simply need to provide the micro-controller with a screen. However, in theory the code would still execute without you seeing it being displayed. So one could write a Java applet that prints "hello world" and then load it onto a micro-controller and run it but that's just silly.
EDIT: I assumed you were not asking: "Can you program a micro-controller with Java" Silly of me, the answer is yes you certainly can; however, you wouldn't want too because the JVM is rather large and it would take up a lot of space. That being said, if you are interested take a look at: the STM32 Java-ready micro-controllers or the Renesas RX. Also, you could run a gutted JVM using uJ or NonvoVM.
The short answer is no, due to the JVM and write once run anywhere feature in java, the code is not ran directly on the hardware but within the JVM... THE JVM essentially acts as a middle man between different hardware/OS...if you look to accomplish this then take a look at C++

Accessing memory with Java

I have a program loaded in the memory. Now I want to access the memory directly and change the OPCODE and DATA in the memory for that program. For this I need to write a Java program.
Can you please tell me if this is feasible? If yes, please let me know how to write such a program.
Thanks in advance!
Java is not designed for this.
The main aim of Java is to let the JVM manage the memory for you. Thus, your programs are sandboxed.
However, there seems to be a backdoor in HotSpot JVM:
Java was initially designed as a safe, managed environment.
Nevertheless, Java HotSpot VM contains a “backdoor” that provides a
number of low-level operations to manipulate memory and threads
directly. This backdoor – sun.misc.Unsafe – is widely used by JDK
itself in the packages like java.nio or java.util.concurrent. It is
hard to imagine a Java developer who uses this backdoor in any regular
development because this API is extremely dangerous, non portable, and
volatile. Nevertheless, Unsafe provides an easy way to look into
HotSpot JVM internals and do some tricks. Sometimes it is simply
funny, sometimes it can be used to study VM internals without C++ code
debugging, sometimes it can be leveraged for profiling and development
tools.
Source: http://highlyscalable.wordpress.com/2012/02/02/direct-memory-access-in-java/
The Unsafe class is, however, undocumented. You may want to have a look at this SO answer for more details: https://stackoverflow.com/questions/5574241/interesting-uses-of-sun-misc-unsafe
Unoffical Docs: http://mishadoff.github.io/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/
Absolute Beginners' Guide http://java-performance.info/string-packing-converting-characters-to-bytes/
http://javapapers.com/core-java/address-of-a-java-object/
P.S. I am aware that I must post some of the content of the link here but since the articles are really very detailed, I have skipped that part
You cannot directly reference memory in java, as their is no concept of pointers in java like c/c++
You must go through this referencing memory address
Hope it helps.

How to identify the cause of a JNI global reference memory leak?

I'm using Tomcat and after stopping my web application there's still a reference to the classloader instance of my web application.
With the consequence that a notable amount of memory (mostly related to static data) will not be freed. Sooner or later this results in an OutOfMemoryError.
I took a heap dump and I realized that its held by a JNI global reference which prevents that the classloader will be garbage collected.
My application does not use JNI. I am also not using the Apache Tomcat Native Library. I am using a Sun/Oracle JDK.
I'd like to track down the cause/origin of this global reference.
(My guess is that the JVM internally references the classloader - but why/where?).
Question:
Which approaches/toolsets exists to achieve this?
UPDATE
It seems that bestsss is right and the JNI global references has been introduced by the jvm debug mode. This helped me out but it does not answer the question so I am still curious to get an answer to the question which might be helpful in the future.
Besides the obvious case: Threads, there is one more:
Are you using your application in debug mode?
The JVM does not hold references to any classloader besides the system one, but it doesn't concern you. The rest of JNI references are either Threads or just debug held objects (provided you don't use JNI and lock the objects down yourself).
JNI references are just roots, edit your answer and post what exactly objects are held by those references.
The first thing i'd do is run with -Xcheck:jni on and see if it comes up with anything. I wouldn't expect it to; it doesn't sound there's anything weird happening with JNI, just incorrect use being made of it. However, it's good to make sure of that.
If you're on a Sun JVM, i think you can do -XX:TraceJNICalls to get an overwhelming listing of JNI calls as they happen. That should let you get an idea of what calls are being made, and from there work towards what is making them, and why this is causing a problem.
JRockit mission control: http://download.oracle.com/docs/cd/E13150_01/jrockit_jvm/jrockit/tools/index.html
A nice GUI tool that should help you find it pretty quick.
You could try jstack.
Maybe one of the listed stacktraces will show you the origin of the global reference.

Jython Optimizations

Are their any ways to optimize Jython without resorting to profiling or significantly changing the code?
Specifically are there any flags that can be passed to the compiler, or code hints in tight loops.
No flags, no code hints. You can optimize by tweaking your code much as you would for any other Python implementation (hoisting, etc), but profiling helps by telling you where it's worth your while to expend such effort -- so, sure, you can optimize "without resorting to profiling" (and the code changes to do so may well be deemed to be not significant), but you're unlikely to guess right about where your time and energy are best spent, while profiling helps you determine exactly that.
Jython compiler does not offer lots of optimization choices. However, since the Java virtual machine (java) and perhaps compiler (javac) are getting invoked in the back end or at runtime, you should take a look at them.
Java has different runtime switches to use depending on whether you are going to launch it as a server process, client process, etc. You can also tell how much memory to allocate too.
I know this is an old question, but I'm just putting this for completeness.
You can use:-J-server flag to launch Jython in the Java server mode, which can help speed up the hot loops. (JVM will look to aggressively optimize, but might slow up the start up time)

Categories

Resources