Skip to content

Commit e6c6b37

Browse files
committed
Revert to previous fix opening frameworks with full path. Adjust test coverage.
> Check for library presence by attempting to dlopen() the path, which will correctly check for the library in the cache. Signed-off-by: David Kocher <[email protected]>
1 parent 65085c1 commit e6c6b37

File tree

2 files changed

+95
-46
lines changed

2 files changed

+95
-46
lines changed

src/com/sun/jna/NativeLibrary.java

+26-32
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ private static int openFlags(Map<String, ?> options) {
150150
return DEFAULT_OPEN_OPTIONS;
151151
}
152152

153-
private static NativeLibrary loadLibrary(String libraryName, Map<String, ?> options) {
153+
private static NativeLibrary loadLibrary(final String libraryName, final Map<String, ?> options) {
154154
LOG.log(DEBUG_LOAD_LEVEL, "Looking for library '" + libraryName + "'");
155155

156156
List<Throwable> exceptions = new ArrayList<Throwable>();
@@ -242,30 +242,17 @@ else if (Platform.isLinux() || Platform.isFreeBSD()) {
242242
}
243243
// Search framework libraries on OS X
244244
else if (Platform.isMac() && !libraryName.endsWith(".dylib")) {
245-
if (System.getProperty("os.version").compareTo("10.16") >= 0) {
245+
for(String frameworkName : matchFramework(libraryName)) {
246246
try {
247-
LOG.log(DEBUG_LOAD_LEVEL, "Trying " + libraryName);
248-
handle = Native.open(libraryName, openFlags);
247+
LOG.log(DEBUG_LOAD_LEVEL, "Trying " + frameworkName);
248+
handle = Native.open(frameworkName, openFlags);
249+
break;
249250
}
250251
catch(UnsatisfiedLinkError e2) {
251252
LOG.log(DEBUG_LOAD_LEVEL, "Loading failed with message: " + e2.getMessage());
252253
exceptions.add(e2);
253254
}
254255
}
255-
else {
256-
LOG.log(DEBUG_LOAD_LEVEL, "Looking for matching frameworks");
257-
libraryPath = matchFramework(libraryName);
258-
if (libraryPath != null) {
259-
try {
260-
LOG.log(DEBUG_LOAD_LEVEL, "Trying " + libraryPath);
261-
handle = Native.open(libraryPath, openFlags);
262-
}
263-
catch(UnsatisfiedLinkError e2) {
264-
LOG.log(DEBUG_LOAD_LEVEL, "Loading failed with message: " + e2.getMessage());
265-
exceptions.add(e2);
266-
}
267-
}
268-
}
269256
}
270257
// Try the same library with a "lib" prefix
271258
else if (Platform.isWindows() && !isAbsolutePath) {
@@ -351,30 +338,37 @@ private static void addSuppressedReflected(Throwable target, Throwable suppresse
351338
}
352339

353340
/** Look for a matching framework (OSX) */
354-
static String matchFramework(String libraryName) {
341+
static String[] matchFramework(String libraryName) {
342+
Set<String> paths = new LinkedHashSet<String>();
355343
File framework = new File(libraryName);
356344
if (framework.isAbsolute()) {
357-
if (libraryName.indexOf(".framework") != -1
358-
&& framework.exists()) {
359-
return framework.getAbsolutePath();
345+
if (libraryName.contains(".framework")) {
346+
if (framework.exists()) {
347+
return new String[]{framework.getAbsolutePath()};
348+
}
349+
paths.add(framework.getAbsolutePath());
360350
}
361-
framework = new File(new File(framework.getParentFile(), framework.getName() + ".framework"), framework.getName());
362-
if (framework.exists()) {
363-
return framework.getAbsolutePath();
351+
else {
352+
framework = new File(new File(framework.getParentFile(), framework.getName() + ".framework"), framework.getName());
353+
if (framework.exists()) {
354+
return new String[]{framework.getAbsolutePath()};
355+
}
356+
paths.add(framework.getAbsolutePath());
364357
}
365358
}
366359
else {
367360
final String[] PREFIXES = { System.getProperty("user.home"), "", "/System" };
368-
String suffix = libraryName.indexOf(".framework") == -1
369-
? libraryName + ".framework/" + libraryName : libraryName;
370-
for (int i=0;i < PREFIXES.length;i++) {
371-
String libraryPath = PREFIXES[i] + "/Library/Frameworks/" + suffix;
372-
if (new File(libraryPath).exists()) {
373-
return libraryPath;
361+
String suffix = !libraryName.contains(".framework")
362+
? libraryName + ".framework/" + libraryName : libraryName;
363+
for (String prefix : PREFIXES) {
364+
framework = new File(prefix + "/Library/Frameworks/" + suffix);
365+
if (framework.exists()) {
366+
return new String[]{framework.getAbsolutePath()};
374367
}
368+
paths.add(framework.getAbsolutePath());
375369
}
376370
}
377-
return null;
371+
return paths.toArray(new String[0]);
378372
}
379373

380374
private String getLibraryName(String libraryName) {

test/com/sun/jna/NativeLibraryTest.java

+69-14
Original file line numberDiff line numberDiff line change
@@ -247,26 +247,81 @@ public void testGetProcess() {
247247
process.getFunction("printf");
248248
}
249249

250-
private String expected(String f) {
251-
return new File(f).exists() ? f : null;
250+
public void testLoadFoundationFramework() {
251+
if (!Platform.isMac()) {
252+
return;
253+
}
254+
assertNotNull(NativeLibrary.getInstance("Foundation"));
252255
}
253256

254-
public void testMatchFramework() {
257+
public void testMatchSystemFramework() {
255258
if (!Platform.isMac()) {
256259
return;
257260
}
258-
final String[][] MAPPINGS = {
259-
// Depending on the system, /Library/Frameworks may or may not
260-
// have anything in it.
261-
{ "QtCore", expected("/Library/Frameworks/QtCore.framework/QtCore") },
262-
{ "Adobe AIR", expected("/Library/Frameworks/Adobe AIR.framework/Adobe AIR") },
263-
264-
{ "QuickTime", expected("/System/Library/Frameworks/QuickTime.framework/QuickTime") },
265-
{ "QuickTime.framework/Versions/Current/QuickTime", expected("/System/Library/Frameworks/QuickTime.framework/Versions/Current/QuickTime") },
266-
};
267-
for (int i=0;i < MAPPINGS.length;i++) {
268-
assertEquals("Wrong framework mapping", MAPPINGS[i][1], NativeLibrary.matchFramework(MAPPINGS[i][0]));
261+
262+
assertEquals("Wrong framework mapping", 1,
263+
NativeLibrary.matchFramework("/System/Library/Frameworks/Foundation.framework/Foundation").length);
264+
assertEquals("Wrong framework mapping", "/System/Library/Frameworks/Foundation.framework/Foundation",
265+
NativeLibrary.matchFramework("/System/Library/Frameworks/Foundation.framework/Foundation")[0]);
266+
267+
assertEquals("Wrong framework mapping", 1,
268+
NativeLibrary.matchFramework("/System/Library/Frameworks/Foundation").length);
269+
assertEquals("Wrong framework mapping", "/System/Library/Frameworks/Foundation.framework/Foundation",
270+
NativeLibrary.matchFramework("/System/Library/Frameworks/Foundation")[0]);
271+
}
272+
273+
public void testMatchOptionalFrameworkExists() {
274+
if (!Platform.isMac()) {
275+
return;
276+
}
277+
278+
if(!new File("/System/Library/Frameworks/QuickTime.framework").exists()) {
279+
return;
280+
}
281+
282+
assertEquals("Wrong framework mapping", 1,
283+
NativeLibrary.matchFramework("QuickTime").length);
284+
assertEquals("Wrong framework mapping", "/System/Library/Frameworks/QuickTime.framework/QuickTime",
285+
NativeLibrary.matchFramework("QuickTime")[0]);
286+
287+
assertEquals("Wrong framework mapping", 1,
288+
NativeLibrary.matchFramework("QuickTime.framework/Versions/Current/QuickTime").length);
289+
assertEquals("Wrong framework mapping", "/System/Library/Frameworks/QuickTime.framework/Versions/Current/QuickTime",
290+
NativeLibrary.matchFramework("QuickTime.framework/Versions/Current/QuickTime")[0]);
291+
}
292+
293+
public void testMatchOptionalFrameworkNotFound() {
294+
if (!Platform.isMac()) {
295+
return;
269296
}
297+
298+
if(new File(System.getProperty("user.home") + "/Library/Frameworks/QuickTime.framework").exists()) {
299+
return;
300+
}
301+
if(new File("/Library/Frameworks/QuickTime.framework").exists()) {
302+
return;
303+
}
304+
if(new File("/System/Library/Frameworks/QuickTime.framework").exists()) {
305+
return;
306+
}
307+
308+
assertEquals("Wrong framework mapping", 3,
309+
NativeLibrary.matchFramework("QuickTime").length);
310+
assertEquals("Wrong framework mapping", System.getProperty("user.home") + "/Library/Frameworks/QuickTime.framework/QuickTime",
311+
NativeLibrary.matchFramework("QuickTime")[0]);
312+
assertEquals("Wrong framework mapping", "/Library/Frameworks/QuickTime.framework/QuickTime",
313+
NativeLibrary.matchFramework("QuickTime")[1]);
314+
assertEquals("Wrong framework mapping", "/System/Library/Frameworks/QuickTime.framework/QuickTime",
315+
NativeLibrary.matchFramework("QuickTime")[2]);
316+
317+
assertEquals("Wrong framework mapping", 3,
318+
NativeLibrary.matchFramework("QuickTime.framework/Versions/Current/QuickTime").length);
319+
assertEquals("Wrong framework mapping", System.getProperty("user.home") + "/Library/Frameworks/QuickTime.framework/Versions/Current/QuickTime",
320+
NativeLibrary.matchFramework("QuickTime.framework/Versions/Current/QuickTime")[0]);
321+
assertEquals("Wrong framework mapping", "/Library/Frameworks/QuickTime.framework/Versions/Current/QuickTime",
322+
NativeLibrary.matchFramework("QuickTime.framework/Versions/Current/QuickTime")[1]);
323+
assertEquals("Wrong framework mapping", "/System/Library/Frameworks/QuickTime.framework/Versions/Current/QuickTime",
324+
NativeLibrary.matchFramework("QuickTime.framework/Versions/Current/QuickTime")[2]);
270325
}
271326

272327
public void testLoadLibraryWithOptions() {

0 commit comments

Comments
 (0)