Updating Lean to Avoid a Kernel Bug

I have been using Lean 4.27.0 from the beginning of the year for one of my formalization projects. I saw newer versions come along but didn’t want to have all my packages updated frequently and see all rebuilds and the associated OneDrive uploads. This is of course silly of me, but that’s how I kept going – until I saw a tweet about a lean kernel soundness bug reported in https://github.com/leanprover/lean4/issues/14576. The bug was fixed in v4.32.2. This is particularly interesting to me because it’s the first kernel bug I’ve seen since I started using lean (or really that’s been brought to my attention seeing as I might have been oblivious about previous ones, especially given my interest in avoiding any disruption updates might bring). I asked ChatGPT how to update my lean installation and walked through the steps:

saint@MacBookPro myproject % lake --version
Lake version 5.0.0-src+db93fe1 (Lean version 4.27.0)
saint@MacBookPro myproject % lean --version
Lean (version 4.27.0, arm64-apple-darwin24.6.0, commit db93fe1608548721853390a10cd40580fe7d22ae, Release)
saint@MacBookPro myproject % which lean
/Users/saint/.elan/bin/lean
saint@MacBookPro myproject % elan self update
info: downloading self-update
info: elan updated successfully to 4.2.3
saint@MacBookPro myproject % elan default leanprover/lean4:stable
info: default toolchain set to 'leanprover/lean4:stable'
saint@MacBookPro myproject % lean --version
Lean (version 4.27.0, arm64-apple-darwin24.6.0, commit db93fe1608548721853390a10cd40580fe7d22ae, Release)

The key step was updating my lean-toolchain file!

-leanprover/lean4:v4.27.0
+leanprover/lean4:v4.32.2

Once I did this, running lean --version downloaded the latest version.

saint@MacBookPro myproject % lean --version
info: downloading https://releases.lean-lang.org/lean4/v4.32.2/lean-4.32.2-darwin_aarch64.tar.zst
524.7 MiB / 524.7 MiB (100 %)  68.3 MiB/s ETA:   0 s
info: installing /Users/saint/.elan/toolchains/leanprover--lean4---v4.32.2
Lean (version 4.32.2, arm64-apple-darwin24.6.0, commit f3b06c705e6c85f5314019d5d3baab0fec5b580c, Release)
saint@MacBookPro myproject % lean --version
Lean (version 4.32.2, arm64-apple-darwin24.6.0, commit f3b06c705e6c85f5314019d5d3baab0fec5b580c, Release)
saint@MacBookPro myproject % 

I hope to dig into the lean implementation one of these fine days and better understand how a kernel bug like this comes about.


Categories: Python

No module named ‘encodings’ Stumps Python N00b.

I tried running a program on my desktop recently and got this error:

$ python myscript.py
Fatal Python error: Failed to import encodings module
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'

Current thread 0x0000b500 (most recent call first):
  <no Python frame>

I had realized that I was accumulating Python installations, so I uninstalled the older versions from my machine. I still had a valid 3.13 installation, so this error was confusing to me. I ensured there were no other versions on my machine.

$ python --version
Python 3.13.3

$ py -0
 -V:3.13 *        Python 3.13 (64-bit)

$ py -0p
 -V:3.13 *        C:\Python313\python.exe

I decided to uninstall 3.14 and install 3.14 since I’m in cleanup mode anyway. This gave me an opportunity to review the active python releases and their end of life dates on the Download Python | Python.org page. I found it interesting that the installer itself is being retired (here’s the More info link).

Once installation of 3.14 was done, I was surprised to find that the problem was still there!

$ python --version
Python 3.14.6

$ python myscript.py
Fatal Python error: Failed to import encodings module
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'

Current thread 0x00007edc (most recent call first):
  <no Python frame>

$ which python
/c/Python314/python

$ /c/Python314/python myscript.py
Fatal Python error: Failed to import encodings module
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'

Current thread 0x00007f60 (most recent call first):
  <no Python frame>

I consulted my AI assistant and its next recommendation was to check for corrupted environment variables! Look at this culprit!

$ echo $PYTHONHOME
C:\Python311\

All I needed to do to this fix was to clear the PYTHONHOME environment variable.

$ export PYTHONHOME=

I also deleted it from the “User variables for saint” section of the Environment Variables dialog box.


Categories: Chemistry

Discovery of O, Ar, and H

I am reading my McMurray chemistry textbook and realizing how fascinating the discovery of various elements was. I went looking for videos on the discovery of various elements, the first one being Argon. This video got me to appreciate the importance of publications for disseminating ideas. Rayleigh couldn’t explain the discrepancies between the density of atmospheric nitrogen and nitrogen obtained from a chemical reaction and this puzzle caught Ramsey’s attention. What followed was a series of intricate experiments and hypotheses until the noble gases were well understood years later.

The Incredible Discovery of the LEAST Reactive Elements (The Noble Gases)

While it’s incredible learning about how many of the elements we know today were discovered because you can see the scientific method at work, it’s fascinating that even scientists struggled to accept new theories that better explained the world than the ones they had long accepted. The story of the discovery of oxygen is one with examples of this phenomenon. The next video goes through the way people probed the inconsistencies in widely accepted ideas (like there being a component of matter called phlogiston that explains why it burns, etc) and how they came up with brilliant experiments to definitively reveal the existence of oxygen.

It’s interesting that oxygen wasn’t even known not that long ago – apparently only about 2 dozen of the 118 elements were known when the declaration of independence was signed. Videos like this are great because they also demonstrate that a good way to combat many anti-science arguments is by acknowledging when they find inconsistencies that aren’t explained by some widely accepted scientific view and observing that such inconsistencies mean that additional research and experimentation is required, not that the scientific method is broken. A basic understanding of the history of science also makes it easier (for me anyway) to study science since it tends to answer a lot of the “why is this important” questions we often have.

I also watched a video on The Origin of Avogadro’s Number and the video below was suggested at end. I was pleasantly surprised to find that it was a serious of almost 2 dozen videos on the history of chemistry. This is the type of background information that makes learning chemistry fun!

How Hydrogen Was Discovered

Categories: Visual Studio

Handy Visual Studio Installer Feature

I want to write a VS extension so I figured this is the best time to finally install Visual Studio 2026. I was pleasantly surprised to find that I had the option to “Copy workloads, components, and settings from a previous installation”! This meant that the key reason I had been putting off upgrading was invalid – I didn’t want to mess around with build errors from missing components that just work in my Visual Studio 2022 setup.

Visual Studio 2026 Installer Configuration

There were a couple of packages that weren’t available in VS 2026. The available packages ID linked to Visual Studio workload and component IDs | Microsoft Learn. These didn’t look like anything I have been using:

  1. Microsoft.VisualStudio.Component.Common.Azure.Tools
  2. Component.Microsoft.WebTools.BrowserLink.WebLivePreview
  3. aspire
  4. Microsoft.Net.Component.4.6.TargetingPack

I did confirm that they are included in the Visual Studio Enterprise (2022) workload and component IDs | Microsoft Learn. I decided to take a look at the Visual Studio Blog (it’s been a while) to see what else has been happening. This post particularly relevant to my extension writing goal caught my eye: SDK-Style Support for Extension Projects – Visual Studio Blog. That said, it’s incredible how much is happening in the developer tools space!


Categories: OpenJDK, Security

Listing Certificates in OpenJDK Test Keystore

I was looking at the OpenJDK test failure reported in [JDK-8384815] SelectOneKeyOutOfMany and PreferredKey fail after expired test certificate – Java Bug System and was curious about how to determine that the certificates had expired. This is the command line I found:

KEYSTORE="$JDKSRCPATH/test/jdk/javax/net/ssl/etc/keystore"
$JDKTOTEST/bin/keytool -list -v -keystore "$KEYSTORE" -storepass passphrase \
 | grep -E 'Alias name|Entry type|Signature algorithm|Valid from|Public Key Algorithm|Subject Public Key'

It outputs the block below.

Alias name: dummy
Entry type: PrivateKeyEntry
Valid from: Mon May 16 04:06:38 MDT 2016 until: Sat May 16 04:06:38 MDT 2026
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Alias name: dummydsa
Entry type: PrivateKeyEntry
Valid from: Thu Mar 29 17:06:34 MDT 2018 until: Tue Mar 28 17:06:34 MDT 2028
Signature algorithm name: SHA256withDSA
Subject Public Key Algorithm: 1024-bit DSA key (weak)
Alias name: dummyecdsa
Entry type: PrivateKeyEntry
Valid from: Mon May 16 04:09:01 MDT 2016 until: Sat May 16 04:09:01 MDT 2026
Signature algorithm name: SHA256withECDSA
Subject Public Key Algorithm: 256-bit EC (secp256k1) key (disabled)
Alias name: dummyecrsa
Entry type: PrivateKeyEntry
Valid from: Fri Apr 13 02:20:55 MDT 2018 until: Wed Apr 12 02:20:55 MDT 2028
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 256-bit EC (secp256r1) key
Valid from: Mon May 16 04:06:38 MDT 2016 until: Sat May 16 04:06:38 MDT 2026
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Alias name: ecdsasecp256r1
Entry type: PrivateKeyEntry
Valid from: Tue Mar 27 16:41:31 MDT 2018 until: Sun Mar 26 16:41:31 MDT 2028
Signature algorithm name: SHA256withECDSA
Subject Public Key Algorithm: 256-bit EC (secp256r1) key

Warning:
<dummydsa> uses a 1024-bit DSA key which is considered a security risk. This key size will be disabled in a future update.
<dummyecdsa> uses a 256-bit EC (secp256k1) key which is considered a security risk and is disabled.
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore C:/java/.../test/jdk/javax/net/ssl/etc/keystore -destkeystore C:/java/.../test/jdk/javax/net/ssl/etc/keystore -deststoretype pkcs12".

The history of the current keystore file shows that it was converted to PKCS12 almost 3 years ago in [JDK-8308453] Convert JKS test keystores in test/jdk/javax/net/ssl/etc to PKCS12 – Java Bug System so the final warning doesn’t affect the latest versions (PR 8308453: Convert JKS test keystores in test/jdk/javax/net/ssl/etc to … · openjdk/jdk@1696603).


Peeking into Ubuntu Crash Handling

I recently turned on an Ubuntu VM I had not used in a while and was greeted by this error dialog about a system program problem. I looked up this message and got a reference to Apport – Ubuntu project documentation explaining that the crash reports are in /var/crash.

There were 3 files in that folder. Although I couldn’t initially read them since I wasn’t root, it was interesting seeing the callout warning me not to start VS Code as a super user.

saint@ubuntuvm3:~$ ls -l /var/crash
total 7428
-rw------- 1 root whoopsie  158635 Jul  1 15:35 python3.10.0.crash
-rw-r----- 1 root whoopsie 2995487 Jul  9 12:50 _usr_lib_cnf-update-db.0.crash
-rw-r----- 1 root whoopsie 4444576 Jul  1 15:35 _usr_lib_python3.10_py_compile.py.0.crash
saint@ubuntuvm3:~$ head -10 /var/crash/_usr_lib_cnf-update-db.0.crash 
head: cannot open '/var/crash/_usr_lib_cnf-update-db.0.crash' for reading: Permission denied
saint@ubuntuvm3:~$ sudo code /var/crash/_usr_lib_cnf-update-db.0.crash 
mkdir: cannot create directory ‘’: No such file or directory
You are trying to start Visual Studio Code as a super user which isn't recommended. If this was intended, please add the argument `--no-sandbox` and specify an alternate user data directory using the `--user-data-dir` argument.

I copied one of the files to my home folder and tried to open it without fixing the permissions. Several warnings appeared in VS Code, which was interesting to me because I never take this path in VS Code (taking me back to my full-time QA days).

2026-07-09 18:06:17.921 [error] [Window] Error: Unable to read file '/home/saint/cnf.txt' (NoPermissions (FileSystemError): An unknown error occurred. Please consult the log for more details.)
    at Kkt.G (vscode-file://vscode-app/snap/code/215/usr/share/code/resources/app/out/vs/workbench/workbench.desktop.main.js:3828:65903)
...
2026-07-09 18:06:18.102 [error] [Window] [File Watcher (node.js)] Failed to watch /home/saint/cnf.txt for changes using fs.watch() (Error: EACCES: permission denied, watch '/home/saint/cnf.txt')
...

Nothing chmod couldn’t take care of.

saint@ubuntuvm3:~$ ls -l cnf.txt 
-rw-r----- 1 root root 2995487 Jul  9 18:06 cnf.txt
saint@ubuntuvm3:~$ sudo chmod o+r cnf.txt 
saint@ubuntuvm3:~$ ls -l cnf.txt 
-rw-r--r-- 1 root root 2995487 Jul  9 18:06 cnf.txt

An interesting aspect of the crash was that it looked like all 3 files were related to cnf-update-db. Per sources like Why do lines with “c-n-f Metadata” appear in the output of `sudo apt update`? – Ask Ubuntu, this is related to the command not found system that suggests packages to install to get the command you’re trying to use.

saint@ubuntuvm3:~$ sudo head -20 /var/crash/_usr_lib_cnf-update-db.0.crash 
ProblemType: Crash
Architecture: amd64
Date: Thu Jul  9 12:50:33 2026
DistroRelease: Ubuntu 22.04
ExecutablePath: /usr/lib/cnf-update-db
ExecutableTimestamp: 1638960799
InterpreterPath: /usr/bin/python3.10
ProcCmdline: /usr/bin/python3 /usr/lib/cnf-update-db
ProcCwd: /tmp
ProcEnviron:
 LANGUAGE=en_US.UTF-8
 LANG=en_US.UTF-8
ProcMaps:
 6087ac793000-6087ac800000 r--p 00000000 08:02 1442737                    /usr/bin/python3.10

I knew that I needed to update everything on this VM. Firefox was on version 146.0.1. The strange thing was that the Software Updater app didn’t even start! Nothing happened when clicking on its icon. I ran apt update anyway.

saint@ubuntuvm3:~$ sudo apt update
Hit:1 https://download.docker.com/linux/ubuntu jammy InRelease
Hit:2 http://security.ubuntu.com/ubuntu jammy-security InRelease                                       
Hit:3 http://us.archive.ubuntu.com/ubuntu jammy InRelease                                              
Get:4 http://us.archive.ubuntu.com/ubuntu jammy-updates InRelease [128 kB]
Hit:5 http://us.archive.ubuntu.com/ubuntu jammy-backports InRelease
Get:6 http://us.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [3,624 kB]
Get:7 http://us.archive.ubuntu.com/ubuntu jammy-updates/main i386 Packages [1,039 kB]
Get:8 http://us.archive.ubuntu.com/ubuntu jammy-updates/universe i386 Packages [814 kB]
Get:9 http://us.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages [1,277 kB]
Get:10 http://us.archive.ubuntu.com/ubuntu jammy-updates/universe Translation-en [321 kB]
Fetched 7,203 kB in 2s (4,014 kB/s)                             
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
7 packages can be upgraded. Run 'apt list --upgradable' to see them.
saint@ubuntuvm3:~$ apt list --upgradable
Listing... Done
docker-compose-plugin/jammy 5.3.1-1~ubuntu.22.04~jammy amd64 [upgradable from: 5.2.0-1~ubuntu.22.04~jammy]
fwupd/jammy-updates 2.0.20-1ubuntu2~22.04.2 amd64 [upgradable from: 2.0.20-1ubuntu2~22.04.1]
iproute2/jammy-updates 5.15.0-1ubuntu2.2 amd64 [upgradable from: 5.15.0-1ubuntu2]
libfwupd3/jammy-updates 2.0.20-1ubuntu2~22.04.2 amd64 [upgradable from: 2.0.20-1ubuntu2~22.04.1]
python3-distupgrade/jammy-updates,jammy-updates 1:22.04.21 all [upgradable from: 1:22.04.20]
ubuntu-release-upgrader-core/jammy-updates,jammy-updates 1:22.04.21 all [upgradable from: 1:22.04.20]
ubuntu-release-upgrader-gtk/jammy-updates,jammy-updates 1:22.04.21 all [upgradable from: 1:22.04.20]
saint@ubuntuvm3:~$ uname -a
Linux ubuntuvm3 6.8.0-90-generic #91~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Nov 20 15:20:45 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
saint@ubuntuvm3:~$ sudo apt upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages were automatically installed and are no longer required:
  libfwupd2 libfwupdplugin5 libgcab-1.0-0 libslirp0 libsmbios-c2 libwpe-1.0-1 libwpebackend-fdo-1.0-1 slirp4netns
Use 'sudo apt autoremove' to remove them.
The following packages have been kept back:
  fwupd libfwupd3 python3-distupgrade ubuntu-release-upgrader-core ubuntu-release-upgrader-gtk
The following packages will be upgraded:
  docker-compose-plugin iproute2
2 upgraded, 0 newly installed, 0 to remove and 5 not upgraded.
Need to get 9,172 kB of archives.
After this operation, 72.7 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 https://download.docker.com/linux/ubuntu jammy/stable amd64 docker-compose-plugin amd64 5.3.1-1~ubuntu.22.04~jammy [8,100 kB]
Get:2 http://us.archive.ubuntu.com/ubuntu jammy-updates/main amd64 iproute2 amd64 5.15.0-1ubuntu2.2 [1,072 kB]
Fetched 9,172 kB in 2s (5,743 kB/s)                  
Preconfiguring packages ...
(Reading database ... 181925 files and directories currently installed.)
Preparing to unpack .../iproute2_5.15.0-1ubuntu2.2_amd64.deb ...
Unpacking iproute2 (5.15.0-1ubuntu2.2) over (5.15.0-1ubuntu2) ...
Preparing to unpack .../docker-compose-plugin_5.3.1-1~ubuntu.22.04~jammy_amd64.deb ...
Unpacking docker-compose-plugin (5.3.1-1~ubuntu.22.04~jammy) over (5.2.0-1~ubuntu.22.04~jammy) ...
Setting up iproute2 (5.15.0-1ubuntu2.2) ...
Setting up docker-compose-plugin (5.3.1-1~ubuntu.22.04~jammy) ...
Processing triggers for man-db (2.10.2-1) ...

These were not as many packages as I expected to have updates! The next question was therefore how to determine whether I was on the latest security release. 22.04.5 appears to be the latest build, which is what cat /etc/lsb-release showed to my relief. Unfortunately, I didn’t check this value before I ran apt upgrade so I don’t know if this was already the version I was running when I started.

saint@ubuntuvm3:~$ uname -r
6.8.0-90-generic
saint@ubuntuvm3:~$ uname -a
Linux ubuntuvm3 6.8.0-90-generic #91~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Nov 20 15:20:45 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
saint@ubuntuvm3:~$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.5 LTS"

At this point, I decided to abandon the VM and create a new one with the latest release. I downloaded the 26.04 ISO from Ubuntu 24.04.4 (Noble Numbat) and verified its entry in the SHASUMS file. I ran into some errors setting up the VM in Hyper V so I ended my experiment with VMs there.


Categories: Visual Studio

Wierd Error About Stale Visual Studio Account

I was trying to use Visual Studio recently but it wouldn’t let me because my “license has gone stale and must be updated. Please make sure that you’re connected to the internet, then check for an updated license to continue using the product.” Clicking on the “Check for an updated license” command did not work. Under the “All Accounts” section of the dialog, there was a message under my account saying that “We need to refresh the credentials for this account.” Notice the Re-enter your credentials command.

Re-entering credentials failed with the AcccountNotFound error:

Fortunately, this issue had already been reported in Authentication: WAM sign-in fails when Windows account is missing – Developer Community and there was a work-around: remove the folder %LOCALAPPDATA%\Microsoft\IdentityCache. This issue did pique my curiosity about how modern authentication is done. The Overview of the Microsoft Authentication Library (MSAL) – Microsoft identity platform appears to be sufficiently detailed. I’ll also have to poke around in the Microsoft Authentication Library for Java at some point. Thankfully, these libraries are open source, e.g. AzureAD/microsoft-authentication-library-for-dotnet: Microsoft Authentication Library (MSAL) for .NET.


Categories: OpenJDK

Servicability Tests with Bad Core Dumps

I occasionally run into odd test failures in servicability tests like ClhsdbFindPC.java related to core dumps. The test sets a flag to request a crash in order to generate a core dump for inspection. One of the earlier issues was that core dumps were not being created and this was fixed in 8348862: runtime/ErrorHandling/CreateCoredumpOnCrash fails on Windows aarch64 by swesonga · Pull Request #27074 · openjdk/jdk. A failure I saw recently was:

Aborting due to java.lang.OutOfMemoryError: Metaspace
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (debug.cpp:289), pid=1234, tid=5678
#  fatal error: OutOfMemory encountered: Metaspace
#
# JRE version: OpenJDK Runtime Environment Microsoft-13945457 (25.0.3+9) (build 25.0.3+9-LTS)
# Java VM: OpenJDK 64-Bit Server VM Microsoft-13945457 (25.0.3+9-LTS, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-aarch64)
# Core dump will be written. Default location: D:\

The test failure output was:

getCoreFileLocation found stringWithLocation = D:\...\hs_err_pid1234.mdmp
Found core file D:\...\hs_err_pid1234.mdmp, size = 0mb
STDERR:
java.lang.RuntimeException: Test ERROR java.lang.RuntimeException: Unexpected core size: expected 0 > 0
	at ClhsdbFindPC.testFindPC(ClhsdbFindPC.java:317)
	at ClhsdbFindPC.main(ClhsdbFindPC.java:339)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at com.sun.javatest.regtest.agent.MainWrapper$MainTask.run(MainWrapper.java:138)
	at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: java.lang.RuntimeException: Unexpected core size: expected 0 > 0
	at jdk.test.lib.Asserts.fail(Asserts.java:715)
	at jdk.test.lib.Asserts.assertGreaterThan(Asserts.java:403)
	at jdk.test.lib.Asserts.assertGT(Asserts.java:374)
	at jdk.test.lib.util.CoreUtils.getCoreFileLocation(CoreUtils.java:113)
	at ClhsdbFindPC.testFindPC(ClhsdbFindPC.java:113)
	... 5 more

The issue here clearly appears to be that the JVM ran out of memory before it could complete the test. However, I wanted to save the expected output from the test for quick reference in future:

# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffaf8cd112c, pid=1234, tid=5678
#
# JRE version: OpenJDK Runtime Environment Microsoft-13945457 (25.0.3+9) (build 25.0.3+9-LTS)
# Java VM: OpenJDK 64-Bit Server VM Microsoft-13945457 (25.0.3+9-LTS, compiled mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-aarch64)
# Problematic frame:
# C  [LingeredApp.dll+0x112c]
#
# Core dump will be written. Default location: C:\...

If the test is working correctly, the crash should come from LingeredApp.dll. This binary is in the test image, specifically in hotspot/jtreg/native. LingeredApp.java has a native method called crash(). It’s implementation in libLingeredApp.c dereferences a non-null invalid pointer with set bits in every word. This guarantees that an EXCEPTION_ACCESS_VIOLATION should be seen if the test ran correctly.


Categories: Web Development

Blank Print Preview when Printing Webpage

I wanted to sign up for an event recently and the web page asked me to sign a waiver. This looked like a document I should save so I tried to print it as a PDF. I was surprised that the PDF was a completely blank page. This reminded me of my encounter with Printer Unfriendly HTML and CSS. I inspected the computed styles of the elements on the page. Interestingly, they were all reasonably sized (e.g. the main div elements appeared to be thousands of pixels tall and wide). Even the body was tall enough to make it strange that nothing would show up in the print preview. My first AI prompt:

One of the answers to the 2nd query was to use DevTools to force print media mode! This approach is documented at Emulate CSS media features  |  Chrome DevTools  |  Chrome for Developers: Open the rendering tab and under Emulate CSS media type select print. This rendered a blank page, which confirmed that the web page was designed to behave this way (this wasn’t just accidentally bad HTML/CSS design, there was some intentionality).


Categories: OpenJDK, Security

Basic OpenJDK JAR File Signature Verification

I was recently exploring JAR file verification and found this post Verifying Signed JAR Files (The Java™ Tutorials > Deployment > Packaging Programs in JAR Files) explaining how The jarsigner Command (which is different from the JarSigner (Java SE 25 & JDK 25) API) can be used to verify a signed JAR file. JarSigner is implemented as a java program implemented as a Java program (that calls the void verifyJar(String jarName) method).

Verifying a JAR File

Verifying Signed JAR Files states that the basic command to use for verifying a signed JAR file is jarsigner -verify jar-file. The jarsigner Command adds that when the -strict option is specified, it constructs the exit code depending on which checks failed. We can check the exit code using echo $? in bash. For example, I get exit code 16 for my unsigned JAR file with --strict but exit code 0 without it.

cd /c/repos/factorize/java/project
time mvn package

export JAVA_HOME=/d/java/binaries/jdk/x64/2026-04/windows-jdk25u/jdk-25.0.3+9

$JAVA_HOME/bin/jarsigner -verify -strict target/factorize-1.0.0-jar-with-dependencies.jar

echo $?

Creating Keys for Signing a JAR File

My next question was how to create keys for signing my java JAR file. The JFrog Security Keys Management page mentioned the keytool-Key and Certificate Management Tool (see newer docs at The keytool Command). The keytool command below from the older article…

mkdir mykeys/

$JAVA_HOME/bin/keytool -genkeypair \
 -dname "cn=Saint Wesonga, ou=Java, o=Microsoft, c=US" \
 -alias business \
 -keypass kpi135 \
 -keystore mykeys/mykeystore \
 -storepass ab987c -validity 180

… output:

Warning:  Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -keypass value.
keytool error: java.lang.Exception: The -keyalg option must be specified.

So I used this command, which is similar to the newer keytool Command example:

$JAVA_HOME/bin/keytool -genkeypair \
 -dname "cn=Saint Wesonga, ou=Java, o=Microsoft, c=US" \
 -alias business \
 -keystore mykeys/mykeystore \
 -storepass ab987c -validity 180 \
 -keyalg DSA

The output from this command was:

Generating 2048-bit DSA key pair and self-signed certificate (SHA256withDSA) with a validity of 180 days
        for: CN=Saint Wesonga, OU=Java, O=Microsoft, C=US

Signing a JAR File

Next, look at the Example of Signing a JAR File in the jarsigner Command docs.

$JAVA_HOME/bin/jarsigner \
 -keystore mykeys/mykeystore \
 -signedjar target/factorize-1.0.0-signed-jar-with-dependencies.jar \
 target/factorize-1.0.0-jar-with-dependencies.jar business

Its output is:

Enter Passphrase for keystore:

jar signed.

Warning:
The signer's certificate is self-signed.
POSIX file permission and/or symlink attributes detected. These attributes are ignored when signing and are not protected by the signature.