[JAVA] Download JDBC driver after build

Products that support multiple databases will usually use Maven profiles to switch dependencies, but it's a hassle because you need a Maven build for each profile.

Therefore, consider leaving one Jar for the application and adding the JDBC driver required at runtime later.

Prepare the following shell.

fetch_jdbc_driver.sh


#!/bin/bash -u

## requires: curl xmllint

declare -A drivers
drivers["h2"]="com.h2database:h2:RELEASE"
drivers["mysql"]="mysql:mysql-connector-java:RELEASE"
drivers["postgres"]="org.postgresql:postgresql:42.2.1"
drivers["sqlserver"]="com.microsoft.sqlserver:mssql-jdbc:6.4.0.jre8"

remote_repository=https://repo.maven.apache.org/maven2

function resolve_version () {
    local version_alias=$1
    local metadata_url=${remote_repository}/$2/maven-metadata.xml
    local xpath="/metadata/versioning/$(echo ${version_alias} | tr 'A-Z' 'a-z')/text()|/metadata/version/text()"

    curl -s ${metadata_url} | xmllint --xpath "$xpath" -
}

function fetch_driver () {
    local dbtype=$1
    local version=$2
    local deps=(`echo ${drivers[$dbtype]} | tr -s ':' ' '`)

    if [ ${#deps[@]} -eq 0 ]; then
        echo "Unknown database type: $dbtype"
        exit 1
    fi

    local group_path=$(echo ${deps[0]} | tr -s '.' '/')
    local artifact_path=${deps[1]}
    if [ -z "${version}" ]; then
        version=${deps[2]}
    fi

    if [ $version = "RELEASE" -o $version = "LATEST" ]; then
        version=$(resolve_version $version "${group_path}/${artifact_path}")
    fi

    local jarfile=${deps[1]}-${version}.jar
    curl -sL -o $dest_dir/$jarfile -w '%{http_code}' \
         ${remote_repository}/${group_path}/${deps[1]}/$version/$jarfile
}

dest_dir=runtime

if [ ! -e "$dest_dir" ]; then
    mkdir -p $dest_dir
fi

for arg in "$@"
do
    dbtypes=(`echo $arg | tr ':' ' '`)
    ret=$(fetch_driver ${dbtypes[0]} ${dbtypes[1]:-""})

    if [ $ret -eq 200 ]; then
        echo "Install driver: ${dbtypes[0]}"
    else
        echo "Not found: ${dbtypes[0]}"
    fi
done
% ./fetch_jdbc_driver mysql

Download the latest JDBC driver like this. It is also possible to specify a specific version.

% ./fetch_jdbc_driver mysql:8.0.9-rc

You can use it like this in the Dockerfile.

Dockerfile


FROM alpine AS build

ARG RASCALOID_VERSION=0.1.0-SNAPSHOT
ARG dbtype=h2
RUN apk --no-cache add curl jq libxml2-utils bash

RUN mkdir /rascaloid
WORKDIR /rascaloid
RUN curl 'https://circleci.com/api/v1.1/project/github/kawasima/rascaloid/latest/artifacts?branch=develop&filter=successful' \
    | jq "map(select(.[\"path\"] == \"home/circleci/repo/target/rascaloid-${RASCALOID_VERSION}.jar\"))" \
    | jq '.[0]["url"]' \
    | xargs curl -o rascaloid.jar

ADD fetch_jdbc_driver.sh /usr/local/bin
RUN fetch_jdbc_driver.sh $dbtype

RUN apk del --purge curl jq libxml2-utils

FROM openjdk:8-alpine
COPY --from=build /rascaloid/ /rascaloid/
WORKDIR rascaloid
ENTRYPOINT ["java", "-cp", "rascaloid.jar:runtime/*", "net.unit8.rascaloid.Main"]

Recommended Posts

Download JDBC driver after build
A little addictive story after updating the JDBC driver for PostgreSQL
How to make a JDBC driver