Thursday, 4 June 2026

Angular Signals

Angular introduced Signals1 in Angular 17. You can find a mention of it in the release notes3 along with other fantastic goodies. From what I hear it's a big thing that solves some of the problems with updating two-way data-bindings without having to go through the entire tree of components and examining all the state (wich zone.js used to do.)

However, it's not a one-size-fits-all. Observables are still highly relevant, it's just that sometimes you use Signals and sometimes you use Observables2.

From what I gather, Signals can be used for highly synchronous code and one of those is to use them in the UI. Where Observables are convenient if the value is not immediately available (so time-based) like with REST calls.

You can learn about it all and try it out at [4], apparently.

There's plenty of youtube videos out there that introduce the concept too, apparently.

References

[1] Angular - Angular Signals
https://angular.dev/guide/signals
[2] Medium - Angular Signals: Best Practices
https://medium.com/@eugeniyoz/angular-signals-best-practices-9ac837ab1cec
[3] Angular Blog - Introducing Angular v17
https://blog.angular.dev/introducing-angular-v17-4d7033312e4b
[4] Angular Home
https://angular.dev/

Monday, 25 May 2026

Azul completed its acquisition of Payara in December 2025

Azul, the guys from the Zulu JDK, has aquired Payara.

I thought I'd mention it here, as I am using Payara in my hobby project.

There's a message on what it means for the Community version of Payara at [1] on https://foojay.io.

References

[1] foojay.io - A New Chapter for the Payara Community
https://foojay.io/today/a-new-chapter-for-the-payara-community/

Saturday, 11 April 2026

Desktop Icons on GNOME

GNOME has traditionally always been one to prefer the benefits of a clean Desktop.

But I'm not one for traditions.

There's an GNOME extention available called Desktop Icons NG (DIN)1.

What I needed to do was:

  • copy the application file (thingy.desktop) from /usr/share/applications somewhere and then drag it onto my Desktop.
  • Make it Executable
  • Set it to "Allow launching"

References

[1] Desktop Icons NG (DING) by rastersoft
https://extensions.gnome.org/extension/2087/desktop-icons-ng-ding/

Wednesday, 8 April 2026

VoxxedDays 2026

So, I went to VoxxedDays on April 1st and 2nd.1

Some of it was very interesting, and I've retained some notes and links written below.

Spec-driven development2
It seems to be a way to specify the wanted behaviour of your software in such a way that AI can successfully create your software based on your spec. Not entirely convinced of this.
Lion3
Lion is a set of highly performant, accessible and flexible Web Components.
PicNic4

PicNic is a online greengrocer/supermarket which is running a Blog on the challenges on scaling up. Quite interesting.

Some interesting things for example are providing fresh products (bread for instance) within a certain timeframe.

Programming Rules your IDE can tell you about.
https://github.com/jborgers/PMD-jPinpoint-rules
Compressed OOPs in the JVM
https://www.baeldung.com/jvm-compressed-oops
A good explanation of generics
https://bramjanssens.nl/generics/
Reduce Object Header Size and Save Memory in Java 25
https://www.baeldung.com/java-object-header-reduced-size-save-memory

The sessions are online now at YouTube. See [5].

References

[1] VoxxedDays Amsterdam
https://amsterdam.voxxeddays.com/
[2] What Is Spec-Driven Development? A Complete Guide
https://www.augmentcode.com/guides/what-is-spec-driven-development
[3] Github - Ing/Lion
https://github.com/ing-bank/lion
[4] PicNic - Blog
https://blog.picnic.nl/
[5] YouTube - VoxxedDays 2026 Sessions
https://youtube.com/playlist?list=PLRsbF2sD7JVoK114W2u9HTK4ftHn_taT1&si=WmiCtfuhEyTtu0lg

Monday, 16 March 2026

Kotlin: lots of functions

I like Kotlin (sometimes) as it has a large and rich number of convenient functions to use.

In Java, we tend to reach for our Guava1 or Apache Commons Lang2 to get the same functionality.

But it does tend to make it a bit hard to decide which to use, especially as I (as most people I hope) do not know the entire dictionary of available functions in Kotlin.

Luckily there's of course colleagues who can help, and my IDE also does a pretty good task of suggesting better ways.

Case in point:

val items : List<Items> = getItems()
val coupon: Coupon? = items.map { it.coupon }.filter { it != null }.firstOrNull()

I do know the code above can be made simpler.

val items : List<Items> = getItems()
val coupon: Coupon? = items.mapNotNull { it.coupon }.firstOrNull()

There, the mapNotNull() is a very convenient function that I use all the time.

But this time my IDE complained again and told me to use .firstNotNullOfOrNull

val items : List<Items> = getItems()
val coupon: Coupon? = items.firstNotNullOfOrNull { it.coupon }

It's fine by me, to use this, but I didn't know this function exists.

Also, the name seems a bit long and it took a minute to understand the meaning.

References

[1] GitHub - Google Guava
https://github.com/google/guava
[2] Maven Repository - Apache Commons Lang (3)
https://mvnrepository.com/artifact/org.apache.commons/commons-lang3

Thursday, 12 February 2026

AssertJ + AutoCloseableSoftAssertions + Kotlin

I've been playing around with AutoCloseableSoftAssertions, as I don't want to have to remind myself to call .assertAll()

But I also wanted to see if I can replace entire rows of assertThat statements in a simple manner, without many changes.

And I think I have found a way in Kotlin.

Let's start with the basics:

Let's try some SoftAssertions, so we can have many asserts that are all evaluated, instead of the Test stopping upon the first failed assert.

Okay, now AutoCloseableSoftAssertions is a convenient class that calls the .assertAll() as part of the final block in a try-with-resources:

Now, in the case above, we have to prefix our assertThat() calls with "it.". There's one more step that we can use to remove this.

Wrapping all this in a function for easy use will end up in:

Now, a stack of assertThat() statements can be encompassed with assertAll{} without any other changes to get the full advantages of SoftAssertions.

Might be overkill, but this was a fun example in Kotlin.

Try-with-resources

So you might have noticed that AutoClosableSoftAssertions is used in a try-with-resources block.

The small advantage you have, is that if there is an unexpected Exception thrown during your asserts, the ".assertAll()" will still be called, because it's part of the "AutoCloseable.close()".

I don't know how much this advantage is, as the unexpected Exception breaks the test anyways, but there it is.

Thursday, 5 February 2026

Retrieving Bookmarks from your Firefox - The Hard Way

Yeah, so I turned my old workstation into a server and no longer have access using a graphical interface.

Normally, this is fine, as I am using it as a server.

But I forgot to export my Firefox bookmarks.

Hopefully I can examine the sqllite database using reference [1] to retrieve my bookmarks.

I open the file /home/mrbear/.mozilla/firefox/xvosm5y9.default/places.sqlite and selecting the tab "Browse data" found the table moz_bookmarks.

It contains all bookmarks and folders and contains references to the moz_places table (using the moz_bookmarks.fk).

The moz_places table contains the actual urls.

References

[1] DB Browser for SQLLite
https://sqlitebrowser.org

Monday, 26 January 2026

Git: Cleaning up

Sometimes, our IDE can make a mess of things (mostly because we did something wrong, though).

And in order to fix it, sometimes we have to get rid of all unversioned files, so that we have a clean git repository and then create a new Project in our IDE.

This helps as it forces the IDE to recreate its config files from scratch.

This blog is just a small note on how to clean your git repository of all unversioned files.

A dry run would look like this:

git clean -n -x -d

A proper clean would look like this:

git clean -d -x

Options:

-n
dry run
-d
also recursively delete unversioned directories.
-x
ignore .git-ignore rules (convenient for cleaning up buildproducts and IDE config files)

Output of a dry run would look something like this:

% git clean -n -x -d
Would remove .DS_Store
Would remove .idea/
Would remove mrbear-parent/mrbear-app/target/
Would remove mrbear-stubs/.gradle/
Would remove mrbear-stubs/.kotlin/
Would remove mrbear-stubs/build/

See also "git restore" or "git reset".

References

git-clean - Remove untracked files from the working tree
https://git-scm.com/docs/git-clean

Thursday, 15 January 2026

Kotlin : NullSafety + Defaults

So, I had a discussion with my colleague about null safety and how it can be non-intuitive if you're not yet used to it.

So we had the following code:

In a lot of REST applications, an Exception may be thrown when a resource does not exist. But it's important to differentiate between "no resource" and "oh no! An exception occurred! We're in trouble!".

That's what this example code does.

So, what did the "getStatus" method do exactly?

This causes the test to fail.

The code should have been "?: false", but doing that does look weird.

A clearer solution would be:

The problem with Kotlin might be that there's alot of "?." and "?:" and "!!" and quite frankly it makes it hard to read.

What do you think?

Sunday, 11 January 2026

Trying out the Github Command Line

So it's possible and quite convenient to use hardcode git commands to checkout Github repositories. It works fine, once you get the SSH keys sorted out and all that.

I tend to use IntelliJ to checkout new github repositories, as it is soo much easier to point and click.

This always happens to me, when I find myself having to do things I don't do often. Because once you have a repo checked out, that's basically the end of all the complicated stuff and you just get to work.

Checking out using Git

I still prefer using Git to checkout a new repository for now4.

The way this works is just do "git clone git@github.com:username/repo.git". You can find this url in the repository on the GitHub website.

However, an ssh key must be available on your GitHub account for the computer/client you're using.

First generate such an ssh key on your computer, using reference [5].

For example: "ssh-keygen -t ed25519 -C "mrbear@mrbear.com"".

Add your ssh key to the ssh-useragent, using "ssh-add ~/.ssh/id_ed25519".

You should see:

$ ssh-add ~/.ssh/id_ed25519
Enter passphrase for /home/mmrbear/.ssh/id_ed25519:
Identity added: /home/mrbear/.ssh/id_ed25519 (mrbear@mrbear.com)

Then you can add the generated key to your Github account using the website, using reference [6].

After that, you can finally just clone your repo as mentioned above.

Installation

GitHub has a command line interface nowadays1. It's easy to install2.

I'm using Fedora, so all it takes on my end is to "sudo dnf install gh".

There used to be a tool called "hub", apparently, which is basically a git wrapper for GitHub. It was an unofficial tool. You can find the differences discusses in [3].

Using the CLI

Logging in using "gh auth login".

$ gh auth login
? Where do you use GitHub? GitHub.com
? What is your preferred protocol for Git operations on this host? SSH
? Upload your SSH public key to your GitHub account? Skip
? How would you like to authenticate GitHub CLI? Login with a web browser

! First copy your one-time code: DFGF-JFDB
Press Enter to open https://github.com/login/device in your browser...
✓ Authentication complete.
- gh config set -h github.com git_protocol ssh
✓ Configured git protocol
✓ Logged in as mrbear

Then the command "gh issue list" shows me open issues.

Works! Quite nice!

References

[1] GitHub - Take GitHub to the command line
https://cli.github.com/
[2] Installing gh on Linux and BSD
https://github.com/cli/cli/blob/trunk/docs/install_linux.md
[3] GitHub - GitHub CLI & hub
https://github.com/cli/cli/blob/trunk/docs/gh-vs-hub.md
[4] GitHub - Cloning a repository
https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository
[5] GitHub - Generating a new SSH key and adding it to the ssh-agent
https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
[6] GitHub - Adding a new SSH key to your account
https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account

Sunday, 28 December 2025

NFS - Network File System

Network File System (NFS) is used to mount external sources of files between Linux/Unix servers.

Nowadays, I think most people use SAMBA (SMB) as that also allows Windows to join the club, but I decided to try NFS (again).

I used to work with NFS back in the past, but it seems to still be viable.

On the server

We will be sharing the directory /mnt/raid.

I've edited the file /etc/exports.d/raid.exports to contain2:

/mnt/raid 192.168.2.0/24(rw,sync,no_root_squash)
rw
read and write access
sync
is the default, makes certain new requests only get a reply when changes have been committed to stable storage
no_root_squash
By default root files are re-mapped to nobody, to prevent write-access etc. in my case, I wish to edit files using root. I don't mind the security consequences very much in my home situation

To apply changes to this file, run "exportfs -ra" or restart the NFS server.

Start services:

# systemctl start nfs-server.service
# systemctl enable nfs-server.service

On the client

To view all mountable directories of a certain server, try this:

# mount | grep raid
watson:/mnt/raid on /mnt/raid type nfs4 (rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,fatal_neterrors=none,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.2.1,local_lock=none,addr=192.168.2.6)

Or of course try "cat /proc/mounts".

Then, on the client, mount the directory:

# mount -t nfs -o vers=4 watson:/mnt/raid /mnt/raid

Surprisingly, I did not have to actually change any configuration of the NFS service.

Works surprisingly well.

References

[1] Fedora Server User Documentation - File sharing with NFS – Installation
https://docs.fedoraproject.org/en-US/fedora-server/services/filesharing-nfs-installation/
[2] My Blog - My Current MDADM Setup
https://randomthoughtsonjavaprogramming.blogspot.com/2024/09/my-current-mdadm-setup.html

Friday, 12 December 2025

Git: Deleting old local branches

Just looking at old local branches. They tend to proliferate, especially if you have a release cadence.

To list the local branches (the default), or list the branches according to a pattern, see the two examples directly below.

git branch
git branch --list "V2022*"

Small explanation of the output of the command:

  • existing branches are listed
  • the current branch will be highlighted in green and marked with an asterisk
  • any branches checked out in linked worktrees will be highlighted in cyan and marked with a plus sign

I'm usually only interested in local branches, but "-r" shows remote-tracking branches and "-a" shows both remote and local branches, if you're interested.

Removing branches

git branch -D `git branch --list "V2022*"`

Bear in mind that branches that are used by a worktree cannot be deleted. Remove the worktree first.

Actually, I really like that behaviour.

Checking old branches

Apparently you can sort the list of branches based on last comitterdate.

git branch --sort=-committerdate # DESC

In the example above, you'll see branches that have been committed to recently at the top.

Finding a commit

This is nice, you can find which branches contain a certain commit quickly.

git branch --list --contains 089aafb331a08d19ed805fff6fea3846776980a0

Unfortunately, we're currently using git as a local repo, and svn remote, so there's a disconnect between commit hashes.

References

Git - git branch documentation
https://git-scm.com/docs/git-branch
StackOverflow - Can you delete multiple branches in one command with Git?
https://stackoverflow.com/questions/3670355/can-you-delete-multiple-branches-in-one-command-with-git

Friday, 28 November 2025

Kotlin: From List To Map

So I've been trying to make a Map from a List in Kotlin, and as I have not much experience with Kotlin and not much experience with Maps, I turn to the Internet.

Funnily enough, after getting it working, my IDE keeps giving me subtle hints that it can be shorter and more concise.

I thought it would be nice to put the steps here.

val primaryKeys = listOf(12L, 15L, 16L, 22L, 204L)
val firstTry = primaryKeys.map { it to getUser(it) }

In the example above it's not a Map yet, but it's a good first step.

As you can tell, it transforms your list into another List of type List<Pair<Long, User>>.

Kotlin has a toMap() method that does what we want.

    @Test
    fun testListToMapConversion() {
        val primaryKeys = listOf(12L, 15L, 16L, 22L, 204L)
        val map = primaryKeys.map { it to getUser(it) }.toMap()
        assertThat(map).isEqualTo(
            mapOf(
                12L to User(12L, "Bob"),
                15L to User(15L, "Jimmy"),
                16L to User(16L, "Jack"),
                22L to User(22L, "Henry"),
                204L to User(204L, "William")
            )
        )
    }

Now my IDE tells me this can be shortened.

    @Test
    fun testListToMapConversion() {
        val primaryKeys = listOf(12L, 15L, 16L, 22L, 204L)
        val map = primaryKeys.associate { it to getUser(it) }
        assertThat(map).isEqualTo(
            mapOf(
                12L to User(12L, "Bob"),
                15L to User(15L, "Jimmy"),
                16L to User(16L, "Jack"),
                22L to User(22L, "Henry"),
                204L to User(204L, "William")
            )
        )
    }

Now my IDE tells me this can be shortened AGAIN!

    @Test
    fun testListToMapConversion() {
        val primaryKeys = listOf(12L, 15L, 16L, 22L, 204L)
        val map = primaryKeys.associateWith { getUser(it) }
        assertThat(map).isEqualTo(
            mapOf(
                12L to User(12L, "Bob"),
                15L to User(15L, "Jimmy"),
                16L to User(16L, "Jack"),
                22L to User(22L, "Henry"),
                204L to User(204L, "William")
            )
        )
    }

Nice!

References

Syntax Highlighter
https://highlight.hohli.com/

Thursday, 20 November 2025

Kotlin: Redundant SAM constructor

Kotlin lambdas are fully compatible with Java functional interfaces.

But sometimes you need to give Kotlin a little nudge, using a SAM constructor.

SAM constructors (Single Abstract Method) allow you to convert a lambda expression to an instance of a functional interface. The syntax is pretty straightforward.

FunctionalInterfaceName { lambda_function }

The message in the title appears when you use a SAM constructor, when you don't have to. Kotlin is smart enough to create the appropriate anonymous class without us being specific in most cases.

I notice this happening sometimes when I have IntelliJ convert my Java class automatically to Kotlin.

A simple example:

// Java
public Builder addMapping(FieldMetadata field, Supplier<?> valueSupplier) {...}
// redundant Kotlin
val fieldMapping = FieldMapping.builder()
.addMapping(OrderItemField.ITEM_NR), Supplier { orderRepository.getOrderItem })
.build()
// correct Kotlin
val fieldMapping = FieldMapping.builder()
.addMapping(OrderItemField.ITEM_NR) { orderRepository.getOrderItem }
.build()

References

Medium - Idiomatic Kotlin: Lambdas and SAM constructors
https://medium.com/tompee/idiomatic-kotlin-lambdas-and-sam-constructors-fe2075965bfb

Thursday, 13 November 2025

Rename .java to .kt

So, I've suddenly recently noticed that whenever I commit a change into Git in IntelliJ that contains a conversion of a .java file into a .kt (Kotlin) file, IntelliJ will automatically make a previous commit containing the comment "Rename .java to .kt" which contains ONLY the renaming of the file.

I thought this was odd, but the reason behind it is that this commit helps Git to bind the two files together in the History.

If you do not have this single commit, (for example, if you're merging this to your integration branch or whatever and you squash your commits), you lose the history. It means Git will see the .java file as a file that has been deleted and the .kt file as a new file that has been added.

Some people complain, but it really depends on what is important to you:

  • do you want to preserve your history in Git for a file
  • or
  • do you want to see the changing the filename as belonging to your commit (and your ticketnumber in de comments)

Ideally, you should bear in mind IntelliJ does this, so you can at least edit the Commit Message of the renaming to include your ticketnr and original comment and such.

Settings

Can you turn this setting off? Yes, you can. There's a checkbox in the settings of the Git Commit dialog.

Unfortunately, this interesting setting only appears when you have indeed converted a Java file into a Kotlin file.

References

Kotlinlang - slack-chats
https://slack-chats.kotlinlang.org/t/465094/hi-i-ve-discovered-to-my-surprise-that-the-java-to-kotlin-co

Monday, 3 November 2025

JFall 2025

So last year I was unable to get tickets. They sold out pretty quickly (like in the first three minutes, I hear?).

I expected not to be able to attend this year either, but I added myself to the waiting list and hoped for the best.

Apparently, I was in luck! I have tickets!

I am planning on attending the following:

  • Catching the 137-Killer: A Java Memory Forensics Investigation
    Martijn Dashorst
  • Java; our personal career companion
    Peter Schuler Ragna Gerretsen
  • Why You Should Build Agents on the JVM
    Rod Johnson
  • Java 25 - Better Language, Better APIs, Better Runtime
    Nicolai Parlog
  • xz: The day the internet (almost) died
    Reinier Zwitserloot Roel Spilke
  • curl | bash | hacked: The Unseen Dangers in Your Dev Lifecycle
    Steve Poole
  • Benchmarking Project Valhalla
    Cay Horstmann
  • The Wait is Over: Foreign Function & Memory (FFM) API brings modern Java to the Raspberry Pi
    Frank Delporte

However, there's several that I also would have liked to see. I'll await those on the YouTubes.

It'll take place coming Thursday, 6th of November 2025.

References

NLJUG - JFall
http://jfall.nl/

Thursday, 23 October 2025

No "new" keyword in Kotlin

So I was wondering what my opinion is about that.

I don't like it a lot, as now it seems like calling a constructor looks similar to calling a method.

The only difference that's visible is that the constructor begins with a capital, and then only if you properly follow the coding style guidelines.

I noticed that where Java prefers clarity of purpose, Kotlin prefers brevity (and sacrifices clarity for this).

In Java the "new" keyword does a lot of heavy lifting, that is not part of the constructor. The constructor merely sets the internal structure of an object-to-be to appropriate values. The responsibility of actually making the object, registering it in de Heap, doing the pointer bits, is indicated by the new keyword.

What are your opinions?

References

Reddit - Is keyword new redundant?
https://www.reddit.com/r/java/comments/1n0m7cg/is_keyword_new_redundant/
Kotlin Documentation - Classes
https://kotlinlang.org/docs/classes.html

Thursday, 16 October 2025

Bridge Methods in Java

In Java, Generics are erased ("type erasure") at compile time. This concept introduces a problem where an abstract super class containing generics <T> will be compiled to abstract super class with "Object".

In which case implementation of this abstract class with specific Generics (say for example <String>) will cause the compiler to create Bridge Methods, in this case the someMethod(Object o) will call someMethod(String o) with an appropriate cast.

Reference [1] and [2] has a much better explanation

You won't find it in the JLS, as it is an implementation detail. But interesting none the less.

References

[1] Medium - Bridge Methods in Java
https://medium.com/@rohitsingh341/bridge-methods-in-java-21a9d06b6b1b
[2] The Java Tutorials - Effects of Type Erasure and Bridge Methods
https://docs.oracle.com/javase/tutorial/java/generics/bridgeMethods.html

Monday, 6 October 2025

Optional.or

Was working on something, and I wanted to combine two optionals. In my case, I know that only one of the two will be present (or none), so combining them would be nice.

I'm not a big fan of using .ifPresent() and .get() combos. So, let's try streams.

Using streams, this looks something like:

Luckily we have a Optional.or() nowadays (Since Java 9), that I haven't used before.

It looks a lot better:

The awesome part (which is not shown in the example above) is that the or() accepts a Supplier, which means the Supplier will not be called if a value is present in the first Optional.

This is similar to the short-circuit evaluation1 present in the || operator of the common if-statement.

References

[1] Wikipedia - Short-circuit evaluation
https://en.wikipedia.org/wiki/Short-circuit_evaluation
[2] Baeldung - Guide To Java Optional
https://www.baeldung.com/java-optional
[3] Combine two Java Optionals
https://www.agalera.eu/combine-two-optionals/

Friday, 29 August 2025

Growing the Java Language #JVMLS

Just a blorb to remind me of the presentation by Brian Goetz during 2025 JVM Language Summit.

which was made available on the YouTube1.

P.S. in the link above was a reference to a presentation (in written form) by Guy Steel2, that was insightful.

References

[1] YouTube - Growing the Java Language #JVMLS
https://youtu.be/Gz7Or9C0TpM?si=ejyjWLRKwSY05AKW
[2] Growing a Language - Guy L. Steel Jr.
https://www.cs.virginia.edu/~evans/cs655/readings/steele.pdf