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 <[email protected]> Authored: Tue Jul 5 23:29:26 2016 +0100 Committer: Sebb <[email protected]> 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); + } + } + } +}
