1 /* 2 * Copyright 2016 The Netty Project 3 * 4 * The Netty Project licenses this file to you under the Apache License, 5 * version 2.0 (the "License"); you may not use this file except in compliance 6 * with the License. You may obtain a copy of the License at: 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 /* 17 * Licensed to the Apache Software Foundation (ASF) under one or more 18 * contributor license agreements. See the NOTICE file distributed with 19 * this work for additional information regarding copyright ownership. 20 * The ASF licenses this file to You under the Apache License, Version 2.0 21 * (the "License"); you may not use this file except in compliance with 22 * the License. You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33 package io.netty.internal.tcnative; 34 35 import java.io.File; 36 37 public final class Library { 38 39 /* Default library names */ 40 private static final String [] NAMES = {"netty-tcnative", "libnetty-tcnative", "netty-tcnative-1", "libnetty-tcnative-1"}; 41 /* 42 * A handle to the unique Library singleton instance. 43 */ 44 private static Library _instance = null; 45 Library()46 private Library() throws Exception { 47 boolean loaded = false; 48 String path = System.getProperty("java.library.path"); 49 String [] paths = path.split(File.pathSeparator); 50 StringBuilder err = new StringBuilder(); 51 for (int i = 0; i < NAMES.length; i++) { 52 try { 53 System.loadLibrary(NAMES[i]); 54 loaded = true; 55 } catch (ThreadDeath t) { 56 throw t; 57 } catch (VirtualMachineError t) { 58 throw t; 59 } catch (Throwable t) { 60 String name = System.mapLibraryName(NAMES[i]); 61 for (int j = 0; j < paths.length; j++) { 62 File fd = new File(paths[j] , name); 63 if (fd.exists()) { 64 // File exists but failed to load 65 throw new RuntimeException(t); 66 } 67 } 68 if (i > 0) { 69 err.append(", "); 70 } 71 err.append(t.getMessage()); 72 } 73 if (loaded) { 74 break; 75 } 76 } 77 if (!loaded) { 78 throw new UnsatisfiedLinkError(err.toString()); 79 } 80 } 81 Library(String libraryName)82 private Library(String libraryName) 83 { 84 if (!"provided".equals(libraryName)) { 85 System.loadLibrary(libraryName); 86 } 87 } 88 89 /* create global TCN's APR pool 90 * This has to be the first call to TCN library. 91 */ initialize0()92 private static native boolean initialize0(); 93 94 /* Internal function for loading APR Features */ has(int what)95 private static native boolean has(int what); 96 /* Internal function for loading APR Features */ version(int what)97 private static native int version(int what); 98 99 /* APR_VERSION_STRING */ aprVersionString()100 private static native String aprVersionString(); 101 102 /** 103 * Calls {@link #initialize(String, String)} with {@code "provided"} and {@code null}. 104 * 105 * @return {@code true} if initialization was successful 106 * @throws Exception if an error happens during initialization 107 */ initialize()108 public static boolean initialize() throws Exception { 109 return initialize("provided", null); 110 } 111 112 /** 113 * Setup native library. This is the first method that must be called! 114 * 115 * @param libraryName the name of the library to load 116 * @param engine Support for external a Crypto Device ("engine"), usually 117 * @return {@code true} if initialization was successful 118 * @throws Exception if an error happens during initialization 119 */ initialize(String libraryName, String engine)120 public static boolean initialize(String libraryName, String engine) throws Exception { 121 if (_instance == null) { 122 if (libraryName == null) 123 _instance = new Library(); 124 else 125 _instance = new Library(libraryName); 126 int aprMajor = version(0x11); 127 128 if (aprMajor < 1) { 129 throw new UnsatisfiedLinkError("Unsupported APR Version (" + 130 aprVersionString() + ")"); 131 } 132 133 boolean aprHasThreads = has(2); 134 if (!aprHasThreads) { 135 throw new UnsatisfiedLinkError("Missing APR_HAS_THREADS"); 136 } 137 } 138 return initialize0() && SSL.initialize(engine) == 0; 139 } 140 } 141