1

I'm trying to run an old JDK (version 1.3 released in May 2000) in a relatively modern Linux box (Debian 10).

As far as binary compatibility is concerned, everything seems fine, since all the necessary 32-bit dependencies are still available in Debian Linux:

  • libbsd0
  • libc6
  • libgcc1
  • libice6
  • libnspr4
  • libodbc1
  • libsm6
  • libuuid1
  • libx11-6
  • libxau6
  • libxcb1
  • libxdmcp6
  • libxext6
  • libxi6
  • libxt6
  • libxtst6
  • unixodbc-dev

What's missing is libxp6:i386 which is luckily still available from Debian 8 "Jessie" and the ancient libstdc++ from gcc 2.96, which can be taken from early CentOS versions (CentOS 4, compat-libstdc++-296 package).

Using the above recipé, I used to successfully run Java 1.3 (incl. even the JDBC-ODBC bridge) up until Debian 9. Then, Debian 10 was released. Now, running java -version instead of the usual

java version "1.3.1_20"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_20-b03)
Java HotSpot(TM) Client VM (build 1.3.1_20-b03, mixed mode)

prints out

Error occurred during initialization of VM
java/lang/NoClassDefFoundError: java/lang/Object

Indeed, it fails to unpack rt.jar and load java/lang/Object.class out of the JAR archive. When running strace -f, the difference between Debian 9 and Debian 10 can be clearly seen. Here, the process opens rt.jar and maps it (mmap()) into the virtual memory:

stat64("/usr/lib/jvm/java-1.3.1_20-sun-i386/jre/lib/rt.jar", {st_mode=S_IFREG|0644, st_size=13904932, ...}) = 0
lstat64("/usr", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/lib/jvm", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/lib/jvm/java-1.3.1_20-sun-i386", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
lstat64("/usr/lib/jvm/java-1.3.1_20-sun-i386/jre", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
lstat64("/usr/lib/jvm/java-1.3.1_20-sun-i386/jre/lib", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
lstat64("/usr/lib/jvm/java-1.3.1_20-sun-i386/jre/lib/rt.jar", {st_mode=S_IFREG|0664, st_size=13904932, ...}) = 0
open("/usr/lib/jvm/java-1.3.1_20-sun-i386/jre/lib/rt.jar", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0664, st_size=13904932, ...}) = 0
_llseek(3, 0, [13904932], SEEK_END)     = 0
mmap2(NULL, 13904932, PROT_READ, MAP_SHARED, 3, 0) = 0xf6b9c000
close(3)                                = 0

And here's exactly the same scenario from Debian 10:

stat64("/usr/lib/jvm/java-1.3.1_20-sun-i386/jre/lib/rt.jar", {st_mode=S_IFREG|0644, st_size=13904932, ...}) = 0
openat(AT_FDCWD, "/usr/lib/jvm/java-1.3.1_20-sun-i386/jre", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
close(3)                                = 0

As you can see, instead of /usr/lib/jvm/java-1.3.1_20-sun-i386/jre/lib/rt.jar being opened (open() or openat()), one of its parent directories (/usr/lib/jvm/java-1.3.1_20-sun-i386/jre) is opened, quite expectedly resulting in the empty JVM classpath.

The cause of the problem is definitely not the kernel: I observe the same difference using i386/debian:10 vs i386/debian:9 Docker image with exactly the same kernel on exactly the same hardware.

The workarounds I'm considering are:

  • using a VM with an earlier Linux version,
  • using a Docker container with an earlier Linux userspace,
  • substituting an earlier glibc version,
  • switching to any BSD UNIX (Free/Net/DragonFly), with a stable Linux ABI.

Still, are there any ways to further diagnose the problem?

Bass
  • 4,977
  • 2
  • 36
  • 82
  • 1
    Out of sheer curiosity - why are you trying to run a 23 year old java? – tink May 03 '23 at 09:17
  • @tink I'm into retrocomputing. In this particular case, I want to run NetBeans 3.0 IDE using the period-correct JVM. – Bass May 03 '23 at 09:25
  • 1
    In that case - opinion based, from a sysadmins experience set - I'd strongly suggest not to retrofit cruft onto your main OS and go with a VM of sorts. KVM, VirtualBox, VMware Desktop, Bochs ... whatever floats your boat. – tink May 03 '23 at 17:17
  • 1
    @tink Thank you! That's what I was considering myself — yet I need some time to accept the inevitable. – Bass May 03 '23 at 17:28
  • 1
    And another tangential note: **relatively modern Linux** ... buster has gone EOL **2022-08-14** ;) Did I mention that I have a sysadmin mindset (and a fairly strong security focus)? ;D – tink May 03 '23 at 20:51

0 Answers0