PageRenderTime 53ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/java/org/jboss/modules/NativeLibraryResourceLoader.java

https://github.com/ALRubinger/jboss-modules
Java | 325 lines | 257 code | 18 blank | 50 comment | 148 complexity | 3f113a9c5c1e422b7c51f6979e103e65 MD5 | raw file
  1. /*
  2. * JBoss, Home of Professional Open Source.
  3. * Copyright 2014 Red Hat, Inc., and individual contributors
  4. * as indicated by the @author tags.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.jboss.modules;
  19. import java.io.File;
  20. import java.net.URI;
  21. import java.security.AccessController;
  22. import java.security.PrivilegedAction;
  23. import java.util.ArrayList;
  24. import java.util.Locale;
  25. /**
  26. * A base class for resource loaders which can load native libraries.
  27. *
  28. * @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
  29. */
  30. public class NativeLibraryResourceLoader extends AbstractResourceLoader {
  31. /**
  32. * Separate class for native platform ID which is only loaded when native libs are loaded.
  33. */
  34. static class Identification {
  35. static final String OS_ID;
  36. static final String CPU_ID;
  37. static final String ARCH_NAME;
  38. static final String[] NATIVE_SEARCH_PATHS;
  39. static {
  40. final Object[] strings = AccessController.doPrivileged(new PrivilegedAction<Object[]>() {
  41. public Object[] run() {
  42. // First, identify the operating system.
  43. boolean knownOs = true;
  44. String osName;
  45. // let the user override it.
  46. osName = System.getProperty("jboss.modules.os-name");
  47. if (osName == null) {
  48. String sysOs = System.getProperty("os.name");
  49. if (sysOs == null) {
  50. osName = "unknown";
  51. knownOs = false;
  52. } else {
  53. sysOs = sysOs.toUpperCase(Locale.US);
  54. if (sysOs.startsWith("LINUX")) {
  55. osName = "linux";
  56. } else if (sysOs.startsWith("MAC OS")) {
  57. osName = "macosx";
  58. } else if (sysOs.startsWith("WINDOWS")) {
  59. osName = "win";
  60. } else if (sysOs.startsWith("OS/2")) {
  61. osName = "os2";
  62. } else if (sysOs.startsWith("SOLARIS") || sysOs.startsWith("SUNOS")) {
  63. osName = "solaris";
  64. } else if (sysOs.startsWith("MPE/IX")) {
  65. osName = "mpeix";
  66. } else if (sysOs.startsWith("HP-UX")) {
  67. osName = "hpux";
  68. } else if (sysOs.startsWith("AIX")) {
  69. osName = "aix";
  70. } else if (sysOs.startsWith("OS/390")) {
  71. osName = "os390";
  72. } else if (sysOs.startsWith("OS/400")) {
  73. osName = "os400";
  74. } else if (sysOs.startsWith("FREEBSD")) {
  75. osName = "freebsd";
  76. } else if (sysOs.startsWith("OPENBSD")) {
  77. osName = "openbsd";
  78. } else if (sysOs.startsWith("NETBSD")) {
  79. osName = "netbsd";
  80. } else if (sysOs.startsWith("IRIX")) {
  81. osName = "irix";
  82. } else if (sysOs.startsWith("DIGITAL UNIX")) {
  83. osName = "digitalunix";
  84. } else if (sysOs.startsWith("OSF1")) {
  85. osName = "osf1";
  86. } else if (sysOs.startsWith("OPENVMS")) {
  87. osName = "openvms";
  88. } else if (sysOs.startsWith("IOS")) {
  89. osName = "iOS";
  90. } else {
  91. osName = "unknown";
  92. knownOs = false;
  93. }
  94. }
  95. }
  96. // Next, our CPU ID and its compatible variants.
  97. boolean knownCpu = true;
  98. ArrayList<String> cpuNames = new ArrayList<>();
  99. String cpuName = System.getProperty("jboss.modules.cpu-name");
  100. if (cpuName == null) {
  101. String sysArch = System.getProperty("os.arch");
  102. if (sysArch == null) {
  103. cpuName = "unknown";
  104. knownCpu = false;
  105. } else {
  106. boolean hasEndian = false;
  107. boolean hasHardFloatABI = false;
  108. sysArch = sysArch.toUpperCase(Locale.US);
  109. if (sysArch.startsWith("SPARCV9") || sysArch.startsWith("SPARC64")) {
  110. cpuName = "sparcv9";
  111. } else if (sysArch.startsWith("SPARC")) {
  112. cpuName = "sparc";
  113. } else if (sysArch.startsWith("X86_64") || sysArch.startsWith("AMD64")) {
  114. cpuName = "x86_64";
  115. } else if (sysArch.startsWith("I386")) {
  116. cpuName = "i386";
  117. } else if (sysArch.startsWith("I486")) {
  118. cpuName = "i486";
  119. } else if (sysArch.startsWith("I586")) {
  120. cpuName = "i586";
  121. } else if (sysArch.startsWith("I686") || sysArch.startsWith("X86") || sysArch.contains("IA32")) {
  122. cpuName = "i686";
  123. } else if (sysArch.startsWith("X32")) {
  124. cpuName = "x32";
  125. } else if (sysArch.startsWith("PPC64")) {
  126. cpuName = "ppc64";
  127. } else if (sysArch.startsWith("PPC") || sysArch.startsWith("POWER")) {
  128. cpuName = "ppc";
  129. } else if (sysArch.startsWith("ARMV7A") || sysArch.contains("AARCH32")) {
  130. hasEndian = true;
  131. hasHardFloatABI = true;
  132. cpuName = "armv7a";
  133. } else if (sysArch.startsWith("AARCH64") || sysArch.startsWith("ARM64") || sysArch.startsWith("ARMV8") || sysArch.startsWith("PXA9") || sysArch.startsWith("PXA10")) {
  134. hasEndian = true;
  135. cpuName = "aarch64";
  136. } else if (sysArch.startsWith("PXA27")) {
  137. hasEndian = true;
  138. cpuName = "armv5t-iwmmx";
  139. } else if (sysArch.startsWith("PXA3")) {
  140. hasEndian = true;
  141. cpuName = "armv5t-iwmmx2";
  142. } else if (sysArch.startsWith("ARMV4T") || sysArch.startsWith("EP93")) {
  143. hasEndian = true;
  144. cpuName = "armv4t";
  145. } else if (sysArch.startsWith("ARMV4") || sysArch.startsWith("EP73")) {
  146. hasEndian = true;
  147. cpuName = "armv4";
  148. } else if (sysArch.startsWith("ARMV5T") || sysArch.startsWith("PXA") || sysArch.startsWith("IXC") || sysArch.startsWith("IOP") || sysArch.startsWith("IXP") || sysArch.startsWith("CE")) {
  149. hasEndian = true;
  150. String isaList = System.getProperty("sun.arch.isalist");
  151. if (isaList != null) {
  152. if (isaList.toUpperCase(Locale.US).contains("MMX2")) {
  153. cpuName = "armv5t-iwmmx2";
  154. } else if (isaList.toUpperCase(Locale.US).contains("MMX")) {
  155. cpuName = "armv5t-iwmmx";
  156. } else {
  157. cpuName = "armv5t";
  158. }
  159. } else {
  160. cpuName = "armv5t";
  161. }
  162. } else if (sysArch.startsWith("ARMV5")) {
  163. hasEndian = true;
  164. cpuName = "armv5";
  165. } else if (sysArch.startsWith("ARMV6")) {
  166. hasEndian = true;
  167. hasHardFloatABI = true;
  168. cpuName = "armv6";
  169. } else if (sysArch.startsWith("PA_RISC2.0W")) {
  170. cpuName = "parisc64";
  171. } else if (sysArch.startsWith("PA_RISC") || sysArch.startsWith("PA-RISC")) {
  172. cpuName = "parisc";
  173. } else if (sysArch.startsWith("IA64")) {
  174. // HP-UX reports IA64W for 64-bit Itanium and IA64N when running
  175. // in 32-bit mode.
  176. cpuName = sysArch.toLowerCase(Locale.US);
  177. } else if (sysArch.startsWith("ALPHA")) {
  178. cpuName = "alpha";
  179. } else if (sysArch.startsWith("MIPS")) {
  180. cpuName = "mips";
  181. } else {
  182. knownCpu = false;
  183. cpuName = "unknown";
  184. }
  185. boolean be = false;
  186. boolean hf = false;
  187. if (knownCpu && hasEndian && "big".equals(System.getProperty("sun.cpu.endian", "little"))) {
  188. be = true;
  189. }
  190. if (knownCpu && hasHardFloatABI) {
  191. String archAbi = System.getProperty("sun.arch.abi");
  192. if (archAbi != null) {
  193. if (archAbi.toUpperCase(Locale.US).contains("HF")) {
  194. hf = true;
  195. }
  196. } else {
  197. String libPath = System.getProperty("java.library.path");
  198. if (libPath != null && libPath.toUpperCase(Locale.US).contains("GNUEABIHF")) {
  199. hf = true;
  200. }
  201. }
  202. if (hf) cpuName += "-hf";
  203. }
  204. if (knownCpu) {
  205. switch (cpuName) {
  206. case "i686": cpuNames.add("i686");
  207. case "i586": cpuNames.add("i586");
  208. case "i486": cpuNames.add("i486");
  209. case "i386": cpuNames.add("i386");
  210. break;
  211. case "armv7a": cpuNames.add("armv7a"); if (hf) break;
  212. case "armv6": cpuNames.add("armv6"); if (hf) break;
  213. case "armv5t": cpuNames.add("armv5t");
  214. case "armv5": cpuNames.add("armv5");
  215. case "armv4t": cpuNames.add("armv4t");
  216. case "armv4": cpuNames.add("armv4");
  217. break;
  218. case "armv5t-iwmmx2": cpuNames.add("armv5t-iwmmx2");
  219. case "armv5t-iwmmx": cpuNames.add("armv5t-iwmmx");
  220. cpuNames.add("armv5t");
  221. cpuNames.add("armv5");
  222. cpuNames.add("armv4t");
  223. cpuNames.add("armv4");
  224. break;
  225. default: cpuNames.add(cpuName);
  226. break;
  227. }
  228. if (hf || be) for (int i = 0; i < cpuNames.size(); i++) {
  229. String name = cpuNames.get(i);
  230. if (be) name += "-be";
  231. if (hf) name += "-hf";
  232. cpuNames.set(i, name);
  233. }
  234. cpuName = cpuNames.get(0);
  235. }
  236. }
  237. }
  238. // Finally, search paths.
  239. final int cpuCount = cpuNames.size();
  240. String[] searchPaths = new String[cpuCount];
  241. if (knownOs && knownCpu) {
  242. for (int i = 0; i < cpuCount; i++) {
  243. final String name = cpuNames.get(i);
  244. searchPaths[i] = osName + "-" + name;
  245. }
  246. } else {
  247. searchPaths = new String[0];
  248. }
  249. return new Object[] {
  250. osName,
  251. cpuName,
  252. osName + "-" + cpuName,
  253. searchPaths
  254. };
  255. }
  256. });
  257. OS_ID = strings[0].toString();
  258. CPU_ID = strings[1].toString();
  259. ARCH_NAME = strings[2].toString();
  260. NATIVE_SEARCH_PATHS = (String[]) strings[3];
  261. }
  262. }
  263. /**
  264. * The filesystem root of the resource loader.
  265. */
  266. private final File root;
  267. /**
  268. * Construct a new instance.
  269. *
  270. * @param root the filesystem root of the resource loader
  271. */
  272. public NativeLibraryResourceLoader(final File root) {
  273. this.root = root;
  274. }
  275. /** {@inheritDoc} */
  276. public String getLibrary(final String name) {
  277. final String mappedName = System.mapLibraryName(name);
  278. final File root = this.root;
  279. File testFile;
  280. for (String path : Identification.NATIVE_SEARCH_PATHS) {
  281. testFile = new File(new File(root, path), mappedName);
  282. if (testFile.exists()) {
  283. return testFile.getAbsolutePath();
  284. }
  285. }
  286. return null;
  287. }
  288. public URI getLocation() {
  289. return root.toURI();
  290. }
  291. /**
  292. * Get the filesystem root of the resource loader.
  293. *
  294. * @return the filesystem root of the resource loader
  295. */
  296. public File getRoot() {
  297. return root;
  298. }
  299. /**
  300. * Get the detected architecture name for this platform.
  301. *
  302. * @return the architecture name
  303. */
  304. public static String getArchName() {
  305. return Identification.ARCH_NAME;
  306. }
  307. }