PageRenderTime 66ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://github.com/fl4via/jboss-modules
Java | 321 lines | 253 code | 18 blank | 50 comment | 146 complexity | 98e108a0e9eba9940d53bec36d5edcb5 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") || sysArch.startsWith("I486") || sysArch.startsWith("I586") || sysArch.startsWith("I686") || sysArch.startsWith("X86") || sysArch.contains("IA32")) {
  116. cpuName = "i686";
  117. } else if (sysArch.startsWith("X32")) {
  118. cpuName = "x32";
  119. } else if (sysArch.startsWith("PPC64")) {
  120. cpuName = "ppc64";
  121. } else if (sysArch.startsWith("PPC") || sysArch.startsWith("POWER")) {
  122. cpuName = "ppc";
  123. } else if (sysArch.startsWith("ARMV7A") || sysArch.contains("AARCH32")) {
  124. hasEndian = true;
  125. hasHardFloatABI = true;
  126. cpuName = "armv7a";
  127. } else if (sysArch.startsWith("AARCH64") || sysArch.startsWith("ARM64") || sysArch.startsWith("ARMV8") || sysArch.startsWith("PXA9") || sysArch.startsWith("PXA10")) {
  128. hasEndian = true;
  129. cpuName = "aarch64";
  130. } else if (sysArch.startsWith("PXA27")) {
  131. hasEndian = true;
  132. cpuName = "armv5t-iwmmx";
  133. } else if (sysArch.startsWith("PXA3")) {
  134. hasEndian = true;
  135. cpuName = "armv5t-iwmmx2";
  136. } else if (sysArch.startsWith("ARMV4T") || sysArch.startsWith("EP93")) {
  137. hasEndian = true;
  138. cpuName = "armv4t";
  139. } else if (sysArch.startsWith("ARMV4") || sysArch.startsWith("EP73")) {
  140. hasEndian = true;
  141. cpuName = "armv4";
  142. } else if (sysArch.startsWith("ARMV5T") || sysArch.startsWith("PXA") || sysArch.startsWith("IXC") || sysArch.startsWith("IOP") || sysArch.startsWith("IXP") || sysArch.startsWith("CE")) {
  143. hasEndian = true;
  144. String isaList = System.getProperty("sun.arch.isalist");
  145. if (isaList != null) {
  146. if (isaList.toUpperCase(Locale.US).contains("MMX2")) {
  147. cpuName = "armv5t-iwmmx2";
  148. } else if (isaList.toUpperCase(Locale.US).contains("MMX")) {
  149. cpuName = "armv5t-iwmmx";
  150. } else {
  151. cpuName = "armv5t";
  152. }
  153. } else {
  154. cpuName = "armv5t";
  155. }
  156. } else if (sysArch.startsWith("ARMV5")) {
  157. hasEndian = true;
  158. cpuName = "armv5";
  159. } else if (sysArch.startsWith("ARMV6")) {
  160. hasEndian = true;
  161. hasHardFloatABI = true;
  162. cpuName = "armv6";
  163. } else if (sysArch.startsWith("PA_RISC2.0W")) {
  164. cpuName = "parisc64";
  165. } else if (sysArch.startsWith("PA_RISC") || sysArch.startsWith("PA-RISC")) {
  166. cpuName = "parisc";
  167. } else if (sysArch.startsWith("IA64")) {
  168. // HP-UX reports IA64W for 64-bit Itanium and IA64N when running
  169. // in 32-bit mode.
  170. cpuName = sysArch.toLowerCase(Locale.US);
  171. } else if (sysArch.startsWith("ALPHA")) {
  172. cpuName = "alpha";
  173. } else if (sysArch.startsWith("MIPS")) {
  174. cpuName = "mips";
  175. } else {
  176. knownCpu = false;
  177. cpuName = "unknown";
  178. }
  179. boolean be = false;
  180. boolean hf = false;
  181. if (knownCpu && hasEndian && "big".equals(System.getProperty("sun.cpu.endian", "little"))) {
  182. be = true;
  183. }
  184. if (knownCpu && hasHardFloatABI) {
  185. String archAbi = System.getProperty("sun.arch.abi");
  186. if (archAbi != null) {
  187. if (archAbi.toUpperCase(Locale.US).contains("HF")) {
  188. hf = true;
  189. }
  190. } else {
  191. String libPath = System.getProperty("java.library.path");
  192. if (libPath != null && libPath.toUpperCase(Locale.US).contains("GNUEABIHF")) {
  193. hf = true;
  194. }
  195. }
  196. if (hf) cpuName += "-hf";
  197. }
  198. if (knownCpu) {
  199. switch (cpuName) {
  200. case "i686": cpuNames.add("i686");
  201. case "i586": cpuNames.add("i586");
  202. case "i486": cpuNames.add("i486");
  203. case "i386": cpuNames.add("i386");
  204. break;
  205. case "armv7a": cpuNames.add("armv7a"); if (hf) break;
  206. case "armv6": cpuNames.add("armv6"); if (hf) break;
  207. case "armv5t": cpuNames.add("armv5t");
  208. case "armv5": cpuNames.add("armv5");
  209. case "armv4t": cpuNames.add("armv4t");
  210. case "armv4": cpuNames.add("armv4");
  211. break;
  212. case "armv5t-iwmmx2": cpuNames.add("armv5t-iwmmx2");
  213. case "armv5t-iwmmx": cpuNames.add("armv5t-iwmmx");
  214. cpuNames.add("armv5t");
  215. cpuNames.add("armv5");
  216. cpuNames.add("armv4t");
  217. cpuNames.add("armv4");
  218. break;
  219. default: cpuNames.add(cpuName);
  220. break;
  221. }
  222. if (hf || be) for (int i = 0; i < cpuNames.size(); i++) {
  223. String name = cpuNames.get(i);
  224. if (be) name += "-be";
  225. if (hf) name += "-hf";
  226. cpuNames.set(i, name);
  227. }
  228. cpuName = cpuNames.get(0);
  229. }
  230. }
  231. } else {
  232. cpuNames.add(cpuName);
  233. }
  234. // Finally, search paths.
  235. final int cpuCount = cpuNames.size();
  236. String[] searchPaths = new String[cpuCount];
  237. if (knownOs && knownCpu) {
  238. for (int i = 0; i < cpuCount; i++) {
  239. final String name = cpuNames.get(i);
  240. searchPaths[i] = osName + "-" + name;
  241. }
  242. } else {
  243. searchPaths = new String[0];
  244. }
  245. return new Object[] {
  246. osName,
  247. cpuName,
  248. osName + "-" + cpuName,
  249. searchPaths
  250. };
  251. }
  252. });
  253. OS_ID = strings[0].toString();
  254. CPU_ID = strings[1].toString();
  255. ARCH_NAME = strings[2].toString();
  256. NATIVE_SEARCH_PATHS = (String[]) strings[3];
  257. }
  258. }
  259. /**
  260. * The filesystem root of the resource loader.
  261. */
  262. private final File root;
  263. /**
  264. * Construct a new instance.
  265. *
  266. * @param root the filesystem root of the resource loader
  267. */
  268. public NativeLibraryResourceLoader(final File root) {
  269. this.root = root;
  270. }
  271. /** {@inheritDoc} */
  272. public String getLibrary(final String name) {
  273. final String mappedName = System.mapLibraryName(name);
  274. final File root = this.root;
  275. File testFile;
  276. for (String path : Identification.NATIVE_SEARCH_PATHS) {
  277. testFile = new File(new File(root, path), mappedName);
  278. if (testFile.exists()) {
  279. return testFile.getAbsolutePath();
  280. }
  281. }
  282. return null;
  283. }
  284. public URI getLocation() {
  285. return root.toURI();
  286. }
  287. /**
  288. * Get the filesystem root of the resource loader.
  289. *
  290. * @return the filesystem root of the resource loader
  291. */
  292. public File getRoot() {
  293. return root;
  294. }
  295. /**
  296. * Get the detected architecture name for this platform.
  297. *
  298. * @return the architecture name
  299. */
  300. public static String getArchName() {
  301. return Identification.ARCH_NAME;
  302. }
  303. }