You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2016/07/05 22:29:29 UTC

commons-crypto git commit: CRYPTO-107 NativeCodeLoader fails to handle UnsatisfiedLinkError

Repository: commons-crypto
Updated Branches:
  refs/heads/master 652b62a2f -> b1d66b82a


CRYPTO-107 NativeCodeLoader fails to handle UnsatisfiedLinkError

Catch UnsatisfiedLinkError
Save the cause on loading error
Add unit tests

Project: http://git-wip-us.apache.org/repos/asf/commons-crypto/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-crypto/commit/b1d66b82
Tree: http://git-wip-us.apache.org/repos/asf/commons-crypto/tree/b1d66b82
Diff: http://git-wip-us.apache.org/repos/asf/commons-crypto/diff/b1d66b82

Branch: refs/heads/master
Commit: b1d66b82a70f6ec68ae0604e64664c698c967fa5
Parents: 652b62a
Author: Sebb <se...@apache.org>
Authored: Tue Jul 5 23:29:26 2016 +0100
Committer: Sebb <se...@apache.org>
Committed: Tue Jul 5 23:29:26 2016 +0100

----------------------------------------------------------------------
 .../java/org/apache/commons/crypto/Crypto.java  |  8 ++
 .../apache/commons/crypto/NativeCodeLoader.java | 34 +++++++--
 .../commons/crypto/NativeCodeLoaderTest.java    | 78 ++++++++++++++++++++
 3 files changed, 112 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/b1d66b82/src/main/java/org/apache/commons/crypto/Crypto.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/Crypto.java b/src/main/java/org/apache/commons/crypto/Crypto.java
index 4fb455e..85e2186 100644
--- a/src/main/java/org/apache/commons/crypto/Crypto.java
+++ b/src/main/java/org/apache/commons/crypto/Crypto.java
@@ -63,4 +63,12 @@ public final class Crypto {
         return NativeCodeLoader.isNativeCodeLoaded();
     }
 
+    /**
+     * The loading error throwable, if loading failed.
+     * 
+     * @return null, unless loading failed.
+     */
+    public static Throwable getLoadingError() {
+        return NativeCodeLoader.getLoadingError();
+    }
 }

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/b1d66b82/src/main/java/org/apache/commons/crypto/NativeCodeLoader.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/NativeCodeLoader.java b/src/main/java/org/apache/commons/crypto/NativeCodeLoader.java
index fa7c436..ec96a4e 100644
--- a/src/main/java/org/apache/commons/crypto/NativeCodeLoader.java
+++ b/src/main/java/org/apache/commons/crypto/NativeCodeLoader.java
@@ -39,6 +39,8 @@ final class NativeCodeLoader {
 
     private final static boolean nativeCodeLoaded;
 
+    private static final Throwable loadingError;
+
     /**
      * The private constructor of {@link NativeCodeLoader}.
      */
@@ -46,10 +48,17 @@ final class NativeCodeLoader {
     }
 
     static {
-        // Try to load native library and set fallback flag appropriately
-        boolean nativeLoaded = false;
+        loadingError = loadLibrary(); // will be null if loaded OK
+
+        nativeCodeLoaded = loadingError == null;
+    }
 
-        //Trying to load the custom-built native-commons-crypto library...");
+    /**
+     * Loads the library if possible.
+     * 
+     * @return null if successrul, otherwise the Throwable that was caught
+     */
+    static Throwable loadLibrary() {
         try {
             File nativeLibFile = findNativeLibrary();
             if (nativeLibFile != null) {
@@ -59,12 +68,12 @@ final class NativeCodeLoader {
                 // Load preinstalled library (in the path -Djava.library.path)
                 System.loadLibrary("commons-crypto");
             }
-            // Loaded the native library
-            nativeLoaded = true;
-        } catch (Exception t) {  // NOPMD: Ignore failure to load
+            return null; // OK
+        } catch (Exception t) {
+            return t;
+        } catch (UnsatisfiedLinkError t) {
+            return t;
         }
-
-        nativeCodeLoaded = nativeLoaded;
     }
 
     /**
@@ -277,4 +286,13 @@ final class NativeCodeLoader {
     static boolean isNativeCodeLoaded() {
         return nativeCodeLoaded;
     }
+
+    /**
+     * Gets the error cause if loading failed.
+     * 
+     * @return null, unless loading failed
+     */
+    static Throwable getLoadingError() {
+        return loadingError;
+    }
 }

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/b1d66b82/src/test/java/org/apache/commons/crypto/NativeCodeLoaderTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/NativeCodeLoaderTest.java b/src/test/java/org/apache/commons/crypto/NativeCodeLoaderTest.java
new file mode 100644
index 0000000..6ed876b
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/NativeCodeLoaderTest.java
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.crypto;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.junit.Assume;
+import org.junit.Test;
+
+public class NativeCodeLoaderTest {
+
+    @Test
+    public void testGetVersion() {
+        assertNotNull(NativeCodeLoader.getVersion());
+    }
+
+    @Test
+    public void testNativePresent() {
+        Assume.assumeTrue(NativeCodeLoader.isNativeCodeLoaded());
+        assertNull(NativeCodeLoader.getLoadingError());
+    }
+
+    @Test
+    public void testNativeNotPresent() {
+        Assume.assumeTrue(!NativeCodeLoader.isNativeCodeLoaded());
+        assertNotNull(NativeCodeLoader.getLoadingError());
+    }
+
+    @Test
+    public void testCanLoadIfPresent() {
+        Assume.assumeTrue(NativeCodeLoader.isNativeCodeLoaded());
+        // This will try to reload the library, so should work
+        assertNull(NativeCodeLoader.loadLibrary());
+    }
+
+    @Test
+    public void testUnSuccessfulLoad() throws Exception {
+        final String nameKey = System.getProperty(Crypto.LIB_NAME_KEY);
+        final String pathKey = System.getProperty(Crypto.LIB_PATH_KEY);
+        // An empty file should cause UnsatisfiedLinkError
+        File empty = File.createTempFile("NativeCodeLoaderTest", "tmp");
+        try {
+            System.setProperty(Crypto.LIB_PATH_KEY, empty.getParent());
+            System.setProperty(Crypto.LIB_NAME_KEY, empty.getName());
+            final Throwable result = NativeCodeLoader.loadLibrary();
+            assertNotNull(result);
+            assertTrue(result instanceof UnsatisfiedLinkError);
+        } finally {
+            empty.delete();
+            if (nameKey != null) {
+                System.setProperty(Crypto.LIB_NAME_KEY, nameKey);
+            }
+            if (pathKey != null) {
+                System.setProperty(Crypto.LIB_PATH_KEY, pathKey);
+            }
+        }
+    }
+}