How does the JDK execute?

This is actually a general java programming question, and I’m just looking for any handy resources people here know; it’s quite hardcore, and I know there are people here who’ve more than a passing familiarity with this stuff, so…

I want to find out exactly what files “javac” and to a lesser extent “java” use and how in order to execute. Everything; I have to build a virtual FS to execute them in, so I can’t miss things out. I’m browsing for release notes etc on the sun site, but IME a lot of this less-frequently-used info tends to be broken links, no-longer-linked-at-all, or password protected.

For instance, I know that rt.jar is sort-of sourced into the classpath to provide all the standard libraries (although I’ve never really delved into how/why it changed from being plain ole classes.zip).

For instance, if javac cannot execute without the presence of some of the DLL’s in the accompanying JRE, this is the stuff I need to know! (I’m particularly concerned to find out to what extent the JDK can execute javac if - for instance - you deleted the entire JRE directory).

Or, for instance, what is the relevance of the [jdk]/include directory? IIRC it’s just for JNI, providing c-headers for JNI to compile against, but I may be very wrong ;D.


(just to allay concerns of any Sun people…)

I’m not trying to cut-down the JDK/JRE for re-distribution. I’m trying to write wrappers for javac and java - in a functional programming language. everything needs to be expressed within the domain of the fn-lang (including mapping all the files that javac needs into the fn environment); javac will actually be executed from within a sandboxed environment provided and managed by the fn lang.

Now, I love fn-langs as much as anyone, but it’s enough of a head-**** when you’re already thinking in java that I’d appreciate any help I can get on making the wrappers work. I’d also like to make OS-independent wrappers if possible (probably not), or at least make sensible decisions on isolating and encapsulating the OS-specific aspects into separate fn’s.

Well for one, I think javac is just a stub to launch a compiler that is written in Java… so you pretty much need a JRE.

You can get the source code of java.exe from src.jar. It uses JNI to start the VM.

I would start by looking at the source code, then pick apart the JRE. You might be able to extract all the JRE jars and then selectively rename folders to effectively take various packages out of the classpath.

You might also look at the stuff for doing dynamic proxies, which I believe does some fancy run-time compiling.

see:
java.lang.reflect.Proxy

I don’t think that it is documented somewhere which files a JVM requires. You could use strace or a similar tool (filemon on Windows) to find the files a certain Java version will use.

For example, starting java.exe without arguments on Windows XP touches the following files: \lib\i386\jvm.cfg, \bin\client\jvm.dll, \bin\hpi.dll, \bin\verify.dll, \bin\java.dll, \bin\zip.dll, c:\cygwin\home\sma.hotspotrc (oops?!), \lib\endorsed, \lib\rt.jar, \lib\sunrsasign.jar, \lib\jsse.jar, \lib\jce.jar, \lib\charsets.jar, c:\cygwin\home\sma.hotspot_compiler (again oops), \lib\ext* (everything what’s in there), \lib\security\java.security, \lib\tzmappings, \lib\zi\europe\berlin, \lib\zi\gmt

I’m pretty sure that other DLLs from \bin will be needed once that part of the JRE will be used, awt.dll for example, fontmanager.dll or jpeg.dll.

I don’t think you can leave out DLLs.

Regarding javac. That’s a Java application and therefore it needs Java, that is, everything java.exe will need.

If you just want to know that files javac needs in addition you could either look at the source (available separately, although not the latest version, I think), or look at the latest gcj alpha version via ealy access program and hope that nothing has changed or for example use the Eclipse java compiler. That’s freely available under an open source license, so you could study that source code, even change it and use the compiler - which is available as a stand alone version, not only as part of the Eclipse IDE - as an replacement.

Well…

I built a virtual FS with the whole of the jdk directory in it, plus all the usual suspects

[] /dev
[
] /boot
[] /etc
[
] /lib
[] /sbin
[
] /usr

But it seems it wasn’t enough :(. Because when invoking javac on a Hello World java source file, I get:

0/#
0/# HotSpot Virtual Machine Error, Internal Error
0/# Please report this error at
0/# http://java.sun.com/cgi-bin/bugreport.cgi
0/#
0/# Java VM: Java HotSpot™ Client VM (1.4.2-b28 mixed mode)
0/#
0/# Error ID: 4F533F4C494E55580E43505001C9
0/#
0/
0/Heap at VM Abort:
0/Heap
0/
0/
0/****************
0/Another exception has been detected while we were handling last error.
0/Dumping information about last error:
0/ERROR REPORT FILE = (N/A)
0/PC = 0x403ffa88
0/SIGNAL = 11
0/FUNCTION NAME = (N/A)
0/OFFSET = 0xFFFFFFFF
0/LIBRARY NAME = (N/A)
0/Please check ERROR REPORT FILE for further information, if there is any.
0/Good bye.

…which is about as helpful as a kick in the teeth.

Presumably I’m either missing something in my FS, or preventing java from accessing something it needs. The parts of the jdk dir I included (recursively) were:

[] bin
[
] include
[] jre
[
] lib
[*] src.zip

Well…I say recursively, and it’s just possible that I’ve got this fn-language wrong and it’s not recursive. Would I even have got as far as invoking hotspot if only one layer of each directory were being imported?

Sadly (very sadly) I can’t get interactive access to my virtual FS to “test” it - because it’s all composed inside this fn-language. Any extra ideas?

(ps: FYI the virtual FS is built under-the-covers using chroot, IIUC).

If the VM crashes, I’d assume some shared lib is missing. From the error message I guess the VM crashes while it wants to report an error. Talking about chroot, why don’t try to create an interactive test environment first and then chroot into that, still using a shell like bash so that you’d been able to look at error report file mentioned in the error message?

Addendum: I just tried

strace java 2>&1 | grep ^open | grep -v ENOENT | less

on Linux to check which files java -version opens. Do you have all required libs in /lib? It’s also interesting (by removing the -v switch)
to see which files the VM looks for but didn’t find.

[quote]Talking about chroot, why don’t try to create an interactive test environment first and then chroot into that, still using a shell like bash so that you’d been able to look at error report file mentioned in the error message?
[/quote]
I’m going to try that, but part of the problem is that a lot of the environment is built by 3rd party code. Someone else has given me some source that will trace failed lib lookups from within the fn-lang, so I’ll try that first (but it’s going to be 10 pages+ of calls to read through, if strace is anything to go by!)

[quote]It’s also interesting (by removing the -v switch)
to see which files the VM looks for but didn’t find.
[/quote]
Yeah, I noticed that too :). Some interesting defaults that it searches for…

Anyway, thanks for the suggested strace cmd, I’ve got a couple of things to try now :). (and I’d never even heard of strace let alone used it until yesterday…it’s quite a funky little thing).

…but not /proc, which certainly gets accessed for some things. Does anyone know (perhaps someone from Sun?) whether /proc is essential to the JVM starting?

EDIT: and I haven’t got /tmp either, which the JVM appears to look for hsperfdata files in…

Apparently there is a way of pausing the fn-lang and cd-ing into the temporarily mounted virtual FS, which I’m trying to do, but unfortunately the command for doing this doesn’t seem to be working at the moment :(.

You might be interested in this /proc related bug, which has been fixed in 1.4.2_04 (and 1.5.0):

http://developer.java.sun.com/developer/bugParade/bugs/4902977.html

for a pre 1.4.2_04 JDK you could mount /proc (possibly with -bind) into your virtual filesystem.

[quote]You might be interested in this /proc related bug, which has been fixed in 1.4.2_04 (and 1.5.0):
[/quote]
Um, I may be about to say “I can’t thank you enough”! That’s the same VM abort I’ve been getting (same Error ID, although different PC, so maybe this isn’t the fix). I hadn’t even noticed _04 was out…

Testing now…

Thanks, sugarshark. That was indeed the problem.

I’m glad I could help :slight_smile:

Seems they haven’t run a full test suite on this - the javac tool won’t accept the “-d” argument if called from chroot environment :(. I may be missing something subtle here, but we seem to be able to invoke the exact same command line - even if the d target is a file, a directory, or non-existent - and under the normal FS we get either successful compile or the correct error messages, but in the chroot we get “invalid flag” from javac.

You would have thought they’d have run some kind of unit test / system test on this?