Curious (Clojure) Programmer Simplicity matters

Menu

  • Home
  • Archives
  • Tags
  • About
  • My Talks
  • Weekly Bits & Pieces
  • Clojure Tip of the Day Screencast
  • RSS
April 13, 2022

Weekly Bits 08/2022 - Clojure keyword deserialization, 'reified', difftastic, and JDK 18 release

Table of Contents
  • Clojure
    • Rich Already Answered That!
    • Bogus: a simple GUI debugger for Clojure
    • What do people mean with "reified"?
    • Problem with Clojure keyword de-serializationa after upgrading to Clojure 1.11
    • difftastic - new diff tool that supports Clojure
  • Java / JVM
    • JDK 18 released
  • AWS & Cloud
    • Naming Load Balancers
  • Security
    • Length (size) of cryptographic keys - recommendations
    • Authentication - Logout: GET or POST?
    • BLAKE3 hash function - very fast and secure
  • MISC
    • New Linux kernel unifies /dev/random and dev/urandom
    • Game Development in Eight Bits
  • Links

Some of the interesting things I did, learned, or found in the past week.

Clojure

Rich Already Answered That!

It’s an old gist but useful to review. Lots of great insights there!

Bogus: a simple GUI debugger for Clojure

An interesting minimalistic debugger with a GUI. It might be a good option if you don’t have a good debugger available, perhaps when working with some IDEs or on the command line.

Simply add #bg/debug and it opens a simple GUI and blocks the execution to inspect the values

What do people mean with "reified"?

A good discussion on clojureverse about the meaning of "reified" - a common term in Clojure community, but rarely used elsewhere.

I found didibus' explanation useful:

  • A good way to think of reified is that it means that the program is aware of its programming and can change it, or you might say it is aware of itself and has the ability to modify itself.

  • To map it to the dictionary definition, you would think of source code for example as the abstraction, and the running program of that compiled source as the concrete representation of it.

    • reifying a function would be the act of taking its source (the abstraction) at runtime and evaluating it again at runtime into a new concretion.

  • Similarly, a spec is an abstraction, and a concrete value that is valid to the spec would be its concrete realization.

  • Similarly a type is an abstraction, and a concrete value of that type in memory is its concrete realization.

  • Similarly an interface or a protocol is an abstraction, and an object or map implementing that interface or protocol is its concrete realization.

Problem with Clojure keyword de-serializationa after upgrading to Clojure 1.11

At work, I eagerly upgraded our codebase to 1.11.0 soon after it was released. However, next day, one of our testers found a problem in the staging environment that I tracked down to this error:

....
org.quartz.impl.StdScheduler.getJobDetail StdScheduler.java: 498
org.quartz.core.QuartzScheduler.getJobDetail QuartzScheduler.java: 1518
org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob JobStoreSupport.java: 1374
org.quartz.impl.jdbcjobstore.JobStoreSupport.executeWithoutLock JobStoreSupport.java: 3739
org.quartz.impl.jdbcjobstore.JobStoreTX.executeInLock JobStoreTX.java: 93
org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock JobStoreSupport.java: 3803
org.quartz.impl.jdbcjobstore.JobStoreSupport$9.execute JobStoreSupport.java: 1377
org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob JobStoreSupport.java: 1385
org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectJobDetail StdJDBCDelegate.java: 860
org.quartz.impl.jdbcjobstore.StdJDBCDelegate.getObjectFromBlob StdJDBCDelegate.java: 3201
java.io.ObjectInputStream.readObject ObjectInputStream.java: 460
...
java.io.ObjectStreamClass.initNonProxy ObjectStreamClass.java: 699
java.io.InvalidClassException: clojure.lang.Keyword; local class incompatible: stream classdesc serialVersionUID = -2105088845257724163, local class serialVersionUID = 2404715664513862299
org.quartz.JobPersistenceException: Couldn't retrieve job because the BLOB couldn't be deserialized: clojure.lang.Keyword; local class incompatible: stream classdesc serialVersionUID = -2105088845257724163, local class serialVersionUID = 2404715664513862299

The affected component reads data about analysis schedules stored in MySQL db via Quartz. Here we see, that Quartz can no longer de-serialize an instance of clojure.lang.Keyword.

The trouble is, that Quartz uses standard Java serialization mechanism and the Keyword class has been updated in the recent release. But while Keyword and many other clojure classes are marked as Serializable, they do not specify custom serialVersionUID. This is a common problem discussed in numerous places, for instance:

  • What is a serialVersionUID and why should I use it? https://stackoverflow.com/questions/285793/what-is-a-serialversionuid-and-why-should-i-use-it

    the automatically-generated UID is generated based on a class name, implemented interfaces, and all public and protected members. Changing any of these in any way will change the serialVersionUID

I was surprised and sad to see this but the excellent Clojure core team responded swiftly and they fix it in 1.11.1. Thanks, Alex!

difftastic - new diff tool that supports Clojure

It looks interesting and useful. And it supports git!

GIT_EXTERNAL_DIFF=difft git log -p --ext-diff

Check the One Minute Demo and Getting Started guide.

Java / JVM

JDK 18 released

Java 18 / JDK 18: General Availability

This release includes some interesting stuff - checkout the JEPs:

  • 400: UTF-8 by Default

    • Specify UTF-8 as the default charset of the standard Java APIs

  • 408: Simple Web Server - jwebserver

  • 413: Code Snippets in Java API Documentation via @snippet

  • 416: Reimplement Core Reflection with Method Handles

  • 417: Vector API (Third Incubator)

  • 418: Internet-Address Resolution SPI

    • so that java.net.InetAddress can make use of resolvers other than the platform’s built-in resolver.

    • One of the motivations was Loom: A resolution operation with the InetAddress API currently blocks in an operating-system call. This is a problem for Loom’s user-mode virtual threads, since it prevents underlying platform threads from servicing other virtual threads while waiting for a resolution operation to complete.

  • 419: Foreign Function & Memory API (Second Incubator)

  • 420: Pattern Matching for switch (Second Preview)

  • 421: Deprecate Finalization for Removal

AWS & Cloud

Naming Load Balancers

From Changing the name of a Load Balancer on AWS Console:

  • You can’t change the name of a load balancer, because that would break the sites that use the load balancer.

  • ELBs have an associated hostname, that looks like this:

    ${balancer_name}-${opaque_identifier}.${region}.elb.amazonaws.com

Security

Length (size) of cryptographic keys - recommendations

  • The Definitive 2019 Guide to Cryptographic Key Sizes and Algorithm Recommendations https://paragonie.com/blog/2019/03/definitive-2019-guide-cryptographic-key-sizes-and-algorithm-recommendations

    • Instead migrate from RSA to elliptic curve cryptography, and then breathe easy while you keep an eye out for post-quantum cryptography recommendations.

  • How can I tell how many bits my ssh key is? https://superuser.com/questions/139310/how-can-i-tell-how-many-bits-my-ssh-key-is

    ssh-keygen -l -f my-signing-key.pem
    256 SHA256:TEpaY6TN8iGfv3sZleOPlUBynmoFHN8xw3tuQjOAnGE no comment (ECDSA)

Authentication - Logout: GET or POST?

https://stackoverflow.com/questions/3521290/logout-get-or-post Logout: GET or POST?^]

  • ⇒ use POST (or DELETE for APIs)

  • In 2010, using GET was probably an acceptable answer. But today (in 2013), browsers will pre-fetch pages they "think" you will visit next.

BLAKE3 hash function - very fast and secure

  • Much faster than MD5, SHA-1, SHA-2, SHA-3, and BLAKE2.

  • Secure, unlike MD5 and SHA-1. And secure against length extension, unlike SHA-2.

  • see also old BLAKE2: https://www.blake2.net/

MISC

New Linux kernel unifies /dev/random and dev/urandom

From https://www.theregister.com/2022/03/21/new_linux_kernel_has_improved/:

  • The /dev/random and /dev/urandom devices now do exactly the same. This brings the Linux kernel in line with FreeBSD and macOS.

  • From Uniting the Linux random-number devices:

    • Torvalds is known to have little patience for theoretical concerns about cryptography (or theoretical concerns about anything else, in truth).

      • Torvalds’s response was rather more direct and categorical: - he said, the insistence on theoretical security has often had the effect of making the kernel less secure, and he had a number of examples to cite.

Game Development in Eight Bits

An interesting talk about Nintendo games and NES system (6502 processor).

The key takeaway: "Embrace the stupid" - there’s a value in that.

  • a really dumb solution might do what you need to do and that’s fine

  • as they say, "I would rather ship Final Fantasy than sitting there for months trying to figure out perfect random generator"

Links

A quick recap of some of the links mentioned in this post:

  • Rich Already Answered That!

  • Bogus: a simple GUI debugger for Clojure

  • What do people mean with "reified"?

  • BLAKE3 hash function - very fast and secure

  • Uniting the Linux random-number devices

  • Torvalds is known to have little patience for theoretical concerns about cryptography

  • Problem with Clojure keyword de-serializationa after upgrading to Clojure 1.11

  • Java 18 / JDK 18: General Availability

  • difftastic - new diff tool that supports Clojure

  • Changing the name of a Load Balancer on AWS Console

  • https://stackoverflow.com/questions/3521290/logout-get-or-post Logout: GET or POST?^]

  • Game Development in Eight Bits


Tags: clojure aws weekly-bits

« Bits & Pieces 09/2022 - April Weekly Bits 07/2022 - clojure.set/union gotcha, memory "leaks" using eval, EC2 Instance Connect, and CloudFront vs Host header »

Copyright © 2022 Juraj Martinka

Powered by Cryogen | Free Website Template by Download Website Templates