1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.jboss.netty.util.internal;
18
19 import org.jboss.netty.logging.InternalLogger;
20 import org.jboss.netty.logging.InternalLoggerFactory;
21
22 import java.io.File;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.net.URL;
28 import java.util.Locale;
29
30
31
32
33
34 public final class NativeLibraryLoader {
35
36 private static final InternalLogger logger = InternalLoggerFactory.getInstance(NativeLibraryLoader.class);
37
38 private static final String NATIVE_RESOURCE_HOME = "META-INF/native/";
39 private static final String OSNAME;
40 private static final File WORKDIR;
41
42 static {
43 OSNAME = SystemPropertyUtil.get("os.name", "").toLowerCase(Locale.US).replaceAll("[^a-z0-9]+", "");
44
45 String workdir = SystemPropertyUtil.get("io.netty.native.workdir");
46 if (workdir != null) {
47 File f = new File(workdir);
48 if (!f.exists()) {
49
50
51 f.mkdirs();
52 }
53
54 try {
55 f = f.getAbsoluteFile();
56 } catch (Exception ignored) {
57
58 }
59
60 WORKDIR = f;
61 logger.debug("-Dio.netty.netty.workdir: " + WORKDIR);
62 } else {
63 WORKDIR = tmpdir();
64 logger.debug("-Dio.netty.netty.workdir: " + WORKDIR + " (io.netty.tmpdir)");
65 }
66 }
67
68 private static File tmpdir() {
69 File f;
70 try {
71 f = toDirectory(SystemPropertyUtil.get("io.netty.tmpdir"));
72 if (f != null) {
73 logger.debug("-Dio.netty.tmpdir: " + f);
74 return f;
75 }
76
77 f = toDirectory(SystemPropertyUtil.get("java.io.tmpdir"));
78 if (f != null) {
79 logger.debug("-Dio.netty.tmpdir: " + f + " (java.io.tmpdir)");
80 return f;
81 }
82
83
84 if (isWindows()) {
85 f = toDirectory(System.getenv("TEMP"));
86 if (f != null) {
87 logger.debug("-Dio.netty.tmpdir: " + f + " (%TEMP%)");
88 return f;
89 }
90
91 String userprofile = System.getenv("USERPROFILE");
92 if (userprofile != null) {
93 f = toDirectory(userprofile + "\\AppData\\Local\\Temp");
94 if (f != null) {
95 logger.debug("-Dio.netty.tmpdir: " + f + " (%USERPROFILE%\\AppData\\Local\\Temp)");
96 return f;
97 }
98
99 f = toDirectory(userprofile + "\\Local Settings\\Temp");
100 if (f != null) {
101 logger.debug("-Dio.netty.tmpdir: " + f + " (%USERPROFILE%\\Local Settings\\Temp)");
102 return f;
103 }
104 }
105 } else {
106 f = toDirectory(System.getenv("TMPDIR"));
107 if (f != null) {
108 logger.debug("-Dio.netty.tmpdir: " + f + " ($TMPDIR)");
109 return f;
110 }
111 }
112 } catch (Exception ignored) {
113
114 }
115
116
117 if (isWindows()) {
118 f = new File("C:\\Windows\\Temp");
119 } else {
120 f = new File("/tmp");
121 }
122
123 logger.warn("Failed to get the temporary directory; falling back to: " + f);
124 return f;
125 }
126
127 @SuppressWarnings("ResultOfMethodCallIgnored")
128 private static File toDirectory(String path) {
129 if (path == null) {
130 return null;
131 }
132
133 File f = new File(path);
134 if (!f.exists()) {
135 f.mkdirs();
136 }
137
138 if (!f.isDirectory()) {
139 return null;
140 }
141
142 try {
143 return f.getAbsoluteFile();
144 } catch (Exception ignored) {
145 return f;
146 }
147 }
148
149 private static boolean isWindows() {
150 return OSNAME.startsWith("windows");
151 }
152
153 private static boolean isOSX() {
154 return OSNAME.startsWith("macosx") || OSNAME.startsWith("osx");
155 }
156
157
158
159
160 public static void load(String name, ClassLoader loader) {
161 String libname = System.mapLibraryName(name);
162 String path = NATIVE_RESOURCE_HOME + libname;
163
164 URL url = loader.getResource(path);
165 if (url == null && isOSX()) {
166 if (path.endsWith(".jnilib")) {
167 url = loader.getResource(NATIVE_RESOURCE_HOME + "lib" + name + ".dynlib");
168 } else {
169 url = loader.getResource(NATIVE_RESOURCE_HOME + "lib" + name + ".jnilib");
170 }
171 }
172
173 if (url == null) {
174
175 System.loadLibrary(name);
176 return;
177 }
178
179 int index = libname.lastIndexOf('.');
180 String prefix = libname.substring(0, index);
181 String suffix = libname.substring(index, libname.length());
182 InputStream in = null;
183 OutputStream out = null;
184 File tmpFile = null;
185 boolean loaded = false;
186 try {
187 tmpFile = File.createTempFile(prefix, suffix, WORKDIR);
188 in = url.openStream();
189 out = new FileOutputStream(tmpFile);
190
191 byte[] buffer = new byte[8192];
192 int length;
193 while ((length = in.read(buffer)) > 0) {
194 out.write(buffer, 0, length);
195 }
196 out.flush();
197 out.close();
198 out = null;
199
200 System.load(tmpFile.getPath());
201 loaded = true;
202 } catch (Exception e) {
203 throw (UnsatisfiedLinkError) new UnsatisfiedLinkError(
204 "could not load a native library: " + name).initCause(e);
205 } finally {
206 if (in != null) {
207 try {
208 in.close();
209 } catch (IOException ignore) {
210
211 }
212 }
213 if (out != null) {
214 try {
215 out.close();
216 } catch (IOException ignore) {
217
218 }
219 }
220 if (tmpFile != null) {
221 if (loaded) {
222 tmpFile.deleteOnExit();
223 } else {
224 if (!tmpFile.delete()) {
225 tmpFile.deleteOnExit();
226 }
227 }
228 }
229 }
230 }
231
232 private NativeLibraryLoader() {
233
234 }
235 }