commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Gerwin (JIRA)" <>
Subject [jira] [Commented] (DAEMON-396) LibraryPath is broken for Java 11
Date Fri, 29 Mar 2019 15:21:00 GMT


Gerwin commented on DAEMON-396:

I have analyzed this a bit more, and I found 3 problems in total:
 *1. LibraryPath is not set for Java 11 jvm.dll*
 When I execute this command
dumpbin /headers <path to binary>
it gives me these results
||binary||linker version||[Visual Studio version|]||
|TomEE.amd64.exe|9.00|Visual Studio 2008|
|jvm.dll (6)|8.00|Visual Studio 2005|
|jvm.dll (7)|10.00|Visual Studio 2010|
|jvm.dll (8)|10.00|Visual Studio 2010|
|jvm.dll (9)|12.00|Visual Studio 2013|
|jvm.dll (10)|12.00|Visual Studio 2013|
|jvm.dll (11)|14.12|Visual Studio 2017 15.5|
|jvm.dll (12)|14.12|Visual Studio 2017 15.5|
|jvm.dll (13)|14.16|Visual Studio 2017 15.9|

Now, when I compile TomEE.amd64.exe with VS2017(15.9), the environment variable is picked
up again! Works both for Java 8 and 11.
 So my proposal is to make a new release of commons-deamon compiled with VS2017(15.9).

*2. LibraryPath does replace PATH instead of append.*
 I found a problem in the call to {{GetEnvironmentVariableW()}} in {{utils.c}}. The provided
buffer size 'rc - al' is too small, hence the existing PATH is not copied to the buffer. And
that results in the PATH being replaced instead of appended. Here is the patch: [^apxAddToPathW.patch].

*3 PATH does not include JAVA_HOME/bin*
 I get this error when I use AWT:
java.lang.UnsatisfiedLinkError: C:\Program Files\Java\jdk-11.0.2\bin\awt.dll: Can't find dependent
 at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
 at java.base/java.lang.ClassLoader$NativeLibrary.load(
 at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(
 at java.base/java.lang.ClassLoader.loadLibrary0(
 at java.base/java.lang.ClassLoader.loadLibrary(
 at java.base/java.lang.Runtime.loadLibrary0(
 at java.base/java.lang.System.loadLibrary(
 at java.desktop/java.awt.Toolkit$
 at java.desktop/java.awt.Toolkit$
 at java.base/ Method)
 at java.desktop/java.awt.Toolkit.loadLibraries(
 at java.desktop/java.awt.Toolkit.<clinit>(
 at java.desktop/java.awt.Color.<clinit>(
Reason is that JAVA_HOME/bin is not on the PATH *and* the the directory of the binary (TomEE.amd64.exe)
is TomEE/bin *and* the working directory is TomEE/bin. So dependent DLLs are not found.
 I fixed this by adding JAVA_HOME/bin explicitly to the PATH when using jvm.dll. See [^JAVA_HOME-bin-to-PATH.patch].

> LibraryPath is broken for Java 11
> ---------------------------------
>                 Key: DAEMON-396
>                 URL:
>             Project: Commons Daemon
>          Issue Type: Bug
>          Components: Procrun
>    Affects Versions: 1.1.1
>            Reporter: Gerwin
>            Priority: Critical
>         Attachments: JAVA_HOME-bin-to-PATH.patch, apxAddToPathW.patch
> My application which runs on TomEE is broken when running on Java 11. I'm getting this
> {code:none}
> java.lang.UnsatisfiedLinkError: no xmlForJava in java.library.path: [C:\Program Files\TomEE\bin,
<<more paths here>>, .]
>                 at java.base/java.lang.ClassLoader.loadLibrary(
>                 at java.base/java.lang.Runtime.loadLibrary0(
>                 at java.base/java.lang.System.loadLibrary(
> {code}
> It works for Java 8 and 10, but fails for both Oracle JDK 11 and OpenJDK 11.
> The application installs the service with the {{--LibraryPath}} option and {{--StartMode
jvm}}. When inspecting the {{java.library.path}} using JMX, I observe this:
> # With Java 8 {{java.library.path}} contains the value specified in the LibraryPath
> # With Java 11 {{java.library.path}} contains the value of the PATH environment variable
> From the sourcecode I see that procrun is executing code in this order:
> {code:none}
> _wputenv("PATH=;C:\\application\\lib");
> LoadLibraryW("jvm.dll")
> JNI_CreateJavaVM()
> SetDllDirectoryW(";C:\\application\\lib")
> {code}
> The JVM is supposed to take the value of the PATH variable into account when loaded,
but it doesn't.
> I found these articles:
> * Stackoverflow: [Program uses outdated (not current) env variable value|]
> * Microsoft Docs: [Potential Errors Passing CRT Objects Across DLL Boundaries#This example
passes environment variables across a DLL boundary|]
> So the C-Runtime library has its own copy of the environment variables and behavior depends
on how the binaries are compiled.
> * /MD means they share a single copy of the C-Runtime library.
> * /MT means that they use separate copies of the C-Runtime library.
> I expect that Java 11 is build differently, which causes this bug.
> Give this quote...
> {quote}
> Normally when Java is launched and a library path is not specified, the JVM will default
to using the system PATH on Windows and the LD_LIBRARY_PATH on UNIX systems to locate any
native libraries loaded by the application. This is akin to what happens with the CLASSPATH
environment variable when a specific classpath is not specified when launching the JVM. The
use of the CLASSPATH environment variable has fallen out of style because of all the conflict
problems which can arise when multiple Java applications are installed on the same machine.
The same issues are all there with the library path as well.
> In general, it is advised that you avoid potential problems when your application is
deployed by being conservative about which directories will be included in the Java library
> {quote}
> .. I think it would be better to change the implementation of {{--LibraryPath}} to set
the JVM option {{-Djava.library.path}} instead of the PATH env var.
> This will make procrun independent of how the jvm.dll is build.

This message was sent by Atlassian JIRA

View raw message