spring-boot
spring-boot copied to clipboard
Enable ANSI output on Windows automatically
Windows supports ANSI encoding since Windows 10 version 1909. All you need to do is call ENABLE_VIRTUAL_TERMINAL_PROCESSING when calling console API.
IntelliJ does this automatically.
All software running via the new Windows Terminal, including Java, does this as well.

Old Windows command prompt doesn't do this by default for compatibility reasons, but new Java versions will make it possible for workaround even for older Windows versions https://stackoverflow.com/questions/74319252/printing-ansi-color-codes-in-java-works-on-vs-code-terminal-but-not-in-cmd
My proposal is to enable ANSI coloring on Windows by default.
Patch should be compatible with both 3.x and 2.7.x branches.
Old Windows command prompt doesn't do this by default for compatibility reasons, but new Java versions will make it possible for workaround even for older Windows versions
Thanks for the PR. Just so that I confirm I understood it, this PR would then break those clients, right? (by returning true instead of checking the windows flag). If so, I don't think we should merge this. Is there a way to check that ENABLE_VIRTUAL_TERMINAL_PROCESSING was set from the Java process?
It won't break, it will just show ANSI symbols in their raw form.
Sadly there is no easy way to check or set Windows API flags in Java process. At least not without using JNI, JNA or similar boilerplate alternative. As mentioned, JDK 19 preview has SymbolLookup.libraryLookup() implemented which would allow this directly, however even then Java needs to load kernel32.dll library to access Windows API, which is maybe a bit too much just for colors :)
I do not believe stripping Windows IntelliJ or Terminal users from automatic ANSI coloring for those running Spring Boot via old cmd is a great compromise.
If compatibility is such a big issue here, I think applying this to 3.x and mentioning in the Release notes would be enough. Anyone running old console can just disable it via spring.output.ansi.enabled=never
It won't break, it will just show ANSI symbols in their raw form.
That's what I meant by breaking. Going through a readable log (without colors) to this is certainly a behavioral breaking change.
If compatibility is such a big issue here, I think applying this to 3.x and mentioning in the Release notes would be enough. Anyone running old console can just disable it via spring.output.ansi.enabled=never
Compatibility is important. One can argue that those who can benefit from the improved support could set that exact same property, isn't it?
I agree. It's probably a matter of what user base is in majority: IntellJ/Eclipse/Windows Terminal users vs Windows cmd users. And not a question of if but when to break compatibility, else innovation stops completely.
In this day and age, I think breaking compatibility in 3.1.x is reasonable.
IMO, it's too late to make this change in 3.1.x as we don't have enough time to get feedback from the community. I think we should merge it early in 3.2 instead.
I'm not sure that we should merge this one or not. I think it might be quite annoying for those that still use cmd.exe. Perhaps we can take another look at https://github.com/fusesource/jansi which has a Kernel32 class implemented using JNI.
I have actually looked at jansi code before, but I could not come up with a working solution. My knowledge of Java is limited :|
If someone could come up with different solution that would be great, however in my opinion loading Kernel32.dll just for this reason is a little bit of waste of resources.
Thanks for the suggestion but we have decided that we do not want to merge this change as we feel that the risk of breaking existing users is too high. Those using a shell that supports ansi colouring can add SPRING_OUTPUT_ANSI_ENABLED=always to their environment. Thanks anyway for the PR.