Open
Description
Running Linux.
I am getting an exception when jme tries to extract a native library to a temp folder.
Aug 15, 2024 5:40:32 PM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.7.0-beta1.2.2
* Branch: HEAD
* Git Hash: 5cadb88
* Build Date: 2024-07-30
Exception in thread "AWT-EventQueue-0" java.io.UncheckedIOException: Failed to extract native library to: /tmp/jme3/natives_8946616b/libbulletjme-x86_64.so
at com.jme3.system.NativeLibraryLoader.loadNativeLibrary(NativeLibraryLoader.java:534)
at com.jme3.system.JmeDesktopSystem.initialize(JmeDesktopSystem.java:290)
at com.jme3.system.JmeDesktopSystem.newContext(JmeDesktopSystem.java:212)
at com.jme3.system.JmeSystem.newContext(JmeSystem.java:175)
at com.jme3.app.LegacyApplication.createCanvas(LegacyApplication.java:560)
at scamsoft.minecraft.terrain3d.Terrain3D.<init>(Terrain3D.java:112)
at scamsoft.minecraft.terrain3d.gui.TerrainGui.lambda$main$12(TerrainGui.java:886)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: java.nio.file.NoSuchFileException: /tmp/jme3/natives_8946616b/libbulletjme-x86_64.so
at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:218)
at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:484)
at java.base/java.nio.file.Files.newOutputStream(Files.java:228)
at java.base/java.nio.file.Files.copy(Files.java:3160)
at com.jme3.system.NativeLibraryLoader.loadNativeLibrary(NativeLibraryLoader.java:506)
The application is running as a non-root user.
The /tmp/jme folder has permissions drwxr-xr-x 5 root root
In other words:
- root has ownership of /tmp/jme
- root has write permissions
- other users have read permissions but not write
The logic in NativeLibraryLoader.getExtractionFolder() has a couple of holes that are causing this to fail.
- The code checks if the user has write permission to the temp folder (/tmp) but doesn't check write permissions to the /tmp/jme subfolder (it assumes write permissions exist)
- There is logic to catch any exceptions while creating the temp folder and to call setExtractionFolderToUserCache() instead. The problem is that the call to extractionFolder.mkdir() does not throw an exception if it fails; but instead returns false. And the JME code does not check the result of this call.
Some suggestions for improvements:
- The /tmp/jme folder is shared between all jme applications. This is probably not a good idea as it seems that whatever user creates the /tmp/jme folder does not give write permissions to other users. A better scheme would be to create completely independent temp folders e.g. /tmp/jme_natives_[hash]
- Calls to mkdir should be checked for failure and handled accordingly e.g. throw an exception so setExtractionFolderToUserCache() will be called instead
Metadata
Metadata
Assignees
Labels
No labels