Kotlin Object Declarations – The fake-static

Instead of implementing my own backup application as I had planned a long time ago, I’m wandering off (re)learning Kotlin after a long absence from that language. In my defense though, I’m doing it in the context of the backup app which will not be Java as originally intended (or maybe later for comparison, who knows, I obviously can’t be trusted with my plans). Putting that aside, the most confusing concept of Kotlin for a Java developer is the object. What is that thing doing that a class can’t do and how do we declare static fields and methods? I know it’s nothing new, but that part seems to have changed a bit since I used Kotlin about two (?) years ago. So, for me this is a refresh of old information and also something new and by writing about it I will engrave it in my brain once and for all. And your confusion will hopefully turn into some productive… fusion… of some sort… or so.

Read More »

Red Dead Redemption 2

I’ve been a gamer for a very long time – it’s easily been twenty years or more (yes, I’m old). But, in the past year or so, my excitement has been waning. I have mentioned in another blog post that I was planning to replace my big tower PC with a notebook for (mobile) coding and writing – which I have done – and, in the short- to mid-term, get a gaming console to replace the video gaming part of the PC with something more casual and affordable. This day has finally come and the first game I have played has been Red Dead Redemption 2. Now, this game was many firsts for me:

  • First non-digital game since Steam has launched. I bought it in a retail store on a BluRay disc.
  • First full-price video game at 60€. Before that, I have always been shopping for special offers and discounts.
  • First console game.

I think Red Dead Redemption is something very special and I will try to explain why I think that is. One thing is for sure and that is the fact that it has rekindled the fire within me to play a video game on-end without pause. Unlike the other game reviews/experience reports I have written so far, this one is a bit different. I started writing when I was about 40% through the game and added to it at different stages of progress. In short: it’s like a diary.

Read More »

Unwanted JUnit 4 Dependency with Kotlin and JUnit 5

I ran across this issue only by accident because I was investigating a completely different problem. I wrote a quick test to debug my issue and was wondering why custom serializers and deserializers are not registered with the Jackson ObjectMapper. I had a nice init() function that was annotated with @Before. So, what the hell?

Let’s back up a bit for some context.

  • Kotlin Project
  • Runs on Java 12
  • JUnit 5 as test engine
  • AssertK for assertions (just for the sake of completeness)

I’m used to JUnit 4, so in my test I used @Before to annotate a setup method. It was one of the many options IntelliJ presented to me.

@Before
fun init() {
    val module = SimpleModule()
    module.addDeserializer(Instant::class.java, InstantDeserializer())
    module.addSerializer(Instant::class.java, InstantSerializer())
    mapper.registerModule(module)
}

The method wasn’t called, however. But it’s annotated! Well, it’s the wrong annotation if you’re using JUnit 5. The correct one is @BeforeEach. This one and @BeforeClass (new name @BeforeAll) have been changed from version 4 to 5 to make their meaning more obvious.

But that’s besides the point. The question is: where does this @Before come from then?

A look at the dependency tree quickly reveals the culprit.

It’s the official JetBrains Kotlin JUnit test artifact. Although it doesn’t hurt me to have it in my project, it certainly caused some confusion and I’d like to avoid that in the future. Hence, I excluded the old version of JUnit in my POM file for this dependency.

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-test-junit</artifactId>
    <version>${kotlin.version}</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Problem solved.

Passively Cool – The Surface Pro 6 Review

One of the computers I was interested in at the beginning of this yearwas the Surface Pro 6 from Microsoft. I had owned a Surface Pro 3 in the past and was very happy with it. But, as mentioned in a previous article, I had noticed something like a moiré pattern on the screen when white background was displayed. It wasn’t as pronounced on the Surface Pro as it was on a lower resolution HP notebook, but it was there, and I was afraid it would bother me.

I managed to get my hands on a Surface Pro 6 base model with a Signature Type Cover in Alcantara and used it as my main computer for about a week instead of my MacBook Pro.

Guess what: it didn’t bother me, and I could have saved a lot of money compared to the MacBook Pro. But that’s only part of the story.

Read More »

Of Affordable Phones, Software Updates and Yearly Upgrades

With the release of the Google Pixel 3a I once again started thinking about what I want in a smartphone. As a reminder, the last time I was pondering the purchase of one I was musing of tall phones, curved displays and notches. I am not in the market for a new phone right now as my iPhone 8 is more than capable of fulfilling my needs. But, with the recent launch of the Pixel 3a I wished that this device had already existed a year ago because it is basically the perfect phone for me. And I also wish Google would get back into the market of less expensive phones with the latest and greatest hardware as was the case with the Nexus line.

Read More »

AdoptOpenJDK 8 NullPointerException sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)

I recently had to deal with this little bugger as we moved from the OpenJDK 8 package supplied by the Linux distro of choice to AdoptOpenJDK 8. It is important to know that we completely uninstalled OpenJDK, including all its transient dependencies.

(And in due time we’ll uninstall Java 8 and replace that grandpa as well)

As a result, parts of our application didn’t work any longer, resulting in this nice and shiny Java stacktrace.

2019-05-03 08:22:07,345 ERROR [qtp1896708863-35] [PlotChartController] [/][/][/]- error while creating chart image
java.lang.NullPointerException
        at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)
        at sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:219)
        at sun.awt.FontConfiguration.init(FontConfiguration.java:107)
        at sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:774)
        at sun.font.SunFontManager$2.run(SunFontManager.java:431)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.font.SunFontManager.<init>(SunFontManager.java:376)
        at sun.awt.FcFontManager.<init>(FcFontManager.java:35)
        at sun.awt.X11FontManager.<init>(X11FontManager.java:57)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at java.lang.Class.newInstance(Class.java:442)
        at sun.font.FontManagerFactory$1.run(FontManagerFactory.java:83)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74)
        at java.awt.Font.getFont2D(Font.java:491)
        at java.awt.Font.defaultLineMetrics(Font.java:2176)
        at java.awt.Font.getLineMetrics(Font.java:2246)
        at org.jfree.chart.axis.DateAxis.estimateMaximumTickLabelWidth(DateAxis.java:1453)
        at org.jfree.chart.axis.DateAxis.selectHorizontalAutoTickUnit(DateAxis.java:1365)
        at org.jfree.chart.axis.DateAxis.selectAutoTickUnit(DateAxis.java:1340)
        at org.jfree.chart.axis.DateAxis.refreshTicksHorizontal(DateAxis.java:1616)
        at org.jfree.chart.axis.DateAxis.refreshTicks(DateAxis.java:1556)
        at org.jfree.chart.axis.ValueAxis.reserveSpace(ValueAxis.java:807)
        at org.jfree.chart.plot.CombinedDomainXYPlot.calculateAxisSpace(CombinedDomainXYPlot.java:364)
        at org.jfree.chart.plot.CombinedDomainXYPlot.draw(CombinedDomainXYPlot.java:442)
        at org.jfree.chart.JFreeChart.draw(JFreeChart.java:1235)
        at org.jfree.chart.JFreeChart.createBufferedImage(JFreeChart.java:1409)
        at org.jfree.chart.JFreeChart.createBufferedImage(JFreeChart.java:1389)
        at org.jfree.chart.ChartUtilities.writeChartAsPNG(ChartUtilities.java:183)

I obviously removed some (a lot) parts to make it more readable and to hide corporate IP 😉 But this is the relevant part.

I found this bug report on Github and for once, plowing through the comments, it helped me. As is mentioned there, the culprit is the missing “fontconfig” package. So, I added another Ansible task to our playbook to provision the server et voila, the problem is gone.

- name: Install fontconfig package
  package:
    name: fontconfig
    state: present
    tags:
      - java

As mentioned earlier, we had wiped all that was relevant to OpenJDK off the system and by doing so, also uninstalled the “fontconfig” package. Otherwise this error wouldn’t have surfaced. But that’s the benefit of starting with a clean slate. This way you know if something is missing and don’t get surprised by errors all of a sudden while, at the same time, it is working on another machine.

Micrometer and Spring (Non-Boot)

Almost all of the tutorials and blog posts I found on this topic were focused on Spring Boot because, starting with version 2, it uses Micrometer as its metrics framework. However, in a particular project at work we do not have access to Spring Boot let alone a recent Spring version. Therefore, I’m explaining how to include Micrometer in your non-Boot Spring application using XML configuration.

In this tutorial I will be using Spring 5 and Java 11, so not exactly the versions I’m dealing with at work, but the concepts are the same and everything can probably be copied exactly as shown here.

Read More »