桜技録

🐈🐈🐈🐈🐘

Oracle 18c XE on CentOS 7.9 on VirtualBoxセットアップ

自分用の作業記録。

  • CentOS 7.9 (2009)
  • Oracle Database Express Edition Release 18.4.0.0.0

仮想マシン構成

  • メモリ: 4096 MB
  • ストレージ: 16 GB VDI (Dynamically allocated)
  • ネットワーク1: NAT
  • ネットワーク2: Host-only Adapter (DHCP disabled)

Oracle XEのインストールに際してインターネットからの依存パッケージのDLが発生する為NATでインターネット・アクセスを可能にする。

ホストマシンからDBへ接続が行えるようHost-only Adapterを追加している。なおホストマシンからは固定IPでアクセスしたいのでDHCPは使わない。

ゲストOSインストール

https://www.centos.org/centos-linux/ からDLしたインストール・メディア(DVDタイプ)をIDEバイスに追加して仮想マシンを起動。GUIインストーラが立ち上がる。

[INSTALLATION SOURCE] 、 [INSTALLATION DESTINATION] はデフォルトのまま。 [SOFTWARE SELECTION] には Minimal Install を指定した。

[NETWORK & HOSTNAME] を開いてアダプタが2つ認識されていることを確認。 enp0s3enp0s8 という名前が付いていた。

enp0s3の接続をONにするとHost-only Adapterのネットワーク・アドレスには乗らないIPアドレスが振られていたのでNATの方のアダプタだと判明。

もう一方のenp0s8は接続がONにできない。 [IPv4 Settings] を開き、 [Method] に Manual を指定、 [Additional static addresses] にHost-only Adapterに適合するゲートウェイサブネットマスクIPアドレスを追加する。これで接続をONにできる。

あとは流れに沿ってインストールを進める。

ホストマシンからの接続確認

インストール後の再起動が済んだらホストマシンからsshでリモート・ログインを試みる。インストーラでネットワーク設定を終わらせておいたので繋がると思ったが失敗。

VirtualBoxのウィンドウからログイン、 ip addr してみる。

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:4e:db:2d brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic enp0s3
       valid_lft 86388sec preferred_lft 86388sec
    inet6 fe80::a00:27ff:fe4e:db2d/64 scope link
       valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:11:f1:63 brd ff:ff:ff:ff:ff:ff

enp0s8にIPアドレスが振られていない。 nmtui でenp0s8の設定を確認すると何故か [Automatically connect] にチェックが付いていなかった。チェックを付けて systemctl restart NetworkManager する。

ip addr でenp0s8に固定IPが表示されること、ホストマシンからssh接続できることを確認する。

Oracle XEインストール

マニュアルに従って実施。

https://docs.oracle.com/en/database/oracle/oracle-database/18/xeinl/procedure-installing-oracle-database-xe.html

https://docs.oracle.com/en/database/oracle/oracle-database/18/xeinl/setting-oracle-database-xe-environment-variables.html

自動起動の設定

OSが立ち上がったらOracle XEも起動するようにする。

chkconfig --add oracle-xe-18c

ファイアウォールの設定

デフォルトでOracleのリスナが使う1521番ポートへ外部(ホストマシン)から接続ができるようにする。

firewall-cmd --permanent --add-port=1521/tcp
firewall-cmd --reload

Raspberry Pi 4Bの有線+固定IP+headlessセットアップ

キーボード/ディスプレイなしでラズパイをセットアップした作業記録。作業PCはmacOS

PC上での作業には💻、リモート接続したラズパイ上での作業には🥧を以下見出しに付ける。

💻 OSインストール

導入するのはGUIレスで軽量なRaspberry Pi OS Lite。

公式のDLページからOSイメージのzipを入手、解凍する。

PCにSDカードを挿す前と後で diskutil list でディスク一覧を表示、使用するSDカードのデバイス・ファイル名を確認する。

dd コマンドでOSイメージをSDカードに焼く。書き込み先には上で確認したデバイス・ファイルを指定すること。

# SDカードをアンマウント
diskutil unmountDisk /dev/disk2

# イメージをコピー
sudo dd bs=1M if=2020-08-20-raspios-buster-armhf-lite.img of=/dev/rdisk2; sync

コピーが終わると /Volumes/boot が見えるようになる。

[参考] https://www.raspberrypi.org/documentation/installation/installing-images/mac.md

💻 SSHを有効化

touch /Volumes/boot/ssh で空ファイルを作る。起動時に /boot/ssh というファイルがあればSSHサービスが有効になる仕組み。

[参考] https://www.raspberrypi.org/documentation/remote-access/ssh/README.md

💻 Bluetooth / Wi-Fiを無効化

無線を使うつもりがないので切った。/boot/config.txt に下を設定する。

# Bluetoothを無効
dtoverlay=disable-bt

# Wi-Fiを無効
dtoverlay=disable-wifi

パラメータの詳細や他に設定可能なパラメータ等は /boot/overlays/README に記載アリ。

💻 起動+SSH接続

SDカードをラズパイに挿し、LANケーブルに繋いで電源を投入する。

緑色LEDの点滅が落ち着き起動し終えたと思われるタイミングでPCからSSH接続する。初期パスワードは raspberry

ssh pi@raspberrypi.local

🥧 aptアップグレード

近場のサイト(ここではJAIST)をミラーサイト一覧から探して /etc/apt/sources.list のURLを置き換える。

すべてのパッケージを最新化する。

sudo apt-get update \
  && sudo apt-get -y upgrade \
  && sudo apt-get -y dist-upgrade \
  && sudo apt-get -y autoremove \
  && sudo apt-get autoclean

🥧 rasp-configアップグレード

Raspberry Pi OSの設定ツールrasp-configを最新化。sudo rasp-config で起動するとメニューが立ち上がるので [Update] を選択する。

🥧 ロケールを設定

rasp-configで設定。[Localisation Options] > [Change Locale] で言語に en_US.UTF-8 を、[Localisation Options] > [Change Time Zone] でタイムゾーンAsia/Tokyo を設定する。

※再起動するまで反映されない。

🥧 ホスト名を変更

rasp-configで設定。[Network Options] > [Hostname] でホスト名を変更する。

※再起動するまで反映されない。

🥧 IPアドレスを固定

/etc/dhcpcd.conf に下を設定する。

interface eth0
static ip_address=192.168.11.2/24        # IPアドレス/サブネットマスク
static routers=192.168.11.1              # デフォルト・ゲートウェイ
static domain_name_servers=192.168.11.1  # DNSサーバ

※再起動するまで反映されない。

LAN内でDHCPを運用している場合はIPアドレスが衝突しないようDHCPの付番範囲外のアドレスを使うこと。

[参考] https://www.raspberrypi.org/documentation/configuration/tcpip/README.md

🥧 再起動+設定確認

sudo reboot でOSを再起動する。

新しいIPアドレスSSH接続出来ることを確認する。

新しいホスト名がプロンプトに表示されていることを確認する。

指定したロケールlocale コマンドで表示されることを確認する。

無線LANインタフェース wlan0ip link コマンドで表示されないことを確認する。

適当なデバイスでそれらしいBluetoothが飛んでいないことを確認する。

💻 known_hostsのゴミを掃除

IP変える前に接続した時のゴミが ~/.ssh/known_hosts に残るので消しておく。

ssh-keygen -R raspberrypi.local

macOS 10.15向けにMozcをビルド

偉大な先駆者様。

環境

必要なもの

  • Ninja

  • Qt

いずれもHomebrewでインストール(Ninja 1.10.1 / Qt 5.15.1)。ビルド・スクリプトを動かすのに必要なPythonはOSプリインストールのもの(2.7.16)で問題なかった。

手順

基本は公式のHow to buildに従う。

リポジトリのclone

git clone https://github.com/google/mozc.git -b master --single-branch --recursive

cd mozc/src

以降の作業はcloneしたプロジェクト直下のsrcで行う。

ビルド

SDKとターゲットのバージョンを環境に合わせ、Qtのインストール場所をオプションで指定。

GYP_DEFINES="mac_sdk=10.15 mac_deployment_target=10.15" python build_mozc.py gyp --qtdir=/usr/local/opt/qt
python build_mozc.py build -c Release mac/mac.gyp:GoogleJapaneseInput gui/gui.gyp:config_dialog_main
python build_mozc.py build -c Release mac/mac.gyp:GoogleJapaneseInput mac/mac.gyp:gen_launchd_confs

が、下のエラーに遭遇。

/Users/sciencesakura/works/Clone/mozc/src/out_mac/Release/Breakpad/src/client/mac/sender/Breakpad.xib:global: error: Compiling for earlier than macOS 10.6 is no longer supported. [12]

エラー対処

コンパイル・ターゲットが古いということでBreakpad.xibを修正する。

  1. third_party/breakpad/src/client/mac/sender/Breakpad.xibXcodeで開く。エラーで指摘されたファイルとは異なるパスなので注意。

  2. 「Trust opening older file format?」と古くて安全でないフォーマットを新しいフォーマットに変換していいか訊かれるので「Open and Upgrade」で続ける。

  3. [Show the File inspector] > [Interface Builder Document] > [Document Editing] > [Build for] に「macOS 10.15 and Later」を指定して保存。

  4. Cleanして再ビルド。

インストール

成果物を所定の場所へ配置。

sudo cp -r out_mac/Release/Mozc.app /Library/Input\ Methods/
sudo cp out_mac/Release/gen/mac/org.mozc.inputmethod.Japanese.Converter.plist out_mac/Release/gen/mac/org.mozc.inputmethod.Japanese.Renderer.plist /Library/LaunchAgents

OSを再起動すると [System Preferences] > [Keyboard] > [Input Sources] でMozcが選択可能になる。

ノート: 情報科学における論理③

間が空いてしまったけれど小野寛晰『情報科学における論理』の読書ノート。なるべく練習問題も解いてく。(→前回)

第2章 述語論理

述語論理の論理式

言語

述語論理を記述するのに必要な以下の記号の集まりを言語(language)という。

  • 論理結合子 :  \land , \lor , \rightarrow , \lnot

  • 量化記号  :  \forall , \exists

  • 対象変数  : 議論対象の「もの」の集合を動く変数

  • 対象定数  : 議論対象の「もの」の集合のうち特定の要素を表す記号

  • 関数記号  : 議論対象の「もの」の集合上に定義された関数を表す記号

  • 述語記号  : 議論対象の「もの」の集合上に定義された述語を表す記号 

  • 補助記号  : 括弧やカンマなど

  • 対象変数、対象定数は項(term)

  •  f  m 変数の関数記号、  t_i が項のとき、  f ( t_1 , \cdots , t_m ) は項

論理式
  •  P  n 変数の述語記号、  t_i が項のとき、  P ( t_1 , \cdots , t_n ) 論理式(formula)(この形を特に原子論理式(atomic formula)という)

  •  A , B が論理式のとき、  A \land B , A \lor B , A \rightarrow B , \lnot A は論理式

  •  A が論理式、  x が対象変数のとき、  \forall x A , \exists x A は論理式

束縛変数と自由変数

論理式  \forall x A , \exists x A に於いて変数  x 出現(occurrence)を束縛された出現といい、  x束縛変数(bound variable)という。反対に束縛されていない出現を自由な出現といい、その変数を自由変数(free variable)という。

自由変数のない論理式を閉じた論理式(closed formula)といい、論理式  A のすべての自由変数  x_1 , \cdots , x_n を全称記号で束縛した論理式  \forall x_1 \cdots \forall x_n A  A 閉包(universal closure)という。

代入

論理式  A の自由変数  x を項  t で置き換えた論理式を  A [ t / x ] と表し、  x への  t 代入(substitution)という。特に複数回の代入を順序を設けず同時に実施する際は  A [ t_1 / x_1 , \cdots , t_n / x_n ] のように表す。

構造

言語  \mathscr{ L } に対する構造(structure)  \mathfrak{ A } = ( U , I ) の定義。

  •  U  \mathscr{ L } の対象変数が動く空でない集合。対象領域(domain)

  •  I  \mathscr{ L } の対象定数を  U の要素に、関数記号を  U 上の関数に、述語記号を  U 上の述語に対応させる写像解釈(interpretation)

解釈  I による像は  I ( x ) ではなく  x^{ I } と表記するのが一般的な模様。

論理式  A が構造  \mathfrak{ A } で正しいことを  \mathfrak { A } \vDash A で表す。

恒真な論理式

ある言語上の論理式  A が任意の構造に於いて正しいとき  A 恒真である(valid)といい、  \vDash A と表す。

ラッセルのパラドックス

自分自身を要素に含まない集合からなる集合  P = \{ x | x \notin x \} を想定したとき、  P 自身は  P に含まれるか否かという問題。ZFC公理系の集合論に於いてはそもそも  P のような集合は集合であると認められない為パラドックスは成立しない(聞きかじり)。

練習問題

問2.1

1)-1 「ある学生が存在し、すべての教師が好きだ」すなわち「教師を好む学生がいる」

1)-2 「すべての怠け者はすべての教師が好きでない」すなわち「怠け者は教師を好きではない」

2)  \lnot \forall x ( T ( x ) \rightarrow L ( x ) )

問2.2

1) 「任意の実数  x , y について、  x \lt y ならば  x \lt z かつ  z \lt y を満たす実数  z が存在する」すなわち「実数は稠密である」

2) 「任意の実数  x , y , z について、  x \lt z かつ  z \lt y ならば  x \lt y 」すなわち「関係  \lt は推移律を満たす」

問2.3

 s  x が出現しない、かつ  t  y が出現しないこと

問2.4

等しいとはいえない。以下いずれをも満たす必要がある

  •  t  x が出現しないこと

  •  B_z  \forall z C または  \exists z C としたとき、  C に自由変数  x の出現する  B_y 、 自由変数  x の出現する  B_t 、 自由変数  y の出現する  B_t がいずれも  A の部分論理式でないこと

問2.5

1)-1 成り立たない。最大元は存在しない

1)-2 成り立つ。  x = a_4 のとき  y = a_4 とし、それ以外は  y = a_5 とすればよい

2)-3 成り立つ。  ( y , z ) = ( a_4 , a_5 ) のときなど

2)-4 成り立たない。  ( x , y , z ) = ( a_1 , a_2 , a_3 ) のときなど

問2.6

1)  \forall s \forall t ( ( A [ s / x ] \land A [ t / x ] ) \rightarrow s = t )

2)  \forall s \forall t ( ( A [ s / x ] \land A [ t / x ] ) \rightarrow s = t ) \land \exists s A [ s / x ]

3)  \exists s \exists t ( ( A [ s / x ] \land A [ t / x ] ) \land \lnot ( s = t ) )

問2.7

1)  \exists x \forall y ( x \leq y ) 自然数に最小元は存在するが整数には存在しない)

2)  \exists x \exists y ( \lnot ( y \leq x ) \land \forall z ( \lnot ( x \leq z ) \lor \lnot ( z \leq y ) ) ) (「間にどんな要素も挟まらない異なる2要素が存在する」の意。整数では正しいが有理数では正しくない)

問2.9

8) 構造  \mathfrak{ A } = ( \mathbf{ N } , I ) をとる。但し  D  x R y とし、  R^{ I } に大小関係  \gt をとる。このとき任意の自然数に対して真に大きい自然数は存在するが、すべての自然数より真に大きな自然数は存在しない。つまり  \mathfrak{ A } \vDash \forall y \exists x ( x R y ) かつ  \mathfrak{ A } \nvDash \exists x \forall y ( x R y ) 、従って  \mathfrak{ A } \nvDash \forall y \exists x ( x R y ) \rightarrow \exists x \forall y ( x R y )

9) 構造  ( \{ 0 , 1 \} , I ) をとればよい。但し  B  P ( x ) とし、  P^{ I } に「1である」をとる。

14) 構造  \mathfrak{ A } = ( \mathbf{ N } , I ) をとる。但し  ( B , C )  ( P ( x ) , Q ( x ) ) とし、  P^{ I } , Q^{ I } にそれぞれ「偶数である」、「奇数である」をとる。このとき明らかに  \mathfrak{ A } \nvDash \forall x P ( x ) 、よって  \mathfrak{ A } \vDash \forall x P ( x ) \rightarrow \forall x Q ( x ) 。一方これもまた明らかに  \mathfrak{ A } \nvDash \forall x ( P ( x ) \rightarrow Q ( x ) ) 。従って  \mathfrak{ A } \nvDash ( \forall x P ( x ) \rightarrow \forall x Q ( x ) ) \rightarrow \forall x ( P ( x ) \rightarrow Q ( x ) )

15) 構造  ( \{ 0 , 1 \} , I ) をとればよい。但し  ( B , C )  ( P ( x ) , Q ( x ) ) とし、  P^{ I } , Q^ { I } にそれぞれ「0または1である」、「1である」をとる。

問2.10

恒真でない。  \mathfrak{ A } \nvDash \exists x P ( x ) となるような構造  \mathfrak{ A } を示せばOK。

問2.11

1) 
  \exists x R ( x , y ) \rightarrow \forall y ( P ( y ) \land \lnot \forall z Q ( z ) ) \\
  = \forall x ( R ( x , y ) \rightarrow \forall y ( P ( y ) \land \lnot \forall z Q ( z ) ) ) \\
  = \forall x \forall t ( R ( x , y ) \rightarrow ( P ( t ) \land \lnot \forall z Q ( z ) ) ) \\
  = \forall x \forall t \exists z ( R ( x , y ) \rightarrow ( P ( t ) \land \lnot Q ( z ) ) )

2) 
  \exists x ( \forall y ( P ( y ) \rightarrow Q ( x , z ) ) \lor \exists z ( \lnot \exists u R ( z , u ) \land Q ( x , z ) ) ) \\
  = \exists x \forall y ( ( P ( y ) \rightarrow Q ( x , z ) ) \lor \exists z ( \lnot \exists u R ( z , u ) \land Q ( x , z ) ) ) \\
  = \exists x \forall y \exists t ( ( P ( y ) \rightarrow Q ( x , z ) ) \lor ( \lnot \exists u R ( t , u ) \land Q ( x , t ) ) ) \\
  = \exists x \forall y \exists t \forall u ( ( P ( y ) \rightarrow Q ( x , z ) ) \lor ( \lnot R ( t , u ) \land Q ( x , t ) ) )

Gradle+JaCoCoでカバレッジ・レポートから除外したいファイルを指定する

jacocoTestReport {
  afterEvaluate {
    classDirectories.setFrom(classDirectories.files.collect {
      fileTree(dir: it, excludes: ["**/xxx/*", "**/Yyy.class"])
    })
  }
}

前は classDirectories にフィルタしたファイルコレクションを直接代入していたけれどGradle 6.0より読取専用になっているので代わりに setFrom メソッドを使う。

GradleからTomcat Manager Appを操作してwarをデプロイする

Gradleを使ってwarファイルをTomcatにデプロイしたいという場面に於いて、warファイルを$CATALINA_BASE/webappsにコピーする手法をよく見かけるが、それとは異なる手法としてTomcatにデフォルトで入っているManager AppをGradleから使う術を記しておく。

warファイルのコピーは単純だがGradleから見てコピー先がローカルなのかネットワーク上なのかDockerコンテナ内なのかを意識する必要がある。一方HTTPクライアントからManager Appを叩く分にはそのような環境差異を意識する必要はなく複数の異なる環境でもビルド・スクリプトを共有しやすい。

前準備

まずはManager AppをGUIレスで使えるようにする。

Tomcatをインストールした直後はManager Appを始めとしたプリインストールのアプリは$CATALINA_BASE/webapps.distにありデフォルトで無効になっている。これを$CATALINA_BASE/webappsから見えるようにする。

下はシンボリック・リンクを用いた例。

ln -s \
  $CATALINA_BASE/webapps.dist/manager \
  $CATALINA_BASE/webapps/

続いて$CATALINA_BASE/conf/tomcat-user.xmlを編集しmanager-scriptロールを持つユーザを作成する。

<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
  <role rolename="manager-script"/>
  <user username="USERNAME" password="PASSWORD" roles="manager-script"/>
</tomcat-users>

WebブラウザからGUIでManager Appを使う為のmanager-guiというロールもあるが同一ユーザにmanager-guiとmanager-scriptを一緒に持たせないことが推奨されている*1。(もしGUIも使うのであれば)GUI用とスクリプト用でユーザを分けるのが良いだろう。

最後にManager Appへの接続を許可するアクセス元アドレスの範囲を必要に応じて$CATALINA_BASE/conf/[enginename]/[hostname]/manager.xmlに設定する。

デフォルトの設定は$CATALINA_BASE/webapps.dist/manager/META-INF/context.xmlにありループバック・アドレスからのみを許可している。ネットワーク上のサーバであれば管理セグメントの特定ノードからは許可する等といった変更がいるだろう。

下は192.168.1.*からのアクセスを許可する例。

<Context privileged="true" antiResourceLocking="false">
   <Valve className="org.apache.catalina.valves.RemoteAddrValve" 
          allow="192\.168\.1\.\d+" />
</Context>

以上の設定を済ましてTomcatを再起動すれば作成したユーザでリモート・デプロイが可能になる。

Gradleでデプロイ

下例ではHTTPクライアントとして個人的にGradleで使いやすいと感じているgradle-http-pluginでdeployタスクを定義してみた。

USERNAMEPASSWORDは上で作成したmanager-scriptユーザのもの。外部定義して環境毎にURLとユーザを切り替えれば複数環境でタスクを共有出来る。

import groovyx.net.http.NativeHandlers
import io.github.httpbuilderng.http.HttpTask

plugins {
  id 'war'
  id 'io.github.http-builder-ng.http-plugin' version '0.1.1'
}

task deploy(type: HttpTask, dependsOn: 'war') {
  config {
    request.uri = 'http://example.com:8080'
    request.auth.basic('USERNAME', 'PASSWORD')
    request.encoder('application/octet-stream', NativeHandlers.Encoders.&handleRawUpload)
  }
  put {
    request.uri.path = '/manager/text/deploy'
    request.uri.query = [path: "/${war.archiveBaseName.get()}", update: true]
    request.contentType = 'application/octet-stream'
    request.body = war.archiveFile.get().asFile
    response.success { fs, body ->
      def message = body as String
      println(message)
      if (message.startsWith('FAIL')) throw new Exception(message)
    }
  }
}

ポイントとなるのはrequest.uri.queryに渡しているクエリパラメータ。

  1. path:対象アプリのコンテキストパスを/myappのようにスラッシュ始まりで指定する。GUIのManager Appやwar配置と違って省略することは出来ない。ROOTアプリケーションの場合は単に/を指定する。ここでは/ + warファイルのベース名を指定している。

  2. update:pathで指定したコンテキストパスにアプリがすでにあった場合の動作を制御する。false(デフォルト値)ならエラーとし、trueならば既存アプリをアンデプロイした後warをデプロイする。繰り返し使用する使途ではtrue固定で良いだろう。

その他に指定可能なパラメータやデプロイ以外に用意されているAPI(アンデプロイやアプリの一覧取得)は公式マニュアルが詳しい。

おまけ:curlでデプロイ

curlでも十分戦える。

curl --basic --user USERNAME:PASSWORD \
  --upload-file build/libs/myapp.war \
  'http://example.com:8080/manager/text/deploy?path=/myapp&update=true'

Maven CentralのRepository Writableエラー

Gradle 6.0.1のMaven Publishプラグインを使ってパッケージをMaven Centralへリリースしようとしたところ以下のエラーで失敗してしまった。

f:id:sciencesakura:20200329212120p:plain

Event: Failed: Repository Writable

typeId         RepositoryWritePolicy
failureMessage Artifact updating: Repository ='releases:Releases' does not allow updating artifact='/com/sciencesakura/dbsetup-spreadsheet/maven-metadata.xml.sha512'
failureMessage Artifact updating: Repository ='releases:Releases' does not allow updating artifact='/com/sciencesakura/dbsetup-spreadsheet/maven-metadata.xml.sha256'

探したところ既にissueが立っていた。

https://issues.sonatype.org/browse/MVNCENTRAL-5276

https://issues.sonatype.org/browse/NEXUS-21802

チェックサムに使用するハッシュ関数としてSHA-256とSHA-512がGradle 6.0で追加されたのだが、NexusMaven Centralのリポジトリ・マネージャ)側にmaven-metadata.xmlのSHA-256/SHA-512チェックサムがあるとリリースに失敗する問題があったということらしい(2020年3月現在未解決)。

暫定的な回避策は2つ提示されている。

回避策①:チェックサムを手動削除

Staging repositoryでclose処理する前にアップロードしたファイルの中からmaven-metadata.xml.sha256maven-metadata.xml.sha512を消す。

試していないがNexus管理画面のContentタブでアップロードしたファイルの一覧が閲覧出来るのでおそらくそこで削除が出来るのだろう。

回避策②:チェックサムを無視するフラグを有効化

Gradle 6.0.1で追加されたシステム・プロパティorg.gradle.internal.publish.checksums.insecuretrueを設定する。これによりSHA-256/SHA-512のチェックサムがアップロードされなくなる。

プロジェクト直下のgradle.propertiesに次の行を加えると良い。

systemProp.org.gradle.internal.publish.checksums.insecure=true