Skip to content

Commit

Permalink
Changing Class<T> to Class<T extends Library> for Native.loadLibrary
Browse files Browse the repository at this point in the history
It was possible to pass a non-library class into this method and get a runtime exception, when the same check can be done at compile-time, so this fix changes it to be done at compile-time.

After erasure, with this change the return type changes from `Object` to `Library`. So as far as backwards compatibility:

1. If you were assigning the result to `Object`, that will still work
2. If you were passing something that wasn't a `Class<? extends Library>`, your code will now not compile, instead of failing at runtime.
3. I can't remember the rules for binary compatibility.

Fixes java-native-access#822.
  • Loading branch information
d-noll committed Sep 22, 2017
1 parent fddc668 commit a82505a
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 5 deletions.
9 changes: 5 additions & 4 deletions src/com/sun/jna/Native.java
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ public static List<String> toStringList(char[] buf, int offset, int len) {
* @throws UnsatisfiedLinkError if the library cannot be found or
* dependent libraries are missing.
*/
public static <T> T loadLibrary(Class<T> interfaceClass) {
public static <T extends Library> T loadLibrary(Class<T> interfaceClass) {
return loadLibrary(null, interfaceClass);
}

Expand All @@ -522,7 +522,7 @@ public static <T> T loadLibrary(Class<T> interfaceClass) {
* dependent libraries are missing.
* @see #loadLibrary(String, Class, Map)
*/
public static <T> T loadLibrary(Class<T> interfaceClass, Map<String, ?> options) {
public static <T extends Library> T loadLibrary(Class<T> interfaceClass, Map<String, ?> options) {
return loadLibrary(null, interfaceClass, options);
}

Expand All @@ -540,7 +540,7 @@ public static <T> T loadLibrary(Class<T> interfaceClass, Map<String, ?> options)
* dependent libraries are missing.
* @see #loadLibrary(String, Class, Map)
*/
public static <T> T loadLibrary(String name, Class<T> interfaceClass) {
public static <T extends Library> T loadLibrary(String name, Class<T> interfaceClass) {
return loadLibrary(name, interfaceClass, Collections.<String, Object>emptyMap());
}

Expand All @@ -560,8 +560,9 @@ public static <T> T loadLibrary(String name, Class<T> interfaceClass) {
* @throws UnsatisfiedLinkError if the library cannot be found or
* dependent libraries are missing.
*/
public static <T> T loadLibrary(String name, Class<T> interfaceClass, Map<String, ?> options) {
public static <T extends Library> T loadLibrary(String name, Class<T> interfaceClass, Map<String, ?> options) {
if (!Library.class.isAssignableFrom(interfaceClass)) {
// Maybe still possible if the caller is not using generics?
throw new IllegalArgumentException("Interface (" + interfaceClass.getSimpleName() + ")"
+ " of library=" + name + " does not extend " + Library.class.getSimpleName());
}
Expand Down
2 changes: 1 addition & 1 deletion test/com/sun/jna/NativeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void testLoadLibraryMethods() throws Exception {
Method m = Native.class.getMethod("loadLibrary", paramTypes);
Class<?> returnType = m.getReturnType();
signature.append(Native.getSignature(returnType));
assertSame("Mismatched return type for signature=" + signature, Object.class, returnType);
assertSame("Mismatched return type for signature=" + signature, Library.class, returnType);
// System.out.println("===>" + m.getName() + ": " + signature);
} catch(NoSuchMethodError err) {
fail("No method for signature=" + signature);
Expand Down

0 comments on commit a82505a

Please sign in to comment.