Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support static native images (fix #246) #270

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

Conversation

Glavo
Copy link
Contributor

@Glavo Glavo commented Oct 3, 2023

This PR provides a new implementation of AnsiConsoleSupport. It uses the native image C interface to implement isatty and uses the stty size command to implement getTerminalWidth.

I'm temporarily naming the provider musl, but that's not an appropriate name and I'll change it later.

@Glavo
Copy link
Contributor Author

Glavo commented Oct 3, 2023

@rsenden It's working!

glavo@glavo-desktop /m/d/P/j/s/target (stty)> native-image --static --libc=musl -Djansi.providers=musl -jar ./jansi-2.4.1-SNAPSHOT.jar
========================================================================================================================
GraalVM Native Image: Generating 'jansi-2.4.1-SNAPSHOT' (static executable)...
========================================================================================================================
[1/8] Initializing...                                                                                    (2.6s @ 0.14GB)
 Java version: 21+35, vendor version: Oracle GraalVM 21+35.1
 Graal compiler: optimization level: 2, target machine: x86-64-v3, PGO: ML-inferred
 C compiler: x86_64-linux-musl-gcc (linux, x86_64, 10.2.1)
 Garbage collector: Serial GC (max heap size: 80% of RAM)
 2 user-specific feature(s):
 - com.oracle.svm.thirdparty.gson.GsonFeature
 - org.fusesource.jansi.internal.NativeImageFeature
------------------------------------------------------------------------------------------------------------------------
Build resources:
 - 26.49GB of memory (41.5% of 63.78GB system memory, determined at start)
 - 16 thread(s) (100.0% of 16 available processor(s), determined at start)
[2/8] Performing analysis...  [****]                                                                     (4.0s @ 0.32GB)
    3,476 reachable types   (72.6% of    4,785 total)
    4,239 reachable fields  (50.8% of    8,343 total)
   18,030 reachable methods (47.4% of   38,027 total)
    1,076 types,   112 fields, and   678 methods registered for reflection
       72 types,   174 fields, and   134 methods registered for JNI access
        4 native libraries: dl, pthread, rt, z
[3/8] Building universe...                                                                               (0.8s @ 0.50GB)
[4/8] Parsing methods...      [*]                                                                        (1.5s @ 0.70GB)
[5/8] Inlining methods...     [***]                                                                      (0.3s @ 0.54GB)
[6/8] Compiling methods...    [***]                                                                      (8.1s @ 0.47GB)
[7/8] Layouting methods...    [*]                                                                        (1.3s @ 0.39GB)
[8/8] Creating image...       [*]                                                                        (1.3s @ 0.47GB)
   7.38MB (47.54%) for code area:     9,327 compilation units
   7.75MB (49.95%) for image heap:  123,075 objects and 35 resources
 399.45kB ( 2.51%) for other data
  15.52MB in total
------------------------------------------------------------------------------------------------------------------------
Top 10 origins of code area:                                Top 10 object types in image heap:
   5.13MB java.base                                            1.93MB byte[] for code metadata
   1.55MB svm.jar (Native Image)                               1.49MB byte[] for java.lang.String
 175.72kB jansi-2.4.1-SNAPSHOT.jar                           925.41kB java.lang.String
 145.67kB java.logging                                       690.28kB java.lang.Class
 132.50kB com.oracle.svm.svm_enterprise                      415.92kB heap alignment
  42.09kB jdk.proxy1                                         299.72kB java.util.HashMap$Node
  41.55kB jdk.proxy3                                         250.95kB byte[] for general heap data
  29.36kB org.graalvm.nativeimage.base                       178.65kB byte[] for reflection metadata
  28.88kB org.graalvm.collections                            162.94kB com.oracle.svm.core.hub.DynamicHubCompanion
  21.54kB jdk.internal.vm.ci                                 155.34kB byte[] for embedded resources
  31.12kB for 4 more packages                                  1.33MB for 952 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:
 G1GC: Use the G1 GC ('--gc=G1') for improved latency and throughput.
 PGO:  Use Profile-Guided Optimizations ('--pgo') for improved throughput.
 INIT: Adopt '-H:+StrictImageHeap' to prepare for the next GraalVM release.
 HEAP: Set max heap for improved and more predictable memory usage.
 CPU:  Enable more CPU features with '-march=native' for improved performance.
------------------------------------------------------------------------------------------------------------------------
                        1.3s (6.0% of total time) in 179 GCs | Peak RSS: 1.34GB | CPU load: 9.81
------------------------------------------------------------------------------------------------------------------------
Produced artifacts:
 /mnt/d/Projects/jansi/stty/target/jansi-2.4.1-SNAPSHOT (executable)
========================================================================================================================
Finished generating 'jansi-2.4.1-SNAPSHOT' in 20.5s.
glavo@glavo-desktop /m/d/P/j/s/target (stty)> ./jansi-2.4.1-SNAPSHOT
Jansi 2.4.1-SNAPSHOT

jansi.providers= musl
Selected provider: musl

os.name= Linux, os.version= 4.4.0-22621-Microsoft, os.arch= amd64
file.encoding= UTF-8
sun.stdout.encoding= null, sun.stderr.encoding= null
stdout.encoding= UTF-8, stderr.encoding= UTF-8
java.version= 21, java.vendor= Oracle Corporation, java.home= null

jansi.graceful=
jansi.mode=
jansi.out.mode=
jansi.err.mode=
jansi.colors=
jansi.out.colors=
jansi.err.colors=
jansi.passthrough= false
jansi.strip= false
jansi.force= false
jansi.noreset= false
org.fusesource.jansi.Ansi.disable= false

IS_WINDOWS: false

isatty(STDOUT_FILENO): 1, System.out is a terminal
width(STDOUT_FILENO): 229
isatty(STDERR_FILENO): 1, System.err is a terminal
width(STDERR_FILENO): 229

Resulting Jansi modes for stout/stderr streams:
  - System.out: AnsiPrintStream{type=Native, colors=Colors256, mode=Default, resetAtUninstall=true}
  - System.err: AnsiPrintStream{type=Native, colors=Colors256, mode=Default, resetAtUninstall=true}
Processor types description:
  - Native: Supports ansi sequences natively
  - Unsupported: Ansi sequences are stripped out
  - VirtualTerminal: Supported through windows virtual terminal
  - Emulation: Emulated through using windows API console commands
  - Redirected: The stream is redirected to a file or a pipe
Colors support description:
  - Colors16: 16 colors
  - Colors256: 256 colors
  - TrueColor: 24-bit colors
Modes description:
  - Strip: Strip all ansi sequences
  - Default: Print ansi sequences if the stream is a terminal
  - Force: Always print ansi sequences, even if the stream is redirected

image

Process process = null;
try {
process = new ProcessBuilder(command)
.redirectInput(ProcessBuilder.Redirect.INHERIT)
Copy link
Member

@gnodet gnodet Oct 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's slightly wrong. The terminal width usually refer to the output rather than the input. See how it's handled in MingwSupport above. Else, a call such as echo foo | jansi would fail...

Btw, we may want to port the change I made earlier in JLine related to this: https://github.com/jline/jline3/pull/868/files

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I refactored MingwSupport to reuse its.

Copy link
Member

@gnodet gnodet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to align with mingw support.

@Glavo Glavo marked this pull request as draft October 4, 2023 06:50
@Glavo Glavo marked this pull request as ready for review October 4, 2023 09:31
@Glavo Glavo marked this pull request as draft October 4, 2023 09:31
@Glavo Glavo requested a review from gnodet October 4, 2023 09:31
@Glavo
Copy link
Contributor Author

Glavo commented Oct 4, 2023

I have updated this PR and hope to have it reviewed again.

However, before it is merged, I would like to rename the provider. musl is not an appropriate name as it also works with glibc or macOS.

@Glavo Glavo marked this pull request as ready for review October 4, 2023 12:46
@Glavo
Copy link
Contributor Author

Glavo commented Oct 4, 2023

I finally decided to rename the provider to native-image.

@rsenden
Copy link

rsenden commented Oct 10, 2023

@Glavo Many thanks for working on this, looking forward to see this included in an upcoming Jansi release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants