|
1 | | -/* |
2 | | - * Copyright (c) 2009-2022 jMonkeyEngine |
3 | | - * All rights reserved. |
4 | | - * |
5 | | - * Redistribution and use in source and binary forms, with or without |
6 | | - * modification, are permitted provided that the following conditions are |
7 | | - * met: |
8 | | - * |
9 | | - * * Redistributions of source code must retain the above copyright |
10 | | - * notice, this list of conditions and the following disclaimer. |
11 | | - * |
12 | | - * * Redistributions in binary form must reproduce the above copyright |
13 | | - * notice, this list of conditions and the following disclaimer in the |
14 | | - * documentation and/or other materials provided with the distribution. |
15 | | - * |
16 | | - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
17 | | - * may be used to endorse or promote products derived from this software |
18 | | - * without specific prior written permission. |
19 | | - * |
20 | | - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
21 | | - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
22 | | - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 | | - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
24 | | - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
25 | | - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
26 | | - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
27 | | - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
28 | | - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
29 | | - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
30 | | - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | | - */ |
32 | | -package com.jme3.system; |
33 | | - |
34 | | -/** |
35 | | - * Enumerate known operating system/architecture pairs. |
36 | | - */ |
| 1 | +/* |
| 2 | + * Copyright (c) 2009-2022 jMonkeyEngine |
| 3 | + * All rights reserved. |
| 4 | + * |
| 5 | + * Redistribution and use in source and binary forms, with or without |
| 6 | + * modification, are permitted provided that the following conditions are |
| 7 | + * met: |
| 8 | + * |
| 9 | + * * Redistributions of source code must retain the above copyright |
| 10 | + * notice, this list of conditions and the following disclaimer. |
| 11 | + * |
| 12 | + * * Redistributions in binary form must reproduce the above copyright |
| 13 | + * notice, this list of conditions and the following disclaimer in the |
| 14 | + * documentation and/or other materials provided with the distribution. |
| 15 | + * |
| 16 | + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
| 17 | + * may be used to endorse or promote products derived from this software |
| 18 | + * without specific prior written permission. |
| 19 | + * |
| 20 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 21 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
| 22 | + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 23 | + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| 24 | + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 25 | + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 26 | + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 27 | + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 28 | + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 29 | + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 30 | + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 | + */ |
| 32 | +package com.jme3.system; |
| 33 | + |
| 34 | +import java.nio.file.Files; |
| 35 | +import java.nio.file.Path; |
| 36 | +import java.nio.file.Paths; |
| 37 | + |
| 38 | +/** |
| 39 | + * Enumerate known operating system/architecture pairs. |
| 40 | + */ |
37 | 41 | public enum Platform { |
38 | 42 |
|
39 | 43 | /** |
@@ -100,8 +104,8 @@ public enum Platform { |
100 | 104 | * Apple Mac OS X 64-bit Intel |
101 | 105 | */ |
102 | 106 | MacOSX64(Os.MacOS, true), |
103 | | - |
104 | | - /** |
| 107 | + |
| 108 | + /** |
105 | 109 | * Apple Mac OS X 64-bit ARM |
106 | 110 | */ |
107 | 111 | MacOSX_ARM64(Os.MacOS, true), |
@@ -187,65 +191,163 @@ public enum Platform { |
187 | 191 | */ |
188 | 192 | Web(Os.Web, true) // assume always 64-bit, it shouldn't matter for web |
189 | 193 | ; |
190 | | - |
191 | | - |
192 | | - /** |
193 | | - * Enumerate generic names of operating systems |
194 | | - */ |
195 | | - public enum Os { |
196 | | - /** |
197 | | - * Linux operating systems |
198 | | - */ |
199 | | - Linux, |
200 | | - /** |
201 | | - * Microsoft Windows operating systems |
202 | | - */ |
203 | | - Windows, |
204 | | - /** |
205 | | - * iOS operating systems |
206 | | - */ |
207 | | - iOS, |
208 | | - /** |
209 | | - * macOS operating systems |
210 | | - */ |
211 | | - MacOS, |
212 | | - /** |
213 | | - * Android operating systems |
214 | | - */ |
215 | | - Android, |
216 | | - /** |
217 | | - * Generic web platform |
218 | | - */ |
219 | | - Web |
220 | | - } |
221 | | - |
222 | | - private final boolean is64bit; |
223 | | - private final Os os; |
224 | | - |
225 | | - /** |
226 | | - * Test for a 64-bit address space. |
227 | | - * |
228 | | - * @return true if 64 bits, otherwise false |
229 | | - */ |
230 | | - public boolean is64Bit() { |
231 | | - return is64bit; |
232 | | - } |
233 | | - |
234 | | - /** |
235 | | - * Returns the operating system of this platform. |
236 | | - * |
237 | | - * @return the generic name of the operating system of this platform |
238 | | - */ |
239 | | - public Os getOs() { |
240 | | - return os; |
241 | | - } |
242 | | - |
243 | | - private Platform(Os os, boolean is64bit) { |
244 | | - this.os = os; |
245 | | - this.is64bit = is64bit; |
246 | | - } |
247 | | - |
248 | | - private Platform(Os os) { |
249 | | - this(os, false); |
250 | | - } |
251 | | -} |
| 194 | + |
| 195 | + |
| 196 | + /** |
| 197 | + * Enumerate generic names of operating systems |
| 198 | + */ |
| 199 | + public enum Os { |
| 200 | + /** |
| 201 | + * Linux operating systems |
| 202 | + */ |
| 203 | + Linux, |
| 204 | + /** |
| 205 | + * Microsoft Windows operating systems |
| 206 | + */ |
| 207 | + Windows, |
| 208 | + /** |
| 209 | + * iOS operating systems |
| 210 | + */ |
| 211 | + iOS, |
| 212 | + /** |
| 213 | + * macOS operating systems |
| 214 | + */ |
| 215 | + MacOS, |
| 216 | + /** |
| 217 | + * Android operating systems |
| 218 | + */ |
| 219 | + Android, |
| 220 | + /** |
| 221 | + * Generic web platform |
| 222 | + */ |
| 223 | + Web |
| 224 | + } |
| 225 | + |
| 226 | + private final boolean is64bit; |
| 227 | + private final Os os; |
| 228 | + private static final boolean NATIVE_IMAGE_RUNTIME = detectNativeImageRuntime(); |
| 229 | + private static final boolean GRAAL_VM_RUNTIME = detectGraalVmRuntime(); |
| 230 | + |
| 231 | + /** |
| 232 | + * Test for a 64-bit address space. |
| 233 | + * |
| 234 | + * @return true if 64 bits, otherwise false |
| 235 | + */ |
| 236 | + public boolean is64Bit() { |
| 237 | + return is64bit; |
| 238 | + } |
| 239 | + |
| 240 | + /** |
| 241 | + * Returns the operating system of this platform. |
| 242 | + * |
| 243 | + * @return the generic name of the operating system of this platform |
| 244 | + */ |
| 245 | + public Os getOs() { |
| 246 | + return os; |
| 247 | + } |
| 248 | + |
| 249 | + /** |
| 250 | + * Test whether this process runs on GraalVM or inside a native-image runtime. |
| 251 | + * |
| 252 | + * @return true if GraalVM/native-image is detected, otherwise false |
| 253 | + */ |
| 254 | + public boolean isGraalVM() { |
| 255 | + return GRAAL_VM_RUNTIME; |
| 256 | + } |
| 257 | + |
| 258 | + /** |
| 259 | + * Test whether this process is running as a GraalVM native-image executable. |
| 260 | + * |
| 261 | + * @return true if running inside a native-image runtime, otherwise false |
| 262 | + */ |
| 263 | + public boolean isNativeImage() { |
| 264 | + return NATIVE_IMAGE_RUNTIME; |
| 265 | + } |
| 266 | + |
| 267 | + /** |
| 268 | + * Test whether this process is running on GraalVM JRE/JDK (not native-image). |
| 269 | + * |
| 270 | + * @return true if GraalVM is detected and this is not native-image |
| 271 | + */ |
| 272 | + public boolean isGraalVmJvm() { |
| 273 | + return GRAAL_VM_RUNTIME && !NATIVE_IMAGE_RUNTIME; |
| 274 | + } |
| 275 | + |
| 276 | + /** |
| 277 | + * Resolve a sibling native library directory next to the current executable. |
| 278 | + * |
| 279 | + * @param directoryName the sibling directory name, for example {@code libs} |
| 280 | + * @return absolute path to the directory, or null if unavailable |
| 281 | + */ |
| 282 | + public static String resolveNativeImageSiblingDirectory(String directoryName) { |
| 283 | + if (!NATIVE_IMAGE_RUNTIME || directoryName == null || directoryName.isEmpty()) { |
| 284 | + return null; |
| 285 | + } |
| 286 | + |
| 287 | + String executableName; |
| 288 | + try { |
| 289 | + Class<?> processPropertiesClass = Class.forName("org.graalvm.nativeimage.ProcessProperties", false, |
| 290 | + Platform.class.getClassLoader()); |
| 291 | + Object result = processPropertiesClass.getMethod("getExecutableName").invoke(null); |
| 292 | + executableName = result instanceof String ? (String) result : null; |
| 293 | + } catch (Throwable ignored) { |
| 294 | + return null; |
| 295 | + } |
| 296 | + |
| 297 | + if (executableName == null || executableName.isEmpty()) { |
| 298 | + return null; |
| 299 | + } |
| 300 | + |
| 301 | + try { |
| 302 | + Path executablePath = Paths.get(executableName).toAbsolutePath().normalize(); |
| 303 | + Path parent = executablePath.getParent(); |
| 304 | + if (parent == null) { |
| 305 | + return null; |
| 306 | + } |
| 307 | + Path sibling = parent.resolve(directoryName).normalize(); |
| 308 | + if (Files.isDirectory(sibling)) { |
| 309 | + return sibling.toString(); |
| 310 | + } |
| 311 | + } catch (Throwable ignored) { |
| 312 | + return null; |
| 313 | + } |
| 314 | + |
| 315 | + return null; |
| 316 | + } |
| 317 | + |
| 318 | + private static boolean detectNativeImageRuntime() { |
| 319 | + return System.getProperty("org.graalvm.nativeimage.imagecode") != null; |
| 320 | + } |
| 321 | + |
| 322 | + private static boolean detectGraalVmRuntime() { |
| 323 | + if (NATIVE_IMAGE_RUNTIME) { |
| 324 | + return true; |
| 325 | + } |
| 326 | + |
| 327 | + String vmName = System.getProperty("java.vm.name", "").toLowerCase(); |
| 328 | + if (vmName.contains("graal")) { |
| 329 | + return true; |
| 330 | + } |
| 331 | + |
| 332 | + String vendor = System.getProperty("java.vendor", "").toLowerCase(); |
| 333 | + if (vendor.contains("graal")) { |
| 334 | + return true; |
| 335 | + } |
| 336 | + |
| 337 | + try { |
| 338 | + Class.forName("org.graalvm.polyglot.Context", false, Platform.class.getClassLoader()); |
| 339 | + return true; |
| 340 | + } catch (ClassNotFoundException ignored) { |
| 341 | + return false; |
| 342 | + } |
| 343 | + } |
| 344 | + |
| 345 | + private Platform(Os os, boolean is64bit) { |
| 346 | + this.os = os; |
| 347 | + this.is64bit = is64bit; |
| 348 | + } |
| 349 | + |
| 350 | + private Platform(Os os) { |
| 351 | + this(os, false); |
| 352 | + } |
| 353 | +} |
0 commit comments