I Bestow Upon Thee “HotkeyAutoExecute”, My Game Screenshot Automator

HotkeyAutoExecute is a simple single-window tool that lets you manage a list of frequently used hotkeys, of which one is repeatedly executed in configurable intervals.

That was the TLDR blurp, and now let’s get into the details. This tool scratches an itch I had in 2020 when I wanted to simplify the process of taking game screenshots for my reviews. During intense gameplay moments, it is difficult to focus on the game and press a keyboard shortcut to take an image of on-screen action. Therefore, I hacked something that would do the job but was not quite baked to be open-sourced as an application. I have changed that now, and boy, was it more complicated than I would have liked.

Read More »

Convert QKeySequence of QKeySequenceEdit to Native Windows Virtual Key Codes VK_*

In a blog post in 2020, I described how to utilize the WinAPI SendInput() function to emulate hotkey presses to automatically take game screenshots for my video game reviews. While I intended to create a simple GUI application to do the task, I ended up with only a hack because of a massive boulder that Windows threw in my way. Or after me, chasing me down a narrow path.

Forget the boulder.

(Although it would be a fitting metaphor to describe Windows: tall, fat, and destructive to user privacy.)

I wanted a simple input field where the user can press a key sequence that will be executed repeatedly at an interval. Qt conveniently provides QKeySequenceEdit for this purpose, and when I tried to insert the Xbox Game Bar hotkey, it did not register. Well, it did, in that Windows took a screenshot. But it was not recorded by the widget. Windows seems to intercept and eat the key presses. That was when I decided to just hard-code my needs and call it a day.

Two years later, I figured that it was about damn time to fix this, and this is where I ran into issues with the translation of key codes from QKeySequenceEdit and QKeySequence to native Windows virtual key codes.

This is where our adventure begins.

Read More »

Spring Boot @RestController Action Returning java.util.Optional

Recently, I wondered what would happen if a Spring Boot RestController returned a java.util.Optional instead of a regular POJO.

I invested 30 minutes of my life to find out, and created an over-engineered example on GitHub.

Here is the controller.

@Slf4j
@RestController
@RequiredArgsConstructor
public class MusicController {

    private final MusicService musicService;

    @GetMapping(path = "/value")
    Album getValue(@RequestParam("isNull") boolean isNull) {
        log.info("Request album value (is null: {})", isNull);
        return musicService.getAlbumAsValue(isNull);
    }

    @GetMapping(path = "/optional")
    Optional<Album> getOptional(@RequestParam("isNull") boolean isNull) {
        log.info("Request album optional (is null: {})", isNull);
        return musicService.getAlbumAsOptional(isNull);
    }
}

The first question I had was if Spring Boot would even start up. You never know. It does, and with this hurdle out of the way, here’s the output of a couple of curl commands.

~ % curl -i 'http://localhost:8080/value?isNull=false'   
HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Sun, 24 Jul 2022 08:24:50 GMT

{"artist":"Insomnium","title":"Winter's Gate","genre":"Melodic Death Metal","year":2016} 

~ % curl -i 'http://localhost:8080/value?isNull=true'    
HTTP/1.1 200 
Content-Length: 0
Date: Sun, 24 Jul 2022 08:24:55 GMT
 
~ % curl -i 'http://localhost:8080/optional?isNull=false'
HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Sun, 24 Jul 2022 08:25:00 GMT

{"artist":"Insomnium","title":"Winter's Gate","genre":"Melodic Death Metal","year":2016} 

~ % curl -i 'http://localhost:8080/optional?isNull=true' 
HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Sun, 24 Jul 2022 08:25:06 GMT

null

Everything works as expected except for the null-case with the Optional. It returns the string “null” instead of nothing.

The moral of the story: Do not return java.util.Optional from a @RestController, or you need to do more work to unpack it.

Thank you for reading.

Simplify Spring Boot Access to Kubernetes Secrets Using Environment Variables

This blog post is a follow-up to a previous blog post titled “Simplify Spring Boot Access to Secrets Using Spring Cloud Kubernetes“. Despite the downsides I mentioned, I already hinted at a more straightforward solution that utilizes environment variables. The plan is to get everything into the Pod with as little configuration effort as possible.

So, I promised a twist, and here it is, thanks to one of my colleagues who pushed me in this direction. Kubernetes gives you yet another tool to handle Secrets in environment variables. This time, it is more convenient since you only point it to the complete Secret, not just a single value. Kubernetes will then make all key-value pairs available as individual environment variables.

Read More »

Simplify Spring Boot Access to Secrets Using Spring Cloud Kubernetes

This topic has its origin in how we manage Kubernetes Secrets at my workplace. We use Helm for deployments, and we must support several environments with their connection strings, passwords, and other settings. As a result, some things are a bit more complicated, and one of them is the access to Kubernetes Secrets from a Spring Boot application running in a Pod.

This blog post covers the following:

  1. How do you generally get Secrets into a Pod?
  2. How do we currently do it using Helm?
  3. How can it be improved with less configuration?
  4. Any gotchas? Of course, it is software.

I will explain a lot of rationales, so expect a substantial amount of prose between the (code) snippets.

Read More »

Apache Commons CLI Handling of –help

An odd thing about Commons CLI is that it has no built-in concept of a “–help” option. Other libraries, like JCommander do (which had other problems, or I would not have bothered with Commons CLI). As a result, you have to build it on your own. It is not enough to include it with all the other application options, especially if you use required arguments. Then it is impossible to only set the Help option.

You must implement a two-step process. See this demo application on GitHub that I created for another blog post. It shows this in action.

First, only parse for the Help option, and if it is present, print the help text and exit the application. To print the complete help text, you must add the other parameters first, though. Otherwise there would be only “–help”.

final var applicationOptions = example_2_Options();

final var options = example_2_Help();
final var cli = parser.parse(options, args, true);

if (cli.hasOption(help)) {
    // Append the actual options for printing to the command-line.
    applicationOptions.getOptions().forEach(options::addOption);
    new HelpFormatter().printHelp("external-config-commons-cli", options);
    return;
}

Second, if no help is requested, parse for the application options.

final var cli = parser.parse(applicationOptions, args, true);

applicationOptions.getOptions().forEach(opt -> {
    if (cli.hasOption(opt)) {
        System.out.printf("Found option %s with value %s%n",
                opt.getOpt(), cli.getOptionValue(opt));
    }
});

Thank you very much for reading. I hope this was helpful.

Spring Boot Externalized Config on Command Line With Apache Commons CLI – Missing Required Option

I know this title is a bit of a mouthful, but you need to get all the keywords in for Google to do its magic 😉. In the previous blog post, I mentioned that I would take another look at this topic through the lens of a programmer that uses Apache Commons CLI for command-line argument handling. In a project for work, I noticed some odd error messages claiming that a command-line option did not have a value assigned to it, although it obviously did.

A more extensive set of examples can be found in the README file on GitHub, together with the code.

The sole reason for this blog post is how unknown parameters from the view of Commons CLI can mess up the parsing. The demo application defines two required Options – one for input (“-i” or “–input”) and one for output (“-o” or “–output”). Consider this command where I also set a Spring configuration setting.

% java -jar target/external-config-commons-cli-1.0.0.jar --spring.config.additional-location=src/config/application-mac.yml -i in -o out
-> AppRunner.run() Command Line Arguments
Argument: --spring.config.additional-location=src/config/application-mac.yml
Argument: -i
Argument: in
Argument: -o
Argument: out
-> ExternalConfigProperties
Input path: /Users/mac/thecode
Output path: /Users/mac/slinger
-> Parsing Help With Apache Commons CLI
-> Parsing Arguments With Apache Commons CLI
Missing required options: i, o

Both options are clearly there. The raw output of the String… args array shows that. By default, Commons CLI complains about unknown options. I disabled that behavior by setting stopAtNonOption to true. The parameter’s name makes no sense to me because it does not stop, but I might misinterpret something.

Either way, I assume that Commons CLI expects an option and a value by default. –spring.config.additional-location=src/config/application-mac.yml is a continuous string, an option without a value – at least to Commons CLI. Then it reads -i as the value to that option, and from there, the parsing goes south. The actual options are interpreted as values now.

Note, though, that Spring still accepts the configuration setting.

How can we fix that? There are two ways to do that:

  1. Add the Spring arguments at the end of the command line.
  2. Use the JVM-style Spring arguments with “-D”, as alluded to in the other blog post.

Putting the argument at the end:

% java -jar target/external-config-commons-cli-1.0.0.jar -i in -o out --spring.config.additional-location=src/config/application-mac.yml
-> AppRunner.run() Command Line Arguments
Argument: -i
Argument: in
Argument: -o
Argument: out
Argument: --spring.config.additional-location=src/config/application-mac.yml
-> ExternalConfigProperties
Input path: /Users/mac/thecode
Output path: /Users/mac/slinger
-> Parsing Help With Apache Commons CLI
-> Parsing Arguments With Apache Commons CLI
Found option i with value in
Found option o with value out

Using the JVM-style:

% java -Dspring.config.additional-location=src/config/application-mac.yml -jar target/external-config-commons-cli-1.0.0.jar -i in -o out
-> AppRunner.run() Command Line Arguments
Argument: -i
Argument: in
Argument: -o
Argument: out
-> ExternalConfigProperties
Input path: /Users/mac/thecode
Output path: /Users/mac/slinger
-> Parsing Help With Apache Commons CLI
-> Parsing Arguments With Apache Commons CLI
Found option i with value in
Found option o with value out

Thank you very much for reading. I hope this was helpful.

Spring Boot Externalized Config on Command Line

Spring Boot applications do not always have to serve as a web service located on the Internet. You can also use Spring Boot (or Spring without the Boot) for a command-line utility. I was recently faced with this task, and one requirement for the tool was to support setting a profile-specific configuration on the command line. This isn’t earth-shattering per se since that is a regular Spring feature. The goal was to provide a profile-specific configuration file on the command line that is not bundled in the application.

Imagine developing a Cloud service and running different environments for the different phases of your project – one for development tests, a staging environment, and, finally, the production environment. Connecting to the different environments may require secrets you do not want to be bundled in the application – and, thus, the source tree.

Now, you could roll your own configuration file reader. But wouldn’t it be nice to make full support of Spring’s @Value annotation or @ConfigurationProperties classes?

Read More »

Create Native Java Executable using jpackage – Sort of

I have always been the kind of developer who prefers to use native code and write native code. My background is in C++, and I have worked with Microsoft’s WinAPI early in my career. That is to say: I like it fast, and I do not mind going to lower levels.

I am not stuck in the past, though, and as such, I, too, have evolved with the times. I still like C++, but I also see how languages like Java and its great tooling can boost productivity in comparison. As a result, I write code fast. Java is the tool of the trade at my current job, and performance usually is not a problem anymore. The JVM has improved, and computer hardware has, so performance is usually not an issue anymore.

There is one little problem, however: Usage. Let me explain.

Read More »

Apple Silicon M1 for Software Development: Java, C++ with Qt

Apple’s laptops have been making quite the splash since the end of 2020 and have made a massive comeback as a professional tool one year later with the M1 Pro and Max designs. Most of the reviews I have seen focus on the editing and rendering capabilities of these new MacBooks. A few reviewers throw a compile test in the mix, but compiling Chromium or any other huge project is only a part of the equation. Developers don’t just compile code; they also use tools and IDEs to develop their software.

Being new to the M1 world, I wanted to recap my experiences so far briefly. I use Java professionally, and I also have a C++ application based on the Qt framework that I wrote an eon ago and still use productively. Being a former C++ professional, I am about native performance, and I like native software. Therefore, I intended to utilize as many Apple Silicon-native tools as possible. Luckily, one year after its release to the desktop world, the most popular applications have caught up. Let me go through my tool suite one by one.

Read More »

C# Delegate, Action, Func, Predicate Explained

Depending on your entry point to delegates, the documentation might look a tad confusing at first. For me, it was The delegate type section of the C# language reference. It throws around terms like Action, Func, Events, custom delegate types. Predicate is also related to this topic, and this was what I was looking for.

Let me briefly explain what all those words mean and how they relate to delegate. Then I will explain why I was looking into this.

Short teaser: “Named Predicate”, like a Hibernate Named Query.

Read More »

Emulate Java Enums With Values in C# (Pt. 2, Improved With Conversion Operator Overload)

In a previous blog post, I demonstrated how Java’ enums that contain one or more values/objects can be emulated with C#. One thing bothered me, though: the switch statement and how inconvenient it was to determine the proper type. Worst of all, it was not type-safe. In my simple example, it was easy because I was using strings. Imagine your fake-enum does not contain a string to quickly identify the instance.

Well, there is a prettier workaround – and it involves an actual enum. I was thinking about how the same could be done in C++ and in C++, you can have type conversion operators. Then I searched if such a feature also exists in C#, and sure enough, it does.

Read More »

Emulate Java Enums With Values in C#

Update August 28, 2021

I have written a follow-up that improves on the following solution using a type conversion operator overload.

When I started dabbling in C#, I wondered if it supports values in enums. In Java, an enum instance can have properties (called fields in Java lingo) associated with the enum’s literals. By taking advantage of this feature, you can encode more information in an enum, like a string, for example, or a constant number. You can even embed instantiated class objects, maybe to associate an object factory with a literal.

In my use case, I wanted to achieve a form of a key-value-pair mapping. I require certain illegal characters in the NTFS file or directory names to be replaced with a given code. I use HTML encoding for my needs because I can simply look up the values online if I need to.

Here is the Java reference example. First, let me start with the basic enum definition (I use Lombok to auto-generate boilerplate code like the constructor and accessors).

@Getter
@RequiredArgsConstructor
enum CharacterReplacementCode  {
    COLON(":", "&58;"),
    POUND("#", "&35;"),
    QUESTION_MARK("?", "&63;"); 

    private final String character;
    private final String replacement;
    
    @Override
    public String toString() {
        return String.format("Character '%s' substituted by code '%s'", character, replacement); 
    }
}
Read More »

Terraform Azure Error SoftDeletedVaultDoesNotExist

I just ran into a frustrating error that seemed unexplainable to me. My goal was to replace an existing Azure Resource Group with a new one managed entirely with Terraform. Besides a few other errors, this SoftDeletedVaultDoesNotExist was incredibly confusing because no more Key Vaults were found in the Resource Group’s list of resources.

Error: creating Vault: (Name "my-fancy-key-vault" / Resource Group "The-Codeslinger"): 
keyvault.VaultsClient#CreateOrUpdate: Failure sending request: StatusCode=0 -- 
Original Error: Code="SoftDeletedVaultDoesNotExist" 
Message="A soft deleted vault with the given name does not exist. 
Ensure that the name for the vault that is being attempted to recover is in a recoverable state. 
For more information on soft delete please follow this link https://go.microsoft.com/fwlink/?linkid=2149745"

with module.base.azurerm_key_vault.keyvault,
on terraform\key_vault.tf line 9, in resource "azurerm_key_vault" "keyvault":
    9: resource "azurerm_key_vault" "keyvault" {

That is because it was soft-delete enabled. And it was the Key Vault from the other Resource Group that I previously cleared of all resources, not the new Resource Group.

Using the az CLI you can display it, though.

> az keyvault list-deleted
[
    {
        "id": "/subscriptions/<subscription-id>/providers/Microsoft.KeyVault/locations/westeurope/deletedVaults/my-fancy-key-vault",
        "name": "my-fancy-key-vault",
        "properties": {
            "deletionDate": "2021-08-02T09:39:29+00:00",
            "location": "westeurope",
            "purgeProtectionEnabled": null,
            "scheduledPurgeDate": "2021-10-31T09:39:29+00:00",
            "tags": {
                "customer": "The-Codeslinger",
                "source": "Terraform"
            },
            "vaultId": "/subscriptions/<subscription-id>/resourceGroups/My-Other-ResourceGroup/providers/Microsoft.KeyVault/vaults/my-fancy-key-vault"
        },
        "type": "Microsoft.KeyVault/deletedVaults"
    }
]

And finally delete it.

> az keyvault purge --name my-fancy-key-vault

After that, it is gone.

$ az keyvault list-deleted
[]

Another option seems to be the Azure Portal, but I discovered this only after removing it on the command line.

Qt6 QtCreator Crash After Install on Ubuntu 21.04

Hopping Linux distributions, I came to Ubuntu 21.04, and one of the first things I do is install Qt manually. I have described the process in a previous blog post on Linux Mint, and it is the same for Ubuntu. Except for a tiny detail. On Ubuntu, the bundled QtCreator immediately crashes and triggers a "Send Diagnostic" dialog.

$ /opt/Qt/Tools/QtCreator/bin/qtcreator
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was 
found. This application failed to start because no Qt platform plugin could be 
initialized. Reinstalling the application may fix this problem.

Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, 
xcb.

The fix is simple.

sudo apt install libxcb-xinerama0

I hope this helps. Thank you for reading.