Skip to content

Commit e20b921

Browse files
8281089: JavaFX built with VS2019 and jlinked into JDK 11.x fails to start
Backport-of: e74cbe8
1 parent dd4cfd0 commit e20b921

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
@@ -5315,13 +5315,6 @@ compileTargets { t ->
53155315
def standaloneSdkDir = "${rootProject.buildDir}/${standaloneSdkDirName}"
53165316
def standaloneLegalDir = "${standaloneSdkDir}/legal"
53175317

5318-
def excludeNativeLibs = []
5319-
if (IS_WINDOWS) {
5320-
// List of duplicate Microsoft DLLs to exclude
5321-
excludeNativeLibs += targetProperties.VS2017DLLNames
5322-
excludeNativeLibs += targetProperties.WinSDKDLLNames
5323-
}
5324-
53255318
moduleProjList.each { project ->
53265319
def moduleName = project.ext.moduleName
53275320
def buildDir = project.buildDir
@@ -5330,9 +5323,36 @@ compileTargets { t ->
53305323
def srcLibDir = "${buildDir}/${platformPrefix}module-lib"
53315324
def srcLegalDir = "${standaloneLegalDir}/${moduleName}"
53325325

5326+
def jmodLibDir = srcLibDir
5327+
if (IS_WINDOWS) {
5328+
jmodLibDir = "${srcLibDir}-jmod"
5329+
}
5330+
53335331
def jmodName = "${moduleName}.jmod"
53345332
def jmodFile = "${jmodsDir}/${jmodName}"
5335-
def jmodTask = project.task("jmod$t.capital", group: "Build", dependsOn: sdk) {
5333+
5334+
// On Windows, copy the native libraries in the jmod image
5335+
// to a "javafx" subdir to avoid conflicting with the Microsoft
5336+
// DLLs that are shipped with the JDK
5337+
def jmodCopyLibTask = project.task("jmodCopyLib$t.capital", type: Copy, dependsOn: sdk) {
5338+
enabled = IS_WINDOWS
5339+
5340+
group = "Basic"
5341+
description = "copied Windows DLLs into javafx subdir for jmods"
5342+
5343+
into jmodLibDir
5344+
5345+
from (srcLibDir) {
5346+
exclude("*.dll")
5347+
}
5348+
5349+
from (srcLibDir) {
5350+
include("*.dll")
5351+
into("javafx")
5352+
}
5353+
}
5354+
5355+
def jmodTask = project.task("jmod$t.capital", group: "Build", dependsOn: [sdk, jmodCopyLibTask]) {
53365356
doLast {
53375357
mkdir jmodsDir
53385358
delete(jmodFile);
@@ -5342,16 +5362,9 @@ compileTargets { t ->
53425362
args("--class-path")
53435363
args(srcClassesDir)
53445364
// Not all modules have a "lib" dir
5345-
if (file(srcLibDir).isDirectory()) {
5365+
if (file(jmodLibDir).isDirectory()) {
53465366
args("--libs")
5347-
args(srcLibDir)
5348-
}
5349-
// Exclude duplicate native libs from javafx.graphics.jmod
5350-
if (moduleName == "javafx.graphics") {
5351-
excludeNativeLibs.each { name ->
5352-
args("--exclude")
5353-
args(name)
5354-
}
5367+
args(jmodLibDir)
53555368
}
53565369
args("--legal-notices")
53575370
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)