QUESTION:
Is there any way to detect the screen size on GraalVM in no-console mode?
FINDINGS:
- I am getting screen size using the class
GraphicsEnvironment
initialized byjava.awt.GraphicsEnvironment.getLocalGraphicsEnvironment()
- when I tried to run the code on jar mode, it is working.
- when I tried to run the code on GraalVM native mode, it is working (
com.tugalsan.blg.gvm.graphicsdevice.exe
). - when I tried to run the code on GraalVM native mode, without console (
com.tugalsan.blg.gvm.graphicsdevice.noconsole.exe
).- on console nothing appears (no log, no error)
- on log file, logs appears only until the initialization of
GraphicsEnvironment
. - Hence it crashes silently.
STEPS TO REPRODUCE: (project link)
create project file: D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\src\main\java\com\tugalsan\blg\gvm\graphicsdevice\Main.java
package com.tugalsan.blg.gvm.graphicsdevice;
import java.awt.GraphicsEnvironment;
import static java.lang.System.out;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
public class Main {
public static void log(CharSequence funcName, Object... oa) {
try {
var lstStr = Arrays.stream(oa)
.map(o -> String.valueOf(o))
.collect(Collectors.toCollection(ArrayList::new));
var str = funcName + " -> " + lstStr + "\n";
out.print(str);
Files.writeString(file, str, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
final public static Path file = FileSystems.getDefault().getPath(Main.class.getPackageName() + ".log").toAbsolutePath();
public static void main(String... s) {
try {
Files.deleteIfExists(file);
log("main", "#1");
var localGraphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
log("main", "#2");
} catch (Exception e) {
log("main", e);
}
}
}
create project file: D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\src\main\java\module-info.java
module com.tugalsan.blg.gvm.graphicsdevice {
requires java.desktop;
}
create project file: D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tugalsan</groupId>
<artifactId>com.tugalsan.blg.gvm.graphicsdevice</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>21</maven.compiler.release>
<exec.mainClass>com.tugalsan.blg.gvm.graphicsdevice.Main</exec.mainClass>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>${exec.mainClass}</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<release>21</release>
<enablePreview>true</enablePreview>
<compilerArgs>
<arg>--add-modules</arg>
<arg>jdk.incubator.vector</arg>
<!-- <arg>-XX:+EnableDynamicAgentLoading -->
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
run bat file: D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\compileJar.bat
d:
cd D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice
cmd /c mvnd clean install -DskipTests -q versions:display-dependency-updates
run bat file: D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\compileAgent.bat
java -agentlib:native-image-agent=config-output-dir=config --enable-preview --add-modules jdk.incubator.vector -jar target/com.tugalsan.blg.gvm.graphicsdevice-1.0-SNAPSHOT-jar-with-dependencies.jar
run bat file: D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\compileNative.bat
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
native-image -H:ConfigurationFileDirectories=config -march=compatibility --enable-url-protocols=http,https --enable-preview --add-modules jdk.incubator.vector -jar target\com.tugalsan.blg.gvm.graphicsdevice-1.0-SNAPSHOT-jar-with-dependencies.jar com.tugalsan.blg.gvm.graphicsdevice
run bat file: D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\compileNoConsole.bat
copy com.tugalsan.blg.gvm.graphicsdevice.exe com.tugalsan.blg.gvm.graphicsdevice.noconsole.exe
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64\editbin.exe" /SUBSYSTEM:WINDOWS com.tugalsan.blg.gvm.graphicsdevice.noconsole.exe
CONSOLE OUT
Microsoft Windows [Version 10.0.22621.2428]
(c) Microsoft Corporation. All rights reserved.
Clink v1.5.9.411d0f
Copyright (c) 2012-2018 Martin Ridgers
Portions Copyright (c) 2020-2023 Christopher Antos
https://github.com/chrisant996/clink
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice>compileJar.bat
d:
cd D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice
cmd /c mvnd clean install -DskipTests -q versions:display-dependency-updates
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice>compileAgent.bat
java -agentlib:native-image-agent=config-output-dir=config --enable-preview --add-modules jdk.incubator.vector -jar target/com.tugalsan.blg.gvm.graphicsdevice-1.0-SNAPSHOT-jar-with-dependencies.jar
WARNING: Using incubator modules: jdk.incubator.vector
main -> [#1]
main -> [#2]
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice>compileNative.bat
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.7.3
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
WARNING: Using incubator modules: jdk.incubator.vector
========================================================================================================================
GraalVM Native Image: Generating 'com.tugalsan.blg.gvm.graphicsdevice' (executable)...
========================================================================================================================
For detailed information and explanations on the build output, visit:
https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md
------------------------------------------------------------------------------------------------------------------------
[1/8] Initializing... (11,7s @ 0,15GB)
Java version: 21.0.1+12, vendor version: Oracle GraalVM 21.0.1+12.1
Graal compiler: optimization level: 2, target machine: compatibility, PGO: ML-inferred
C compiler: cl.exe (microsoft, x64, 19.37.32822)
Garbage collector: Serial GC (max heap size: 80% of RAM)
1 user-specific feature(s):
- com.oracle.svm.thirdparty.gson.GsonFeature
------------------------------------------------------------------------------------------------------------------------
Build resources:
- 20,82GB of memory (66,3% of 31,41GB system memory, determined at start)
- 16 thread(s) (100,0% of 16 available processor(s), determined at start)
[2/8] Performing analysis... [******] (11,5s @ 0,52GB)
6.723 reachable types (80,1% of 8.392 total)
9.551 reachable fields (55,2% of 17.314 total)
34.508 reachable methods (55,0% of 62.750 total)
2.211 types, 114 fields, and 1.798 methods registered for reflection
97 types, 120 fields, and 87 methods registered for JNI access
0 foreign downcalls registered
4 native libraries: crypt32, ncrypt, version, winhttp
[3/8] Building universe... (1,8s @ 0,70GB)
[4/8] Parsing methods... [**] (3,7s @ 0,61GB)
[5/8] Inlining methods... [***] (0,6s @ 0,66GB)
[6/8] Compiling methods... [*****] (24,9s @ 0,83GB)
[7/8] Layouting methods... [**] (2,5s @ 0,92GB)
[8/8] Creating image... [**] (3,0s @ 0,64GB)
17,91MB (54,74%) for code area: 19.468 compilation units
14,53MB (44,42%) for image heap: 206.679 objects and 50 resources
279,28kB ( 0,83%) for other data
32,71MB in total
------------------------------------------------------------------------------------------------------------------------
Top 10 origins of code area: Top 10 object types in image heap:
12,01MB java.base 4,83MB byte[] for code metadata
2,74MB svm.jar (Native Image) 2,52MB byte[] for java.lang.String
1,25MB java.desktop 1,45MB java.lang.String
367,37kB java.rmi 1,15MB java.lang.Class
266,37kB java.naming 636,93kB byte[] for general heap data
257,91kB jdk.crypto.ec 503,70kB heap alignment
180,64kB com.oracle.svm.svm_enterprise 380,02kB byte[] for reflection metadata
164,87kB java.logging 315,14kB com.oracle.svm.core.hub.DynamicHubCompanion
135,25kB jdk.naming.dns 267,41kB java.util.HashMap$Node
105,20kB jdk.crypto.mscapi 195,44kB c.o.svm.core.hub.DynamicHub$ReflectionMetadata
338,36kB for 16 more packages 2,34MB for 1723 more object types
Use '-H:+BuildReport' to create a report with more details.
------------------------------------------------------------------------------------------------------------------------
Security report:
- Binary includes Java deserialization.
- Use '--enable-sbom' to embed a Software Bill of Materials (SBOM) in the binary.
------------------------------------------------------------------------------------------------------------------------
Recommendations:
PGO: Use Profile-Guided Optimizations ('--pgo') for improved throughput.
INIT: Adopt '--strict-image-heap' to prepare for the next GraalVM release.
HEAP: Set max heap for improved and more predictable memory usage.
QBM: Use the quick build mode ('-Ob') to speed up builds during development.
------------------------------------------------------------------------------------------------------------------------
3,8s (6,2% of total time) in 515 GCs | Peak RSS: 1,73GB | CPU load: 6,73
------------------------------------------------------------------------------------------------------------------------
Produced artifacts:
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\awt.dll (jdk_library)
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\com.tugalsan.blg.gvm.graphicsdevice.exe (executable)
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\fontmanager.dll (jdk_library)
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\freetype.dll (jdk_library)
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\java.dll (jdk_library_shim)
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\javaaccessbridge.dll (jdk_library)
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\jawt.dll (jdk_library)
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\jvm.dll (jdk_library_shim)
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice\lcms.dll (jdk_library)
========================================================================================================================
Finished generating 'com.tugalsan.blg.gvm.graphicsdevice' in 1m 0s.
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice>compileNoConsole.bat
copy com.tugalsan.blg.gvm.graphicsdevice.exe com.tugalsan.blg.gvm.graphicsdevice.noconsole.exe
1 file(s) copied.
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64\editbin.exe" /SUBSYSTEM:WINDOWS com.tugalsan.blg.gvm.graphicsdevice.noconsole.exe
Microsoft (R) COFF/PE Editor Version 14.37.32822.0
Copyright (C) Microsoft Corporation. All rights reserved.
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice>com.tugalsan.blg.gvm.graphicsdevice.exe
main -> [#1]
main -> [#2]
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice>copy com.tugalsan.blg.gvm.graphicsdevice.log con:
main -> [#1]
main -> [#2]
1 file(s) copied.
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice>com.tugalsan.blg.gvm.graphicsdevice.noconsole.exe
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice>copy com.tugalsan.blg.gvm.graphicsdevice.log con:
main -> [#1]
1 file(s) copied.
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice>java -version
java version "21.0.1" 2023-10-17
Java(TM) SE Runtime Environment Oracle GraalVM 21.0.1+12.1 (build 21.0.1+12-jvmci-23.1-b19)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 21.0.1+12.1 (build 21.0.1+12-jvmci-23.1-b19, mixed mode, sharing)
D:\git\blg\com.tugalsan.blg.gvm.graphicsdevice>
Not an answer, but just a fix:
I think the only way to do is, calling a console app from non-console app, there console app will pop up, detect screen size, print it to console and disappear. At least the main non-console app can run hidden.
On my computer, nothing popped up, but it may vary according to speed of cpu.
Here is a working implementation: