• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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