-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Try all frameworks paths regardless of file exist check. #1216
Conversation
Could you please have a look at the result of the CI build? https://travis-ci.org/github/java-native-access/jna/jobs/702961796 The change introduces unittest failures. |
(not the OP but took a look at their commit) It looks like the failing test is essentially using comparing
Previously, this made sense since the By definition, this won't work anymore with this new change's strategy - per the Apple release note, system-provided libraries won't necessarily exist anymore, yet they will be magically available if you dlopen() them. In other words, unless there is a reason not to try to |
It seems the logic here tries to solve all problems at once, but probably handles more cases than it should.
It still does make sense and works for 10.x. Switching on |
So, I may be missing something obvious here, but one question: this new behavior on macOS 11.x is for "system-provided" libraries. Previously, we poked around and attempted to find them directly on the file system. Now, they magically come back if you ask for them, presumably by just their name, not with a fake path? What if, when E.g., instead of changing the logic to try all framework paths regardless of file presence, instead just do a "blind" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more comments on the code, but I think we still have an open discussion on the overall logic.
}; | ||
for (int i=0;i < MAPPINGS.length;i++) { | ||
assertEquals("Wrong framework mapping", MAPPINGS[i][1], NativeLibrary.matchFramework(MAPPINGS[i][0])); | ||
if (!System.getProperty("os.version").startsWith("10")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can probably simplify by including this in the previous conditional. Also for the comment rather than "10.11" should say either "macOS 11" or "11.x".
src/com/sun/jna/NativeLibrary.java
Outdated
libraryPath = matchFramework(libraryName); | ||
if (libraryPath != null) { | ||
for(String frameworkName : matchFramework(libraryName)) { | ||
libraryName = frameworkName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm missing why this assignment is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm missing why this assignment is needed.
In fact, this causes a problem for the later attempt to find a library in an embedded jar. By assigning the various attempts to libraryPath (e.g., mutating that variable) we end up trying to find an embedded jar in ${os-prefix}/libraryPath
with whatever the last "guess" value was for libraryPath.
Removing that assignment and instead passing frameworkName to the Native.open(frameworkName, openFlags)
call fixes this issue by not mangling libraryPath for the later attempt to open from the JAR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that change was backed out from the final commit. Here's the actual changes.
src/com/sun/jna/NativeLibrary.java
Outdated
} | ||
} | ||
return null; | ||
return paths.toArray(new String[paths.size()]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor point: the [0]
version of toArray
is slightly more efficient, and we went through and changed them all back in #1060 so best to be consistent here.
} | ||
// Depending on the system, /Library/Frameworks may or may not have anything in it. | ||
assertEquals("Wrong framework mapping", "/Library/Frameworks/QtCore.framework/QtCore", | ||
NativeLibrary.matchFramework("QtCore")[2]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not understanding why the array index 2 here and the next two entries, but 0 for QuickTime?
}; | ||
for (int i=0;i < MAPPINGS.length;i++) { | ||
assertEquals("Wrong framework mapping", MAPPINGS[i][1], NativeLibrary.matchFramework(MAPPINGS[i][0])); | ||
if (!System.getProperty("os.version").startsWith("10")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: System.getProperty("os.version")
currently returns 10.16
for developer beta 1. My understanding is this will eventually become 11.00
(or possibly 11.0
?) in a subsequent build, and may already be reporting that on the Apple DTK ARM build. But for the time being this check on just startsWith("10")
won't work on DP1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
System.getProperty("os.version").compareTo("10.15") > 0
should work.
(EDIT: or not, given I'm currently on 10.15.5. Comparing >= 10.16 should work!)
System.getProperty("os.version").compareTo("10.16") >= 0
should work.
Probably makes sense to simplify this way and only do the various path concatenation when running on earlier versions. Will do the |
Let me know if I should sqash the commits. |
Generally before merging, yes. For complex changes, I don't mind seeing individual commits during review so we can see what has changed in each commit. You can squash when you add a changelog entry. :-) |
This looks good to me. I'll leave it for anyone else to comment. |
Merged in 65085c1 |
Welp, I may have been trying to be too clever too quickly with my previous suggestion to @dkocher were you able to successfully access a native framework library, e.g. Carbon, with this version of code? dlopen() fails for me if I pass it simply When I build JNA using your first attempt that went through the previous logic of coming up with possible paths to try to open, but didn't do the file-exists-check, that did work, and allow me to invoke Carbon APIs as expected. Is my experience different from yours? Are you able to load a system framework with the currently-merged code in JNA? |
I mean to have this verified with loading |
I forgot to install the latest build into my local Maven repository and thus tested with a previous build :( I can confirm loading with Thus I propose to revert to a variant of my initial patch. |
… 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]>
I'll wait until @msm tests this latest version before merging again. Thanks for updating. |
I have tested the updated fix for loading frameworks on macOS 11. I am happy to report it is working now for both system frameworks and loading embedded libraries in jars. @dkocher Thanks for updating! @dbwiddis Would it be possible to work towards releasing a 5.6 or similar version in the near future? There are a few other projects that have issues reported against them that this would fix: gmethvin/directory-watcher#52 |
OK, I'll get this merged (again!). Regarding a 5.6.0 release, I suggest starting a thread on the mailing list. |
Changes to the latest beta version of macOS broke the mechanism that we're using to observe filesystem change events. It's more than just filesystem observation that has broken: any attempt to run a hot-reloading workflow crashes the Figwheel process with an uncaught exception at startup. (Note that build-once still works, since it doesn't try to access filesystem events). The underlying hawk library does have an implementation of a less-efficient polling watcher. Figwheel can use this to provide hot-reloading even when native events aren't available. This commit wraps the `hawk.core/watch!` function to catch any exception that's thrown, and re-try with the same options *except* that it explicitly starts a polling watcher. See also - gjoseph/BarbaryWatchService#13 - java-native-access/jna#1216 Part of bhauman#253.
@dkocher , @msm Would you be able to test the 5.6.0 snapshot on the macOS 11 beta? See the mailing list thread for links. |
Mac OS 11 (aka. "Big Sur") made some changes to the way that the Carbon library is located, causing JNA calls to fail. This has been fixed in JNA 5.6.0; see java-native-access/jna#1216 Since Barbary is implemented on JNA, this is causing downstream projects that rely on file watching to crash on JVM start when used on Mac OS 11. Examples: - bhauman/figwheel-main#253 - thheller/shadow-cljs#767
Fix #1215.
Signed-off-by: David Kocher [email protected]