Benki โ†’ All Posts

โ‡  previous page next page โ‡ข

I have long been skeptical of the educational value of non-fiction books. Mostly when I have bought a book on a topic I found interesting, I either never started reading it, abandoned it after two chapters, or skimmed through the table of contents to find just the things that seemed interesting and ignored everything else. When I did read several chapters in order, I mostly did not remember much later.

There are exceptions, of course. Effective Java is one, which is because it is a compilation of many small independent pieces of wisdom each of which is presented in a compact form. Modern Principles of Economics is another, and that is because it is a proper course textbook for a formal curriculum, with exercises and all.

The classic essay-as-book type of book, however, is mostly worthless to me.

Arnold Kling agrees.

A free-as-in-beer web browser for iOS and Mac from the people behind the Kagi search engine. Privacy-centric and ad-blocking by default.

Not sure why you would use this on a desktop computer over Firefox, but on iOS I can see how it could be useful.

A web search engine that promises efficiency, privacy, and user-centricity in exchange for a subscription fee.

High-fidelity image format with lossless recompression from JPEG. Supports both lossless and lossy compression.

Matthias #

Always fun dealing with Spring Boot

I just released version 6.1.0 of Quarkus Google Cloud JSON Logging, the somewhat inaccurately named library for logging in Google Cloud JSON format for JBoss Log Manager, a drop-in replacement for the LogManager from java.util.logging.

The original motivation for creating this release was that Quarkus in version 3.4 switched away from its custom JBoss Log Manager Embedded fork of JBoss Log Manager, rendering my libraryโ€™s DefaultEmbeddedConfigurator class useless. But as it turns out, the Quarkus extension never used it, so nothing was actually broken by the change. Yay.

Instead I noticed that, somewhat unrelatedly, Spring Boot 3, which the library also supports (I mentioned it is somewhat inaccurately named, yes?), broke the way JBoss Logging (not to be confused with JBoss Log Manager) interacts with everything, especially JBoss Log Manager Embedded, leading logs from its logging facade to be swallowed and consequently never printed.

The good news is that migrating away from JBoss Log Manager Embedded fixes the problem. The real JBoss Log Manager even has another nice feature: You can configure it using a logging.properties file, so a custom configurator factory is not, in fact, needed. You can just create your logging.properties file and set it to use my DefaultConsoleHandler as the handler for your log messages. Or if you prefer, you can inject your own LogContextConfigurator using the standard ServiceLoader mechanism and leave the logging.properties file empty. Great!

Except! Spring Boot likes to make things extra fun. If you use the JavaLoggingSystem, which is what you want to do when you use JBoss Log Manager as your log sink (remember, it is a drop-in replacement for the standard LogManager from java.util.logging), Spring Boot first initializes the root logger, then sets its log level to SEVERE, and finally it asks it to load the configuration file that you supplied. But JBoss Log Manager loads its configuration (or your custom LogContextConfigurator if you supplied one) when it is initialized, so loading it another time means it loads it twice. And that puts you in a pickle because:

  1. If you leave the configuration file empty and configure the message handler some other way, the log level stays at SEVERE and you lose all logs.
  2. If you configure a logger in the configuration file and set its level and message handler, the handler is added twice, so you get double the logs.

So in the end I still had to make the change that I had originally set out to do, which was to add a new DefaultConfiguratorFactory class to replace the old DefaultEmbeddedConfigurator and enable everyone to migrate away from JBoss Log Manager Embedded. With my DefaultConfiguratorFactory, the configuration file still gets loaded twice, but the custom configurator takes care of fixing the list of handlers to a single Google-Cloud-JSON-enabled ConsoleHandler.

Check out the readme in case you want to get in on the fun.

โ‡  previous page next page โ‡ข