codenameone / CodenameOne

Cross-platform framework for building truly native mobile apps with Java or Kotlin. Write Once Run Anywhere support for iOS, Android, Desktop & Web.

Home Page:https://www.codenameone.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ability to run iOS Build in a headless environment

Rocketeer007 opened this issue · comments

Is your feature request related to a problem? Please describe.
I'm trying to set up a CI/CD build for my CodenameOne app. Unfortunately, when I run the Maven build for the iOS project over SSH, I get an exception when processing the CSS files:

% mvn package -DskipTests -Dcodename1.platform=ios -Dcodename1.buildTarget=ios-source -Dopen=false -U -e
... snip ...
[INFO] --- codenameone-maven-plugin:7.0.90:css (cn1-process-classes) @ flexone-common ---
[INFO] Exception in thread "main" java.lang.ExceptionInInitializerError
[INFO]  at com.codename1.designer.ResourceEditorApp._main(ResourceEditorApp.java:274)
[INFO]  at com.codename1.designer.ResourceEditorApp.main(ResourceEditorApp.java:258)
[INFO] Caused by: java.awt.HeadlessException
[INFO]  at java.desktop/sun.java2d.HeadlessGraphicsEnvironment.getDefaultScreenDevice(HeadlessGraphicsEnvironment.java:58)
[INFO]  at com.codename1.impl.javase.JavaSEPort.calcRetinaScale(JavaSEPort.java:406)
[INFO]  at com.codename1.impl.javase.JavaSEPort.<clinit>(JavaSEPort.java:637)
[INFO]  ... 2 more

Describe the solution you'd like
Looking at the ResourceEditorApp, it appears to initialise display immediately, even if this is not going to be used.

We can see that the CompileCSSMojo passes -Dcli=true as well as -css, so it should be possible for the app to realise it is being used on the command line, and skip the UI initialisation.

Describe alternatives you've considered
Have considered using an equivalent to Xvfb, but this doesn't appear to exist for the Mac without installing a bunch of extra dependencies.

Additional context
N/A

Looking in a bit of detail into this, the problem seems to be that the CN1CSSCLI class depends on the Util class for all file IO, which cannot be used without an initialised Display; that in turn requires a non-headless environment.

While normally I'm a big fan of re-use of existing logic, in this case it seems that making the CLI dependent on the UI is not ideal, so I would propose replacing the uses of Util with standard Java file IO.

If I were to create a PR with this change, would it be accepted?

After further digging, it's a bit more complex, as there are some other parts that also require an initialized display, not just the FileIO in CSSTheme. It seems that there is also a bunch of code associated with Fonts that is in the JavaSEPort class and used by the CN1CSSCLI process.

One working solution I have tried was to create a JavaCLIPort implementation of CodenameOneImplementation; this implementation mostly copied the Font logic from JavaSEPort, and didn't implement any other features of the CN1 logic.

An alternative solution would be to refactor the Font logic into a separate FontHelper type class, which would then be used by both JavaSEPort and CSSTheme. This feels like a nicer solution, but would also require the refactoring of the File IO logic mentioned above.