Fix for test/jdk/tools/jpackage/share/JavaOptionsTest.java on Alpine Linux

Mikael Vidstedt mikael.vidstedt at oracle.com
Sat Feb 22 00:49:04 UTC 2020


Looping in the AIX folks for good luck.

I sorta expected the “hack” of enabling that re-execution in the launcher would bite back at some point, but at the time it seemed like the simple thing to do. At the time I even went down the rabbit hole of exploring the option of merging libjava.so and libjvm.so, but not sure that’s really practical or in the end even solves the problem.

Assuming 1. is the “Right Way(tm)”, why wouldn’t we do that? :) Sharing the code would of course be nice, but worst case some duplication may be the better option?

Cheers,
Mikael

> On Feb 20, 2020, at 5:29 AM, Alexander Scherbatiy <alexander.scherbatiy at bell-sw.com> wrote:
> 
> 
> Hello,
> 
> Short description:
> 
> JavaOptionsTest.java test creates a jar file with a simple Hello java class, packages it into a native app and calls it.
> 
> JLI reexecutes the native app on Linux Alpine and because of this java options are doubled when passed to Hello application.
> 
> The proposed fix adds java options only if the application arguments does not contain them:
> 
> http://cr.openjdk.java.net/~alexsch/portola/tests/jpackage/webrev.01
> 
> 
> Detailed description:
> 
> The native app first calls start_launcher() method from src/jdk.incubator.jpackage/share/native/libapplauncher/main.cpp file which uses Package::SetCommandLineArguments() to store provided arguments in FBootFields->FArgs field. Next it calls RunVM().
> 
> JavaVirtualMachine::launchVM() method stores both java options and arguments from FBootFields->FArgs into jvm args list and calls javaLibrary.JavaVMCreate() so the provided args are passed to the java application.
> 
> This path is different on Alpine Linux which sets LD_LIBRARY_PATH and JLI decides to invoke start_launcher() one more time with the updated library path (see [1]).
> 
> This time all java options are passed to start_launcher() method, they stored in FBootFields->FArgs and concatenated with java options passed to JavaVirtualMachine::launchVM() method.
> 
> So jvm options are stored twice in case the launcher decides to reexec itself.
> 
> Possible solutions:
> 
> 1. The right way would be to detect that the JLI is reexecuted in the same way as it does JLI (see [2]). It has some complicated logic in ContainsLibJVM() method and the code needs to be shared between java.base and jdk.incubator.jpackage modules.
> 
> 2. Using a static variable to check that the jpackage is executed the second time. It does not work because the jpackage is executed by as a new process by execve().
> 
> Here are two subsequent calls of execve() on Alpine Linux from strace log:
> 
> -----
> 
> execve("./output/test/bin/test", ["./output/test/bin/test", "-Dparam2=test2"], 0x7fff98259778 /* 8 vars */) = 0
> 
> execve("/root/mount/repos/branch-portola-dev/jtreg/alpine/app/output/test/bin/test", ["./output/test/bin/test", "-Djava.library.path=/root/mount/"..., "-Djava.l
> arch_prctl(ARCH_SET_FS, 0x7f42a0298d48) = 0
> 
> -----
> 
> Java options are passed to the second app call there jpackage adds them one more time.
> 
> 
> 3. Check in some way that the app arguments already contain java options and to not add them the second time.
> 
> The proposed fix converts the app arguments to std::set. I tried to use std::unordered_set but got the error message:
> 
> "#error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options."
> 
> Actually java options are always set first for vmargs so it is also possible only to check that if the app arguments list starts with java options list. It relies on the way how java options are passed to jpackage and it can be fragile.
> 
> 
> May be it has sense to check the app arguments and java options only if LIBC is defined and it equals to musl.
> 
> One more interesting question is if the test passes on AIX because AIX also requires the modified LD_LIBRARY_PATH and the test should fail for the same reason.
> 
> 
> [1] https://hg.openjdk.java.net/portola/portola/file/7ff60204a181/src/java.base/unix/native/libjli/java_md_solinux.c#l85
> 
> [2] https://hg.openjdk.java.net/portola/portola/file/7ff60204a181/src/java.base/unix/native/libjli/java_md_solinux.c#l306
> 
> Thanks,
> 
> Alexander.
> 



More information about the portola-dev mailing list