constellation-app / constellation

A graph-focused data visualisation and interactive analysis application.
https://constellation-app.com
Apache License 2.0
388 stars 58 forks source link

Update code/configuration for compatibility with posix_spawn as the Process Launcher. #2044

Open OrionsGuardian opened 6 months ago

OrionsGuardian commented 6 months ago

Prerequisites

Description

From Java 13 onwards, the Process Launcher has been changed to use posix_spawn internally, instead of vfork. However, this causes issues when trying to run the Linux version of Constellation.

This error appears on startup:

 SEVERE [org.netbeans.core.network.proxy.gnome.GnomeNetworkProxy]: Cannot execute command: /usr/bin/gsettings list-recursively org.gnome.system.proxy
  java.io.IOException: error=0, Failed to exec spawn helper: pid: 5416, exit value: 127
      at java.base/java.lang.ProcessImpl.forkAndExec(Native Method)
      at java.base/java.lang.ProcessImpl.<init>(Unknown Source)
      at java.base/java.lang.ProcessImpl.start(Unknown Source)
  Caused: java.io.IOException: Cannot run program "/usr/bin/gsettings": error=0, Failed to exec spawn helper: pid: 5416, exit value: 127
      at java.base/java.lang.ProcessBuilder.start(Unknown Source)
      at java.base/java.lang.ProcessBuilder.start(Unknown Source)
      at java.base/java.lang.Runtime.exec(Unknown Source)
      at java.base/java.lang.Runtime.exec(Unknown Source)
      at java.base/java.lang.Runtime.exec(Unknown Source)
 [catch] at org.netbeans.core.network.proxy.gnome.GnomeNetworkProxy.executeCommand(GnomeNetworkProxy.java:59)
      at org.netbeans.core.network.proxy.gnome.GsettingsNetworkProxy.isGsettingsValid(GsettingsNetworkProxy.java:139)
      at org.netbeans.core.network.proxy.gnome.GnomeNetworkProxy.getNetworkProxySettings(GnomeNetworkProxy.java:40)
      at org.netbeans.core.network.proxy.NetworkProxyReloader.reloadNetworkProxy(NetworkProxyReloader.java:68)
      at org.netbeans.core.network.proxy.NbProxySelector.lambda$new$0(NbProxySelector.java:58)
      at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1420)
      at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)
      at org.openide.util.lookup.Lookups.executeWith(Lookups.java:287)
      at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2035)
 SEVERE [org.openide.util.RequestProcessor]: Error in RequestProcessor org.netbeans.core.network.proxy.NbProxySelector$$Lambda/0x00007ff0fc31a220
  java.lang.NullPointerException: Cannot invoke "java.io.BufferedReader.ready()" because "reader" is null
      at org.netbeans.core.network.proxy.gnome.GsettingsNetworkProxy.isGsettingsValid(GsettingsNetworkProxy.java:140)
      at org.netbeans.core.network.proxy.gnome.GnomeNetworkProxy.getNetworkProxySettings(GnomeNetworkProxy.java:40)
      at org.netbeans.core.network.proxy.NetworkProxyReloader.reloadNetworkProxy(NetworkProxyReloader.java:68)
      at org.netbeans.core.network.proxy.NbProxySelector.lambda$new$0(NbProxySelector.java:58)
      at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1420)
      at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)
      at org.openide.util.lookup.Lookups.executeWith(Lookups.java:287)
 [catch] at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2035)

And this error appears when trying to open a new graph:

   SEVERE [global]
   java.lang.UnsatisfiedLinkError: Can't load library: /home/constellation/V3/dist/constellation/natives/linux-amd64/libgluegen_rt.so
       at java.base/java.lang.ClassLoader.loadLibrary(Unknown Source)
       at java.base/java.lang.Runtime.load0(Unknown Source)
       at java.base/java.lang.System.load(Unknown Source)
       at com.jogamp.common.jvm.JNILibLoaderBase.loadLibraryInternal(JNILibLoaderBase.java:625)
       at com.jogamp.common.jvm.JNILibLoaderBase.access$000(JNILibLoaderBase.java:64)
       at com.jogamp.common.jvm.JNILibLoaderBase$DefaultAction.loadLibrary(JNILibLoaderBase.java:107)
       at com.jogamp.common.jvm.JNILibLoaderBase.loadLibrary(JNILibLoaderBase.java:488)
       at com.jogamp.common.os.DynamicLibraryBundle$GlueJNILibLoader.loadLibrary(DynamicLibraryBundle.java:427)
       at com.jogamp.common.os.Platform$1.run(Platform.java:321)
       at java.base/java.security.AccessController.doPrivileged(Unknown Source)
       at com.jogamp.common.os.Platform.<clinit>(Platform.java:290)
       at au.gov.asd.tac.constellation.help.utilities.toc.TOCGenerator.convertXMLMappings(TOCGenerator.java:104)
       at au.gov.asd.tac.constellation.help.utilities.toc.TOCGenerator.convertXMLMappings(TOCGenerator.java:95)
       at au.gov.asd.tac.constellation.help.utilities.Generator.run(Generator.java:71)
       at org.netbeans.core.windows.WindowManagerImpl$Exclusive$1.run(WindowManagerImpl.java:1611)
       at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)
       at org.openide.util.lookup.Lookups.executeWith(Lookups.java:287)
       at org.netbeans.modules.openide.util.NbMutexEventProvider$Event.lambda$doEventRequest$1(NbMutexEventProvider.java:112)
       at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
       at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
       at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
       at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
       at java.base/java.security.AccessController.doPrivileged(Unknown Source)
       at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
       at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
   [catch] at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:136)
       at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
       at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
       at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
       at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
       at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
       at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
   Warning: Caught Exception while retrieving executable temp base directory:
   java.io.IOException: Could not determine a temporary executable directory
       at com.jogamp.common.util.IOUtil.getTempDir(IOUtil.java:1336)
       at com.jogamp.common.util.cache.TempFileCache.<clinit>(TempFileCache.java:84)
       at com.jogamp.common.util.cache.TempJarCache.initSingleton(TempJarCache.java:96)
       at com.jogamp.common.os.Platform$1.run(Platform.java:313)
       at java.base/java.security.AccessController.doPrivileged(Unknown Source)
       at com.jogamp.common.os.Platform.<clinit>(Platform.java:290)
       at au.gov.asd.tac.constellation.help.utilities.toc.TOCGenerator.convertXMLMappings(TOCGenerator.java:104)
       at au.gov.asd.tac.constellation.help.utilities.toc.TOCGenerator.convertXMLMappings(TOCGenerator.java:95)
       at au.gov.asd.tac.constellation.help.utilities.Generator.run(Generator.java:71)
       at org.netbeans.core.windows.WindowManagerImpl$Exclusive$1.run(WindowManagerImpl.java:1611)
       at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)
       at org.openide.util.lookup.Lookups.executeWith(Lookups.java:287)
       at org.netbeans.modules.openide.util.NbMutexEventProvider$Event.lambda$doEventRequest$1(NbMutexEventProvider.java:112)
       at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
       at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
       at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
   INFO [null]: Last record repeated again.
       at java.base/java.security.AccessController.doPrivileged(Unknown Source)
       at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
       at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
       at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:136)
       at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
       at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
       at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
       at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)

As a workaround we are using a JVM option to use the old Process Launcher mechanism (vfork):

-J-Djdk.lang.Process.launchMechanism=vfork

We need to investigate what changes are needed to the Constellation code and configuration for it to be able to run correctly with the posix_spawn implementation of the Process Launcher.

Expected behaviour: Constellation should run correctly with the latest Java Process Launcher implementation.

Actual behaviour: Constellation does not run correctly with the latest Java Process Launcher implementation. It needs to revert to the old vfork implementation to be fully functional.

Reproduces how often: 100%

Additional Information

The change to using posix_spawn aims to improves memory efficiency and reduce the risk of out-of-memory errors when forking processes from a Java process with a large heap. Ideally it will enhance performance and memory management during process creation.

github-actions[bot] commented 2 days ago

This issue is stale because it has been open for 6 months with no activity. Consider reviewing and taking an action on this issue.