crush depth

JDK 21

Like many people, I've been waiting for JDK 21 for a long time. Now that Eclipse Temurin has JDK 21 builds, I'm finally now starting the push to upgrade all of my projects to JDK 21.

Primarily, I'm interested in pattern matching for my existing code. I wrote an article back in 2016 investigating the various ways that people have implemented algebraic data types on the JVM.

Since then, sealed classes have been added to the JVM. Sealed classes allow for specifying that a group of classes form a closed set, and the compiler can then reason about the set as a whole. Unfortunately, up until JDK 21, there was effectively no way to safely pattern match on a value of a sealed class. The old way to do this was via the visitor pattern, which frankly noone would have done by choice if there'd been any other alternative.

Knowing that pattern matching was due to become a first-class language feature (but didn't know exactly when), I've been writing code that looks like this for the past couple of years:

    if (message instanceof final NPACommandType<?> command) {
      return toWireCommand(command);
    }
    if (message instanceof final NPAResponseType response) {
      return toWireResponse(response);
    }
    if (message instanceof final NPAEventType event) {
      return toWireEvent(event);
    }
    throw new IllegalStateException();

Why write this kind of obviously-fragile code? My reasoning was that there would be a more direct migration path from this kind of if-then-else over sealed classes than there would be had I made every single class I wanted to match on implement a visitor. I'm hoping that Intellij IDEA will offer to convert the above code into an exhaustive switch statement when I set the language level to JDK 21. Time will tell!

Journey To The ... Earth

I bought a Yamaha Pacifica PAC120H a while back. I wanted a guitar that I could use as a testbed for hardware experiments. Ideally, an inexpensive guitar, so that I wouldn't care too much about ruining it. I've played a lot of guitars over the years, so I was pretty shocked when this almost-bottom-of-the-range instrument turned out to be one the best sounding and best feeling guitars I'd ever played.

It did, however, have a slight grounding issue (the guitar would quietly hum until you touched any metal component). It was also fairly noisy when the coil split was engaged. This isn't exactly unexpected; when the coil split is engaged, one of the coils is disabled and therefore the hum cancelling property of the humbucker is also disabled.

I'd heard of people applying shielding to the interiors of guitars in order to reduce noise, so I decided to try it. Shielding essentially involves covering every surface of the guitar's internal cavities with conductive material. There are lots of options here, but the cheapest and simplest appears to be common garden copper tape (with conductive adhesive).

I bought a couple of rolls of this:

Kraftex Copper Tape

I tested it with a multimeter and it had roughly the expected resistance for copper of that thickness. I also checked that the adhesive was actually conductive, and it did appear to be.

I opened the guitar, and was presented with bad wiring. The Pacifica series has a slightly frustrating design where it's simultaneously front-routed and rear-routed. Most guitars pick one or the other, so that when you're doing work on the internals, you don't have to work on both sides of the guitar simultaneously. The wiring was chaotic, and wired in an order that meant desoldering many components just to move one wire:

Internals 1 Internals 2

The wiring also followed the horrific guitar convention of soldering every ground cable to the volume pot, resulting in a giant compost heap of solder:

Heap

I ended up ripping out all the components in the process of applying shielding to the cavity:

Shielded 1 Shielded 2

Unfortunately, the ground pin of the volume pot had been mutilated in the process of soldering the pin to the casing along with everything else. Clearly someone just grabbed the pin with a pair of needle-nose pliers and bent it around as hard as they could until it made contact with the casing. Rather than try to fix that mess, I replaced the volume pot with something with the same specifications.

I took off the scratchplate and shielded it and all the front cavities too, leaving plenty of excess so that the back of the scratchplate would be in contact with the internal shielding in as many places as possible.

Shielded 3

With a fresh volume pot in place, I didn't want to repeat the convention of soldering everything to it. I fabricated a little block with some screw-in terminals on it that could be mounted inside the back cavity that essentially provided a solderless connection to ground for all of the things that needed to be connected to ground.

Ground 0

Unfortunately, I constructed the board such that the screw terminals ended up mounted too high in the cavity. This meant that, with (or without) cables plugged into it, there would be no way to get the backplate on without squashing the cables somewhat.

Continuing the theme of overengineering, I decided the best and most compact way to get a good quality ground connection would be to have a small PCB made with eight side-mounted screw terminals on it. The small cavity makes it extremely difficult to get any kind of screwdriver into the cavity in order to loosen or tighten screws, so I decided that the most pleasant way to work would be to have something that could be attached and detached without tools that could host the connections. It would then no longer be necessary to try to jam a screwdriver into the cavity to work on anything.

I put together the most idiotic circuit ever designed in KiCad:

Grounding Schematic Grounding PCB

I uploaded the resulting Gerber files to pcbway and had some nice printed PCBs a week later. After soldering on the screw terminals the result was obviously far better than the original perfboard construction:

Ground 0

I didn't want to fix the PCB directly to the guitar. I instead designed and printed a small mounting plate that could be hooked onto a pair of wood screws inside the cavity.

Plate

Mounting the plate and PCB inside the cavity was painless, and the resulting solderless connections are solid. I subjected them to more-than-the-minimum amount of violence, and was unable to get the wires to come out of the connectors when screwed in.

Mounted 0 Mounted 1 Mounted 2

With the backplate back on, I strung the guitar with the cheapest, worst strings I could find (as I fully expected to have to take the strings off again to fix one or more accidental grounding problems). I plugged the guitar in and ... it worked!

So was it all worth it?

Well, I took a recording of the guitar before I added the shielding. Compared with a recording taken with the new shielding and wiring in place... Noise levels are lower by 1dB. At least the wiring is now actually maintainable.

beforeAfter

Join us again next week when we disassemble a washing machine to reduce the length of the rinse cycle by 3.2 seconds.

New PGP Keys

It's that time of year again.

Fingerprint                                       | Comment
---------------------------------------------------------------------------
A438 A737 C771 7871 95CF C166 F843 51F7 2C91 8476 | 2023 personal
62AB 091D 563E 51BE 9E54 B680 7E20 DC73 5505 FE84 | 2023 maven-rsa-key
567B 7EA4 703E D530 5B73 3FBC 10C3 9A85 438F 996F | 2023 jenkins-maven-rsa-key

Keys are published to the keyservers as usual.

Boot Config

Did a pile of server updates today, and for some reason one specific VPS refused to boot with this error:

Boot error

It turned out I hadn't updated the boot code to handle the latest zpool version. There's a note about this buried at the bottom of the zpool administration chapter of the FreeBSD documentation:

https://docs.freebsd.org/en/books/handbook/zfs/#zfs-zpool

This would be fine, except I've literally never had to do this once on any number of physical machines or virtual machines over more than a decade of continual upgrades. I don't understand why it was suddenly a problem on this one machine.

I mounted a FreeBSD ISO into the virtual machine, booted from it, temporarily imported and mounted the zroot zpool to /mnt and ran:

# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 vtbd0

Exported the zpool again, and rebooted. Machine came up.

New PGP Keys

It's that time of year again.

Fingerprint                                       | Comment
---------------------------------------------------------------------------
2680 A50E FD03 2007 FABE 8C87 B0E4 322E EE81 8BDE | 2022 personal
3CCE 5942 8B30 462D 1045 9909 C560 7DA1 46E1 28B8 | 2022 maven-rsa-key
8EAE 10EA 3E8D F42F E58F CFD2 7863 6912 E065 EAD3 | 2021 jenkins-maven-rsa-key

Keys are published to the keyservers as usual.