How could I have a breakpoint in Java that's triggered when a native method calls (directly or indirectly) a certain Linux syscall?
This is not quite a breakpoint, but at least it gives you a stack trace, which may be all you need. Furthermore, the Systemtap language does allow you to do more stuff than just print stack traces, if you need to.
In the IcedTea JVM source code, you will find a SystemTap file with functions that can be used to get stack traces from a running IcedTea (with Hotspot) JVM. As I understand it, with these functions you can get a Java stack trace from any event that SystemTap supports - even from in-kernel events.
Note that despite having the same name, these jstack functions are unrelated to the jstack(1) command-line utility supplied with the JDK. They work via memory inspection, not via calling back to the JVM, so they are quite specific to Hotspot internals, and therefore probably won't work with non-Hotspot-based JVMs.
Note: Systemtap does not fully work on default Debian kernels, so you may need to compile your own kernel on Debian-based systems. This problem does not affect Fedora or Red Hat.
In theory, it would be possible to native-compile the application using an ahead-of-time (AOT) compiler for Java, and then use a native debugger to set a breakpoint or catchpoint on the syscall. (Bonus: You then get a complete stack trace including all the C functions called by the native method, and the ability to debug those C functions seamlessly.)
You would probably want to use a debugger which knew how to demangle names produced by the AOT compiler. For example, gdb knows how to demangle names produced by gcj, so a gcj combination with gdb should work.
The trouble with this combination is that gcj is still stuck at partial JDK 1.5 compatibility, and no-one has bothered to do the work of merging in the OpenJDK class library (it was suggested on the gcj mailing list in 2009). And as a result, gcj has never been a popular option - people do often use it unintentionally (particularly on Debian and Ubuntu), but then when they hit a problem they tend to switch to a more standard JDK instead of reporting a bug.
Native compilation with an AOT compiler is also much slower than just letting the JRE JIT-compile code when it thinks it's necessary.
Related
I'm looking for a tool for debugging and stepping through Java Bytecode, with
visualizing of the basic JVM state, including the operand stack and the local variables array, merely for educational purposes and JVM learning (for myself, and hopefully for others as well). Is there such a tool at hand?
I came across the Bytecode Visualizer Eclipse plugin by Dr. Garbage, which allows breaking on and stepping through Bytecode, but it doesn't visualize the JVM state:
http://www.drgarbage.com/bytecode-visualizer
The following related questions (quite old) mention a few tools, some of which allow stepping through Bytecode, but none with JVM state visualization:
Are there any JVM simulators / bytecode execution visualizers?
Is there a disassembler + debugger for java (ala OllyDbg / SoftICE for assembler)?
Java debugging with byte codes
Is there such a tool at hand, that is capable of debugging simple Java programs? Or even a simple JVM simulator?
Thanks!
I've adapted the PyJVM to do what you are after. It shows a simple gui for each thread of the Java program (they have to be compiled for Java7).
The only issue with this tool is that it doesn't have a GC, since garbage collection is handled by Python itself. Therefore, the Thread 1 (daemon) (the reference handler) will not ever do anything. Finalize method also won't trigger.
Source is available on https://github.com/MatevzFa/pyjvm (warning: the source code isn't very nice to look at), you can also install it with pip (pip2 actually, since PyJVM is written in Python2).
Install:
pip install pyjvmgui
Upgrade:
pip install pyjvmgui --upgrade --no-deps
I stil have to write a good README for it.
I have simple java programm that will just print Hello World.Can it be possible to print without using JVM installed in a machine ?But compiler is there.
You can compile Java Byte Code to Machine Code using something like this:
http://en.wikipedia.org/wiki/GNU_Compiler_for_Java
Or you can use any of the MANY Java to C/C++ converters out there to make a C/C++ version, and compile that. (Search Google for "Java C Converter")
Warning: I have never tried any of these, including the linked GNU Compiler, so I cannot make any attestations to their usefulness or quality.
#SplinterReality already pointed you to some compilers (googling "java bytecode to native code compiler" will show you some more options).
I will just expand on that seeing some people are a bit confused:
The JVM is a program that takes java bytecode, which you get by running javac on your java source code (or you generate it in some other fashion). Bytecode is just a set of instructions that the JVM understands, it's there to give you a consistent set of opcodes which are platform independent. It's the JVM's job to then map those opcodes to native instructions, that's why JVMs are platform dependent. That's why when you compile your java source code to java bytecode you can run it on every platform.
That's why, whether you have java source or bytecode, you can take it and just compile it directly to native code (platform dependent, actually sometimes that's exactly what the JVM, and to be more precise the JIT, does - it compiles stuff to native code when it sees the need to). Still there's more to the JVM than just bytecode interpretation - for instance you need to take care of garbage collection.
So the answer is: yes, but do you really want to do it? Unless you want to be running it on some embedded systems I don't really see any reason to.
Yees, it is possible to run a java program without a JVM, albeit with limitations. Aside from the http://en.wikipedia.org/wiki/GNU_Compiler_for_Java , there is the GraalVM native-image generator, which could be used : https://www.graalvm.org.
If that program is a one file source code (not compiled in bytecode) then you can ;)
Here or here. Here will be fine as well ;)
Just put it there and press compile and run.
But it will work only with simple stuff only, and you have to have source code.
I would not be surprised if there would be a site that would allowed to upload class from users PC
I was wondering, is it possible to get eyes on the actual machine code that the HotSpot compiler generates when it compiles a given Java bytecode class or method?
Yes, with -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly the Hotspot VM can give you that information when it actually executes (compiles) a given bytecode method.
See for example HotSpotInternals Wiki:Print Assembly for details. It does require a disassembler module (hsdis-*.dll on Windows).
A bit more comfortable is using JITWatch (but it uses the same infrastructure from HotSpot).
I was recently comparing the JVM and CLR platforms and was discussing the impact of JIT compilation. The discussion I was having led to .NET's ability to precompile code using the NGen tool, which would eliminate the need for JIT compilation. Is there an equivalent in the Java platform?
The native compiler that I've heard the most about is Excelsior JET - Java Virtual Machine and Native Compiler. See http://www.excelsior-usa.com/jet.html for more details. Basically you can turn your project into a single executable without the hassles of the usual Java packaging.
They have been around for a long time (they where here when I joined the Java ranks in 2001 and they are here now. I just heard a week ago how a company is using their solution are and are happy with it.
About couple of years ago at JavaONE I also met a developer or two of the product and they told me that they are live and kicking and doing well.
I'm not aware of any, personally (you can look at options like launch4j, jexe, etc, they are just wrappers, not like NGen), and I'm not sure how feasible it would be... The answer to this question goes into some details on the subject of compiling to native code: Differences in JIT between Java and .Net
Yes. As of Java 9, you can. The feature you are looking for is called Ahead of Time (AOT) compilation.
There are two main JVMs in use today:
HotSpot (and it's variants), which is the main JVM from Oracle.
OpenJ9, originally from IBM.
OpenJ9
In OpenJ9, just run the Java Virtual Machine with the -Xshareclasses:persistent option. This causes the VM to store compiled binaries into a cache, which persists across system boots. It does not force the Java VM to use the precompiled code in all cases, as in many cases Just In Time (JIT) code can execute faster. The JVM will pick whether to use the cached binary or not on a case by case basis. When a cached AOT method is run it might also be optimized further by the Just-In-Time (JIT) compiler.
Full details are available at:
https://www.eclipse.org/openj9/docs/aot/
https://www.eclipse.org/openj9/docs/xshareclasses
HotSpot (OpenJDK)
The HotSpot (OpenJDK) builds now include an experimental VM that can completely precompile everything, called GraalVM. You manually create native binaries using the jaotc executable. Note: this is currently only available on Linux (and possibly Mac) systems.
Details on how to use the jaotc compiler are at:
https://docs.oracle.com/javase/10/vm/java-hotspot-virtual-machine-performance-enhancements.htm#JSJVM-GUID-F33D8BD0-5C4A-4CE8-8259-FD9D73C7C7C6
https://openjdk.java.net/jeps/295 (this includes an example where you generate and use an AOT library for the java.base module).
Note: jaotc is not as simple to use as the OpenJ9 shared classes flag.
Java code is compiled to bytecode which it is portable across many platforms.
But Java also is JIT compiled which happens on the fly.
Does this mean Java is compile twice? first by us to produce the bytecode and the second by the JVM?
Thanks.
Your code may be compiled from bytecode into native code by the JVM if it's "hot enough"; and it may be so compiled several times, with the old version being discarded, depending on the runtime characteristics of your program.
The JIT is a complicated beast; in fact the Sun JVM has two JITs (-client and -server) that behave differently from each other, and some implementations even support both JITs running together (so you may have interpreted bytecode running alongside code compiled by two different JITs in your application).
I recommend you read more about Hotspot (the most common JIT since it's the Sun one) if you're really interested in this subject. You can start at Sun's page.
TMK, when you compile you are compiling for the JVM platform. Then when you run the app on the JVM on any machine, certain parts of code that are used frequently get compiled into code native to that machine for optimization.
So in short: Yes, but for a very good reason
Does this mean Java is compile twice?
first by us to produce the bytecode
and the second by the JVM? Thanks.
You could say that, once using information available in the source code (compiler), then the other in runtime (JVM/JIT) when information about the specific hardware is available, along with some profiling to decide what gets to be JIT-compiled or not.
The mechanism is
Java -> Byte Code (compiled By java compiler)
ByteCode -> native code (interpreted by JVM)
Short answer: Yes kind of.
The longest one: That is 2 different things.
The first compilation is from the source code to the bytecode often call the intermediate representation (IR) in the compilation field.
Then the VM take the bytecode and translate it back to the native code on which platform it is installed.
This is 2 completely different kind of compilation. The second is not even quite a compilation since there is no syntax checker scope analyzer... Well there is some check but not the same kind of check that you have in a compiler.