Renew p12 certificate for java (let’s encrypt)

When let’s encrypt updates the certificates, the p12 file remains unchanged and if that’s what your Spring app for example uses, then you need to update it as well.

Sample folder where your letsencrypt certificates reside:

root@01:/etc/letsencrypt/live/mysite.com# ls -l
total 24
-rw-r--r-- 1 root root 692 Jan 16 16:00 README
-rw-r--r-- 1 root root 4186 Apr 26 12:09 _keystore.p12
lrwxrwxrwx 1 root root 34 Apr 26 11:56 cert.pem -> ../../archive/mysite.com/cert3.pem
lrwxrwxrwx 1 root root 35 Apr 26 11:56 chain.pem -> ../../archive/mysite.com/chain3.pem
lrwxrwxrwx 1 root root 39 Apr 26 11:56 fullchain.pem -> ../../archive/mysite.com/fullchain3.pem
-rw-r--r-- 1 root root 2933 Apr 26 12:18 keystore.p12
lrwxrwxrwx 1 root root 37 Apr 26 11:56 privkey.pem -> ../../archive/mysite.com/privkey3.pem

the renew bot will update all files except for p12. Spring uses p12 file (application.properties):

server.ssl.key-store-type=PKCS12
server.ssl.key-store=/etc/letsencrypt/live/mysite.com/keystore.p12

So you need to do it manually or put in a sh script and setup crontab to run once in a while:

openssl pkcs12 -export -in cert.pem -inkey privkey.pem -out keystore.p12

Don’t forget to restart you spring app to take effect.

1Z0-819 Java 11 Oracle Certification

I’ve just passed the 1Z0-819 exam and I must say it is one of the hardest OCP exams out there.

Some aspects:

Logistics – you will need a working phone with good camera and wifi in order to take pictures of your surroundings and documents (ONLY when taking from home)

Questions:

  1. Some tricky questions
  2. Broad list of topics.

1 Question on Threads – given code, identify what type of threading problem is represented: Livelock, Deadlock, Race Condition…

1 Question on Annotations – given an annotated code, identify the correct annotation declaration

1 on Files

1 on MessageResources / i18n

A couple of inheritance / OOP questions (implement interface and extend class which also implements it). Default methods overriding.

Several questions on exception handling (multi catch, try with resources)

A couple of questions on JDBC (setNull for example)

Array Sorting Algorithms

Insertion Sort (n2)

 static void insertionSort(int[] a) {
        for (int i = 2; i < a.length; i++) {
            int key = a[i];
            int j = i - 1;
            while (j > 0 && a[j] > key) {
                a[j + 1] = a[i];
                j--;
            }
            a[j + 1] = key;
        }
    }

Merge Sort (n lg n)

package vvirlan.sorting;

import vvirlan.utils.PrintUtils;

public class MergeSort {
    public static void main(String[] args) {
        int[] A = new int[]{37, 0, 1, 35, 39, 44, 2, 25, 8, 43, 48, 34, 6, 50, 15, 5, 26, 47, 49, 24};
        mergeSort(A, 0, A.length - 1);
        PrintUtils.print1DArray(A);
    }

    static void mergeSort(int[] A, int p, int r) {
        if (p < r) {
            int q = (p + r) / 2;
            mergeSort(A, p, q);
            mergeSort(A, q + 1, r);
            merge(A, p, q, r);
        }
    }


    static void merge(int[] A, int p, int q, int r) {
        int n1 = q - p + 1;
        int n2 = r - q;
        int[] L = new int[n1 + 1];
        int[] R = new int[n2 + 1];

        for (int i = 0; i < n1; i++) {
            L[i] = A[p + i];
        }
        for (int j = 0; j < n2; j++) {
            R[j] = A[q + j + 1];
        }
        L[n1] = Integer.MAX_VALUE;
        R[n2] = Integer.MAX_VALUE;

        int i = 0;
        int j = 0;
        for (int k = p; k <= r; k++) {
            if (L[i] <= R[j]) {
                A[k] = L[i];
                i++;
            } else {
                A[k] = R[j];
                j++;
            }
        }
    }
}

ERROR 1410 (42000): You are not allowed to create a user with GRANT

You will get this error

ERROR 1410 (42000): You are not allowed to create a user with GRANT

If you are trying to run a GRANT on a user that doesn’t exist!

Therefore, first run this to make sure the user you use in your GRANT matches exactly to what you have:

select User, Host from user;

In particular pay attention whether the user you created is at localhost but the one you are trying to grant to is %

RAM modules 3 and 4 not working

A very curious case. An existing system with 4 RAM modules had it’s CPU upgraded. After replacing the CPU and restarting the system, BIOS was beeping 3 short beeps and 1 long beep and it would not continue booting.

Removing modules 3 and 4 and only leaving modules 1 and 2 resulted in normal start-up. First, I thought it was due to modules themselves, then after swapping the modules it turned out only slots 3 and 4 would not work.

In the end, it turned out, the issue was with dirty/greasy probably CPU pins (to note, in my case those were not pins but rather dots – LGA 1155). After cleaning the CPU contacts with alcohol all worked fine.

Graphs – path exists? (BFS)

This is a simple implementation of a directed Graph and searching whether there is a path between node u and node v

package vvirlan.graph.simplegraph;

import java.util.LinkedList;
import java.util.List;

public class Graph {
    // Number of vertices
    private final int v;
    // Adjacency List
    private final List<Integer>[] adj;

    Graph(int v) {
        this.v = v;
        adj = new LinkedList[v];
        for (int i = 0; i < v; i++) {
            adj[i] = new LinkedList<>();
        }
    }

    public static void main(String[] args) {
        Graph graph = new Graph(4);
        graph.addEdge(0, 1);
        graph.addEdge(0, 2);
        graph.addEdge(1, 2);
        graph.addEdge(2, 0);
        graph.addEdge(2, 3);
        graph.addEdge(3, 3);

        int u = 1;
        int v = 3;
        if (graph.isReachable(u, v)) {
            System.out.printf("There is a path from %s to %s%n\n", u, v);
        } else {
            System.out.printf("There is no path from %s to %s%n\n", u, v);

        }
    }

    void addEdge(int from, int to) {
        adj[from].add(to);
    }

    /**
     * BFS traversal. Is reachable from source to dest
     *
     * @param source
     * @param dest
     * @return
     */
    boolean isReachable(int source, int dest) {

        boolean[] visited = new boolean[this.v];
        LinkedList<Integer> queue = new LinkedList<>();

        visited[source] = true;
        queue.add(source);


        while (queue.size() > 0) {
            int current = queue.poll();
            List<Integer> outgoingVertices = adj[current];
            for (Integer vertex : outgoingVertices) {
                if (vertex == dest) {
                    return true;
                }
                if (!visited[vertex]) {
                    visited[vertex] = true;
                    queue.add(vertex);
                }
            }
        }

        //If BFS is complete without visited d
        return false;
    }
}

Embedded js import scripts

Sometimes you might want to split a big js file into “modules” when developing web pages with js / jQuery. By embedded here I mean plain old javascript in HTML imported using this syntax:

<script src="js/main.js"/>

Let’s say your main.js looks like this:

function sayHi() {
for (i=0; i < 3;i++) {
 alert("Hello");
}
}

And in the HTML page you have something like:

<button onClick="sayHi()"/>

Now you want to extract the “Hello” message to a different js “module” or file. Here are the steps:

  1. Declare the new file ‘module.js’:
function helloMsg() {
 return "Hello from Module";
}
export {helloMsg}

2. Import the new file in your main script and change sayHi to use your new function

import {helloMsg} from './module.js'

function sayHi() {
for (i=0; i < 3;i++) {
 alert(helloMsg());
}
}

3. At this point you will get an error in browser something like:

SyntaxError: Cannot use import statement outside a module

4. Add type=”module” in your <script> tag:

<script src="js/main.js" type="module"/>

5. After reloading the browser, you will get another error:

Uncaught ReferenceError: i is not defined

6. Now this means that by using type=”module”, the strict mode is enabled by default. That’s why you need to use “use strict”; from the beginning. Now you just need to change that loop to use let:

"use strict";
import {helloMsg} from './module.js'

function sayHi() {
for (let i=0; i < 3;i++) {
 alert(helloMsg());
}
}