What if you run it with this environment variable:
AWT_FORCE_HEADFUL=true ./gradlew clean run
What if you run it with this environment variable:
AWT_FORCE_HEADFUL=true ./gradlew clean run
can you run ps aux
and see if windowserver
is running?
Try disabling headless mode by adding:
static {
System.setProperty("java.awt.headless", "false");
}
It is already disabled.
The application hangs with no output.
I suspect our best course is to rewrite the test chooser and the settings dialog so that they donāt use AWT/Swing.
I see. Anyway, dear @sgold thank you so much for putting in your time and trying the test. It is so much appreciated
Iāve had a busy fortnight, porting my libraries and JME apps to run on the Mac Mini while publishing 2 Minie feature releases plus JME v3.5.1.
Iāve got native physics working for macOS-on-ARM.
Iāve had no success combining LWJGL v3 with Swing/AWT on macOS.
Iāve had some success using the -XstartOnFirstThread
JVM argument (on macOS only) and setting application.setShowSettings(false)
.
Iāve stumbled on a few issues that seem worth noting:
HeadlessException
when switching from windowed to fullscreen display ā impacts multiple apps; I still need to develop a simple test app and document this issue at GitHubI still think our way forward with macOS is to rewrite the current test chooser and settings dialog so that they donāt use AWT/Swing. I hope to begin work soon on these projects.
Sadly, I havenāt got a good answer for JME apps that rely on AWT/Swing.
For clarity, are you referring only to transitioning between AWT/Swing and another windowing system, (A la the TestChooser) or do you also mean embedding an LWJGL Display
in an AWT Canvas
?
Iāve only tried transitioning, not embedding. Is there a jme3-examples app that does embedding?
This feature does not currently work with LWJGL 3. There is the issue and one PR about it. I have briefly looked using GitHub - LWJGLX/lwjgl3-awt: AWT support for LWJGL3. But it requires some time and skill to implement.
Iām checking back in on this issue. Iām on a mac M1 arm. I donāt need AWT or swing, but I do need to be able to run GLFW off the main thread for my own applicationās test framework. I just tried pulling master, updating the build to use jme3-lwjgl3 and running a simple blue cube hello world, which works on main, but not off with glfw_async. Below is my sample code, runOnMain() works, runOffMain() just hangs with no error. This is with openjdk 11.
package jme3test.animation;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import org.lwjgl.system.Configuration;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class Main2 extends SimpleApplication {
static Executor executor= Executors.newFixedThreadPool(10);
public static void main(String[] args) throws InterruptedException {
// runOnMain();
runOffMain();
}
public static void runOnMain() {
Main2 app = new Main2();
AppSettings settings = new AppSettings(true);
settings.setTitle("My Awesome Game");
app.setSettings(settings);
app.setShowSettings(false);
app.start();
}
public static void runOffMain() throws InterruptedException {
Main2 app = new Main2();
Configuration.GLFW_CHECK_THREAD0.set(false);
Configuration.GLFW_LIBRARY_NAME.set("glfw_async");//"libglfw_async.dylib"
AppSettings settings = new AppSettings(true);
settings.setTitle("My Awesome Game");
app.setSettings(settings);
app.setShowSettings(false);
executor.execute(()->app.start());
Thread.sleep(1000000);
}
@Override
public void start() {
try {
super.start();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void simpleInitApp() {
Box b = new Box(1, 1, 1);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
geom.setMaterial(mat);
rootNode.attachChild(geom);
}
@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}
}```
Turns out that issue was also related to mixing AWT with LWJGL. I was using AWTās GraphicsEnvironment
to enumerate the available display modes. Does LWJGL provide equivalent functionality?
Edit: It looks like I should be using glfwGetVideoModes
.
Do lwjgl3 demos (available on LWJGL GitHub repo) run fine with glfw_async
?
Ok, Iāve not played around with lwjgl3ās build before, the demoās do not work out of the box. They throw
Failed to locate library: liblwjgl.dylib
But if you modify line 140 of the pom.xml at lwjgl3-demos/pom.xml at main Ā· LWJGL/lwjgl3-demos Ā· GitHub to read:
<platform>macos-arm64</platform>
They then throwā¦
GLFW may only be used on the main thread and that thread must be the first thread in the process. Please run the JVM with -XstartOnFirstThread. This check may be disabled with Configuration.GLFW_CHECK_THREAD0.
But if you then add
Configuration.GLFW_LIBRARY_NAME.set("glfw_async");
to the static main method of org.lwjgl.demo.intro.Intro2 you get a dialog with a triangle. So with some caveats, they seem to work.
I just modified GeometryShaderTestās static main method to:
static Executor executor= Executors.newFixedThreadPool(10);
public static void main(String[] args) throws InterruptedException {
Configuration.GLFW_LIBRARY_NAME.set("glfw_async");
executor.execute(()->{
new GeometryShaderTest().run();
});
Thread.sleep(10000);
}
And it does run correctly off the main thread.
So I believe Iāve found the problem. My earlier example works if you turn off inputs.
Main2 app = new Main2();
Configuration.GLFW_CHECK_THREAD0.set(false);
Configuration.GLFW_LIBRARY_NAME.set("glfw_async");//"libglfw_async.dylib"
AppSettings settings = new AppSettings(true);
settings.setTitle("My Awesome Game");
settings.setUseInput(false);
app.setSettings(settings);
app.setShowSettings(false);
executor.execute(()->app.start());
Thread.sleep(1000000);
}
With inputs on, when you get to the native method org.lwjgl.glfw.GLFW.glfwSetInputMode() it fails without a stack trace.
I opened an issue on LWJGL⦠glfw_async native method crashes when GLFW.glfwSetInputMode() is invoked · Issue #754 · LWJGL/lwjgl3 · GitHub no motion so far.
Iām investigating glfw_async again. I have more practical experience with itāin the LbjExamples project, where it works greatābut thatās not JMonkeyEngine.
The intermittent and confusing headless exceptions I saw before were probably caused by a Gradle daemon with its DISPLAY environment variable unset. When running apps via the Gradle daemon, the daemonās environment is used, which may differ from the shellās environmentāespecially if a user has multiple logins to the host. One workaround is to bypass Gradle and execute the app (or its start script) directly, from the command line. But I find that awkward. My preferred workaround is to execute gradlew with the āāno-daemonā option, which creates a temporary daemon with a copy of the shellās environment.
The -XstartOnFirstThread option (which default GLFW requires on macOS) is not required with glfw_async, or even a good idea.
When I try using āglfw_asyncā with JMonkeyEngine 3.5.2, my apps hang somewhere between invoking run()
in LwjglWindow.create()
and invoking simpleInitApp()
. Investigation continues ā¦
EDIT: The hang occurs in glfwInit()
. Iāll try initializing GLFW sooner in case that helps.
EDIT2: Near as I can determine, set("glfw_async")
should be invoked from main()
and as early as possible! Invoking a mostly harmless utility method prior to set()
is causing glfwInit()
to hang. Commenting out the utility method eliminated the hang. If this holds up, PR 1779 wonāt be useful.
I made some progress with āglfw_asyncā and JME 3.5.2 on macOS, but now Iāve got an issue where some apps terminate cleanly, while others terminate with exit value 133 and a ājava quit unexpectedly.ā system dialog.
Itās not clear what distinguishes the one group of apps from the other. It doesnāt seem to matter whether the apps are terminated using the Esc key (LegacyApplication.stop(false)
) or the red button in the window decorations. I plan to gradually delete features from an āexit value 133ā app until it stops misbehaving. Hopefully that will provide a clue as to the cause.
EDIT: Itās bizarre. The failing apps all set the background color of the default viewport. If I comment out the calls to viewPort.setBackgroundColor()
, they no longer fail! Iām stumped and unsure how to proceed.