PageRenderTime 54ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

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

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