Skip to content

Commit e74cbe8

Browse files
8281089: JavaFX built with VS2019 and jlinked into JDK 11.x fails to start
Reviewed-by: arapte, sykora
1 parent adf1da4 commit e74cbe8

File tree

2 files changed

+86
-51
lines changed

2 files changed

+86
-51
lines changed

build.gradle

+30-17
Original file line numberDiff line numberDiff line change
@@ -5343,13 +5343,6 @@ compileTargets { t ->
53435343
def standaloneSdkDir = "${rootProject.buildDir}/${standaloneSdkDirName}"
53445344
def standaloneLegalDir = "${standaloneSdkDir}/legal"
53455345

5346-
def excludeNativeLibs = []
5347-
if (IS_WINDOWS) {
5348-
// List of duplicate Microsoft DLLs to exclude
5349-
excludeNativeLibs += targetProperties.VS2017DLLNames
5350-
excludeNativeLibs += targetProperties.WinSDKDLLNames
5351-
}
5352-
53535346
moduleProjList.each { project ->
53545347
def moduleName = project.ext.moduleName
53555348
def buildDir = project.buildDir
@@ -5358,9 +5351,36 @@ compileTargets { t ->
53585351
def srcLibDir = "${buildDir}/${platformPrefix}module-lib"
53595352
def srcLegalDir = "${standaloneLegalDir}/${moduleName}"
53605353

5354+
def jmodLibDir = srcLibDir
5355+
if (IS_WINDOWS) {
5356+
jmodLibDir = "${srcLibDir}-jmod"
5357+
}
5358+
53615359
def jmodName = "${moduleName}.jmod"
53625360
def jmodFile = "${jmodsDir}/${jmodName}"
5363-
def jmodTask = project.task("jmod$t.capital", group: "Build", dependsOn: sdk) {
5361+
5362+
// On Windows, copy the native libraries in the jmod image
5363+
// to a "javafx" subdir to avoid conflicting with the Microsoft
5364+
// DLLs that are shipped with the JDK
5365+
def jmodCopyLibTask = project.task("jmodCopyLib$t.capital", type: Copy, dependsOn: sdk) {
5366+
enabled = IS_WINDOWS
5367+
5368+
group = "Basic"
5369+
description = "copied Windows DLLs into javafx subdir for jmods"
5370+
5371+
into jmodLibDir
5372+
5373+
from (srcLibDir) {
5374+
exclude("*.dll")
5375+
}
5376+
5377+
from (srcLibDir) {
5378+
include("*.dll")
5379+
into("javafx")
5380+
}
5381+
}
5382+
5383+
def jmodTask = project.task("jmod$t.capital", group: "Build", dependsOn: [sdk, jmodCopyLibTask]) {
53645384
doLast {
53655385
mkdir jmodsDir
53665386
delete(jmodFile);
@@ -5371,16 +5391,9 @@ compileTargets { t ->
53715391
args(srcClassesDir)
53725392
args("--module-version", "$RELEASE_VERSION_SHORT")
53735393
// Not all modules have a "lib" dir
5374-
if (file(srcLibDir).isDirectory()) {
5394+
if (file(jmodLibDir).isDirectory()) {
53755395
args("--libs")
5376-
args(srcLibDir)
5377-
}
5378-
// Exclude duplicate native libs from javafx.graphics.jmod
5379-
if (moduleName == "javafx.graphics") {
5380-
excludeNativeLibs.each { name ->
5381-
args("--exclude")
5382-
args(name)
5383-
}
5396+
args(jmodLibDir)
53845397
}
53855398
args("--legal-notices")
53865399
args(srcLegalDir)

modules/javafx.graphics/src/main/java/com/sun/glass/utils/NativeLibLoader.java

+56-34
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ public static synchronized void loadLibrary(String libname, List<String> depende
6969

7070
private static boolean verbose = false;
7171

72-
private static boolean usingModules = false;
7372
private static File libDir = null;
7473
private static String libPrefix = "";
7574
private static String libSuffix = "";
@@ -116,8 +115,9 @@ private static String[] initializePath(String propname) {
116115

117116
private static void loadLibraryInternal(String libraryName, List<String> dependencies, Class caller) {
118117
// The search order for native library loading is:
119-
// - try to load the native library from the same folder as this jar
120-
// (only on non-modular builds)
118+
// - try to load the native library from either ${java.home}
119+
// (for jlinked javafx modules) or from the same folder as
120+
// this jar (if using modular jars)
121121
// - if the native library comes bundled as a resource it is extracted
122122
// and loaded
123123
// - the java.library.path is searched for the library in definition
@@ -130,7 +130,7 @@ private static void loadLibraryInternal(String libraryName, List<String> depende
130130
// since it isn't applicable to Jigsaw.
131131
loadLibraryFullPath(libraryName);
132132
} catch (UnsatisfiedLinkError ex) {
133-
if (verbose && !usingModules) {
133+
if (verbose) {
134134
System.err.println("WARNING: " + ex);
135135
}
136136

@@ -326,51 +326,73 @@ static byte[] calculateCheckSum(File file) {
326326
}
327327

328328

329+
private static File libDirForJRT() {
330+
String javaHome = System.getProperty("java.home");
331+
332+
if (javaHome == null || javaHome.isEmpty()) {
333+
throw new UnsatisfiedLinkError("Cannot find java.home");
334+
}
335+
336+
// Set the native directory based on the OS
337+
String osName = System.getProperty("os.name");
338+
String relativeDir = null;
339+
if (osName.startsWith("Windows")) {
340+
relativeDir = "bin/javafx";
341+
} else if (osName.startsWith("Mac")) {
342+
relativeDir = "lib";
343+
} else if (osName.startsWith("Linux")) {
344+
relativeDir = "lib";
345+
}
346+
347+
// Location of native libraries relative to java.home
348+
return new File(javaHome + "/" + relativeDir);
349+
}
350+
351+
private static File libDirForJarFile(String classUrlString) throws Exception {
352+
// Strip out the "jar:" and everything after and including the "!"
353+
String tmpStr = classUrlString.substring(4, classUrlString.lastIndexOf('!'));
354+
// Strip everything after the last "/" or "\" to get rid of the jar filename
355+
int lastIndexOfSlash = Math.max(tmpStr.lastIndexOf('/'), tmpStr.lastIndexOf('\\'));
356+
357+
// Set the native directory based on the OS
358+
String osName = System.getProperty("os.name");
359+
String relativeDir = null;
360+
if (osName.startsWith("Windows")) {
361+
relativeDir = "../bin";
362+
} else if (osName.startsWith("Mac")) {
363+
relativeDir = ".";
364+
} else if (osName.startsWith("Linux")) {
365+
relativeDir = ".";
366+
}
367+
368+
// Location of native libraries relative to jar file
369+
String libDirUrlString = tmpStr.substring(0, lastIndexOfSlash)
370+
+ "/" + relativeDir;
371+
return new File(new URI(libDirUrlString).getPath());
372+
}
373+
329374
/**
330-
* Load the native library from the same directory as the jar file
331-
* containing this class.
375+
* Load the native library either from the same directory as the jar file
376+
* containing this class, or from the Java runtime.
332377
*/
333378
private static void loadLibraryFullPath(String libraryName) {
334379
try {
335-
if (usingModules) {
336-
throw new UnsatisfiedLinkError("ignored");
337-
}
338380
if (libDir == null) {
339381
// Get the URL for this class, if it is a jar URL, then get the
340382
// filename associated with it.
341383
String theClassFile = "NativeLibLoader.class";
342384
Class theClass = NativeLibLoader.class;
343385
String classUrlString = theClass.getResource(theClassFile).toString();
344386
if (classUrlString.startsWith("jrt:")) {
345-
// Suppress warning messages
346-
usingModules = true;
347-
throw new UnsatisfiedLinkError("ignored");
348-
}
349-
if (!classUrlString.startsWith("jar:file:") || classUrlString.indexOf('!') == -1) {
387+
libDir = libDirForJRT();
388+
} else if (classUrlString.startsWith("jar:file:") && classUrlString.indexOf('!') > 0) {
389+
libDir = libDirForJarFile(classUrlString);
390+
} else {
350391
throw new UnsatisfiedLinkError("Invalid URL for class: " + classUrlString);
351392
}
352-
// Strip out the "jar:" and everything after and including the "!"
353-
String tmpStr = classUrlString.substring(4, classUrlString.lastIndexOf('!'));
354-
// Strip everything after the last "/" or "\" to get rid of the jar filename
355-
int lastIndexOfSlash = Math.max(tmpStr.lastIndexOf('/'), tmpStr.lastIndexOf('\\'));
356-
357-
// Set the native directory based on the OS
358-
String osName = System.getProperty("os.name");
359-
String relativeDir = null;
360-
if (osName.startsWith("Windows")) {
361-
relativeDir = "../bin";
362-
} else if (osName.startsWith("Mac")) {
363-
relativeDir = ".";
364-
} else if (osName.startsWith("Linux")) {
365-
relativeDir = ".";
366-
}
367-
368-
// Location of native libraries relative to jar file
369-
String libDirUrlString = tmpStr.substring(0, lastIndexOfSlash)
370-
+ "/" + relativeDir;
371-
libDir = new File(new URI(libDirUrlString).getPath());
372393

373394
// Set the lib prefix and suffix based on the OS
395+
String osName = System.getProperty("os.name");
374396
if (osName.startsWith("Windows")) {
375397
libPrefix = "";
376398
libSuffix = ".dll";

0 commit comments

Comments
 (0)