the JDBC Driver has been forcibly unregistered


My Tomcat instance keeps complaining about de-registration failures of JDBC drivers whenever my web app re-deployed.

The web application [some-fine-webapp] registered the JDBC driver [some.nasty.JdbcDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.

This is actually not a problem. That message means that the Tomcat took care of something by himself.

I pay or I owe.

@WebListener
public class EpdServletContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(final ServletContextEvent sce) {
    }

    @Override
    public void contextDestroyed(final ServletContextEvent sce) {
        // Is this safe? De-registering while enumerating?
        for (final Enumeration<Driver> drivers = DriverManager.getDrivers();
             drivers.hasMoreElements();) {
            try {
                DriverManager.deregisterDriver(drivers.nextElement());
            } catch (final SQLException sqle) {
            }
        }
    }
}

Well, well, well.

Collections.list(DriverManager.getDrivers()).forEach(d -> {
    try {
        DriverManager.deregisterDriver(d);
    } catch (final SQLException sqle) {
    }
});

Shell script for restarting tomcat


References

startup/shutdown

There are two shell scripts for starting up and shutting down tomcat instance. The former is startup.sh and the latter is shutdown.sh.
It is not a big deal for making another shell script calls these two scripts in a row.

$ cat restart.sh
#!/bin/sh
sh ./shutdown.sh
sh ./startup.sh
$ 

The problem is that this script doesn’t run outside the directory contains the script. You can find a solution for this problem from the link above.

$ cat restart.sh
wd="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
sh $wd/shutdown.sh
sh $wd/startup.sh
$ 

Shift Operators in Java


References

Quiz

                          // 31                  15                 0
final int i = -1;         //  1111 1111 1111 1111 1111 1111 1111 1111

final int a = (i >>>  1); //  0111 1111 1111 1111 1111 1111 1111 1111
final int b = (i >>> 15); //  0000 0000 0000 0001 1111 1111 1111 1111
final int c = (i >>> 17); //  0000 0000 0000 0000 0111 1111 1111 1111
final int d = (i >>> 31); //  0000 0000 0000 0000 0000 0000 0000 0001

final int e = (i >>> 32); //  ???? ???? ???? ???? ???? ???? ???? ????
assert e == 0; // @@?

Answer

Here is a quote from The Java® Language Specification, Java SE 8 Edition.

If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.

Here are actual values of each right operands evaluated in above code.

decimal hexadecimal binary & 0b11111
 1 0x01 0000 0000 0000 0000 0000 0000 000 0 0001 0b00001 (0x01)
15 0x0F 0000 0000 0000 0000 0000 0000 000 0 1111 0b01111 (0x0F)
17 0x11 0000 0000 0000 0000 0000 0000 000 1 0001 0b10001 (0x11)
31 0x1F 0000 0000 0000 0000 0000 0000 000 1 1111 0b11111 (0x1F)
32 0x20 0000 0000 0000 0000 0000 0000 001 0 0000 0b00000 (0x00)

Do it for yourself

$ cat ShiftTest.java
public class ShiftTest {
    public static void main(final String[] args) {
        System.out.printf("%+d\n", -1 >>> 31);
        System.out.printf("%+d\n", -1 >>> 32);
    }
}
$ javac ShiftTest.java
$ java ShiftTest
+1
-1
$

Singleton Design Pattern


references

double-checked locking

public class MySingleton {

    private static volatile MySingleton INSTANCE = null; // volatile

    public static MySingleton getInstance() {
        if (INSTANCE == null) {                          // check 1
            synchronized (MySingleton.class) {
                if (INSTANCE == null) {                  // check 2
                    INSTANCE = new MySingleton();
                }
            }
        }
        return INSTANCE;
    }

    private MySingleton() {
        super();
    }
}

initialization-on-demand holder idiom

public class MySingleton {

    private static class InstanceHolder {
        private static final MySingleton INSTANCE = new MySingleton(); // final
    }

    public static MySingleton getInstance() {
        return InstanceHolder.INSTANCE;
    }

    private MySingleton() {
        super();
    }
}