Skip to content

Commit e8f6a8e

Browse files
committed
Improve UIService headless mode and fix test
After much hand-wringing, @hinerm and I gave up and decided to call java.awt.GraphicsEnvironment.isHeadless() to make sure the UIService reports the correct headless status. Otherwise, testing becomes very tricky with more edge cases, and more importantly, the UIService.isHeadless() method does not behave as one might expect.
1 parent fe8297f commit e8f6a8e

File tree

3 files changed

+44
-13
lines changed

3 files changed

+44
-13
lines changed

src/main/java/org/scijava/ui/DefaultUIService.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
package org.scijava.ui;
3131

32+
import java.awt.GraphicsEnvironment;
3233
import java.io.File;
3334
import java.io.FileFilter;
3435
import java.util.ArrayList;
@@ -191,9 +192,9 @@ public void setHeadless(final boolean headless) {
191192

192193
@Override
193194
public boolean isHeadless() {
194-
// NB: We do not use java.awt.GraphicsEnvironment.isHeadless()
195-
// because scijava-common eschews java.awt.* classes when possible.
196-
return forceHeadless || Boolean.getBoolean("java.awt.headless");
195+
return forceHeadless ||
196+
Boolean.getBoolean("java.awt.headless") ||
197+
GraphicsEnvironment.isHeadless();
197198
}
198199

199200
@Override

src/main/java/org/scijava/ui/UIService.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,15 @@ public interface UIService extends SciJavaService {
119119
*/
120120
void setHeadless(boolean isHeadless);
121121

122-
/** Gets whether the UI is running in headless mode (no UI). */
122+
/**
123+
* Gets whether the UI is running in headless mode (no UI).
124+
* <p>
125+
* More precisely: returns true when {@code java.awt.headless} system
126+
* property is set, and/or {@link java.awt.GraphicsEnvironment.isHeadless()}
127+
* returns true, and/or {@link #setHeadless(boolean)} was called with {@code
128+
* true} to force headless behavior in an otherwise headful environment.
129+
* </p>
130+
*/
123131
boolean isHeadless();
124132

125133
/**

src/test/java/org/scijava/ui/UIServiceTest.java

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
import static org.junit.Assert.assertEquals;
3333
import static org.junit.Assert.assertFalse;
34+
import static org.junit.Assert.assertSame;
3435
import static org.junit.Assert.assertTrue;
3536

3637
import java.util.List;
@@ -79,19 +80,40 @@ public void testAvailableUIs() {
7980

8081
@Test
8182
public void testHeadlessUI() {
83+
// If true here, before we messed with it, the assumption is that we are
84+
// in a truly headless environment, not just forced via setHeadless(true).
85+
boolean reallyHeadless = uiService.isHeadless();
86+
8287
final MockUserInterface mockUI = new MockUserInterface();
8388
uiService.setDefaultUI(mockUI);
8489

8590
// test non-headless behavior
86-
uiService.setHeadless(false);
87-
assertFalse(uiService.isHeadless());
88-
assertTrue(uiService.getDefaultUI() instanceof MockUserInterface);
89-
90-
// test headless behavior
91-
uiService.setHeadless(true);
92-
assertTrue(uiService.isHeadless());
93-
assertTrue("UIService should return HeadlessUI when running \"headless\"",
94-
uiService.getDefaultUI() instanceof HeadlessUI);
91+
if (reallyHeadless) {
92+
// This environment is truly headless, and
93+
// we should not be able to override it.
94+
uiService.setHeadless(false);
95+
assertTrue(uiService.isHeadless());
96+
assertTrue("UIService should return HeadlessUI when running \"headless\"",
97+
uiService.getDefaultUI() instanceof HeadlessUI);
98+
}
99+
else {
100+
// This environment is not headless! We can test more things.
101+
assertSame("UIService default UI override failed",
102+
mockUI, uiService.getDefaultUI());
103+
104+
// This environment isn't headless now;
105+
// let's test overriding it to be so.
106+
uiService.setHeadless(true);
107+
assertTrue(uiService.isHeadless());
108+
assertTrue("UIService should return HeadlessUI when running \"headless\"",
109+
uiService.getDefaultUI() instanceof HeadlessUI);
110+
111+
// Now we put it back!
112+
uiService.setHeadless(false);
113+
assertFalse(uiService.isHeadless());
114+
assertSame("UIService default UI override was not restored",
115+
mockUI, uiService.getDefaultUI());
116+
}
95117
}
96118

97119
private static final class MockUserInterface extends AbstractUserInterface {

0 commit comments

Comments
 (0)