MacOSにOracle SQL Developerをインストールする

Oracle DBを操作するインターフェースとしてOracle SQL Developerを試してみることにしました。そのインストールの手順を残します。
私の環境はmacOS Catalinaになります

おまけでSQL DeveloperのJDKのバージョンチェックの仕組みを調べてみました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/9d3e2a7a-37c1-26e2-7a01-a44181b37a4c.png" width=25%>

# インストール
## ダウンロード
公式サイトからソフトをダウンロードします。プラットフォームはMac OSXです。

- [Oracle SQL Developerのダウンロード | Oracle 日本](https://www.oracle.com/jp/tools/downloads/sqldev-downloads.html)

zipファイルを解答するとappファイルが入っています。このappファイルをアプリケーションフォルダに移動すればインストール完了です。

## JDKのインストール
動作させるにはJDKが必要です。以下のサイトからインストールしましょう。バージョンとしては8か11が必要です。

- [Java SE - Downloads | Oracle Technology Network | Oracle](https://www.oracle.com/java/technologies/javase-downloads.html)

古いバージョンのJDKを直接入れるのが嫌なら以下のツールを使ってみると良いかも

- [SDKMAN! the Software Development Kit Manager](https://sdkman.io/)

JDKが入っていない，もしくはバージョンが適切でない場合は以下のようなエラーが発生します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62268/801be735-dd57-23f5-5f05-8a83a966a7cf.png" width=75%>

最低でもJava 8が必要と書かれていますが，最新バージョンを入れても上のアラートが出るのでご注意を。
私は脳死でJDK 16を入れて動かなくて少し詰まりました。 
調べてみると同じようにハマった方々がいらっしゃって，正しいバージョン（JDK 11）をインストールすることで解決できました。

- [Oracle SQLDeveloper on MacOS won't open after installation of correct Java - Stack Overflow](https://stackoverflow.com/questions/50708608/oracle-sqldeveloper-on-macos-wont-open-after-installation-of-correct-java)
- [sqldeveloper - Why can't I open SQL Developer when I have Java 10 installed? - Super User](https://superuser.com/questions/1332715/why-cant-i-open-sql-developer-when-i-have-java-10-installed)
- [MacでOracle SQL Developerを起動するには、Java 8が必要だった - 多趣味エンジニアによる備忘録](https://malmint.hatenablog.com/entry/oracle-sqldeveloper-install)

## 完了
これにてインストール完了です。お疲れさまでした:v:

# おまけ
最新のJDKを入れても動作しないというのが不思議でしたので深ぼって調べてみることにしました。

## JDKバージョンのチェック処理
appファイルを覗いてみるとSQL Developerの起動時に走るシェルスクリプトを見つけました。
`/Applications/SQLDeveloper.app/Contents/MacOS/sqldeveloper.sh`

中身を読んでみると以下のスクリプトでJDKのバージョンをチェックしていました。

``` sh
#!/bin/bash 
TMP_PATH=`/usr/libexec/java_home -F -v 1.8`
if [ -z "$TMP_PATH" ] ; then
  TMP_PATH=`/usr/libexec/java_home -F -v 11`
  if [ -z "$TMP_PATH" ] ; then
    TMP_PATH=`/usr/libexec/java_home -F -v 12`
    if [ -z "$TMP_PATH" ] ; then
      osascript -e 'tell app "System Events" to display dialog "SQL Developer requires a minimum of Java 8. \nJava 8 can be downloaded from:\n http://www.oracle.com/technetwork/java/javase/downloads/"'
      exit 1
    fi
  fi
fi
```

どうやら`/usr/libexec/java_home`というコマンドでバージョンを調べているようです。
if文でJDK 8（1.8）, JDK 11, JDK 12のどれかが入っていると起動できるようにしてあります。
公式では8と11のみ対応となっていましたが，一応12でもOKなようです。
（ここを弄れば最新のJDKでも動かせそうですね:rolling_eyes:）

`osascript`というのがmacOS標準のアラートのようです。

## java_home
`$JAVA_HOME`を読み取ってJDKをチェックするのが普通だと思っていましたが，SQL Developerでは`java_home`というコマンドを使っています。初めて知ったコマンドだったので，ここに関して少し深ぼってみます。

`/usr/libexec/java_home`を覗いてみるとこれはシンボリックリンクで本当のパスは`/System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java_home`でした。
システム直下にあるということでどうやらAppleが提供しているコマンドっぽいです。
`man`で使い方を調べてみます。

```
NAME
       java_home - return a value for $JAVA_HOME


SYNOPSIS
       /usr/libexec/java_home [options]


DESCRIPTION
       The java_home command returns a path suitable for setting the JAVA_HOME
       environment variable.  It determines this path from the user's  enabled
       and  preferred  JVMs  in  the Java Preferences application.  Additional
       constraints may be provided to filter the list of JVMs  available.   By
       default,  if  no  constraints  match  the  available  list of JVMs, the
       default order is used.  The path is printed to standard output.


OPTIONS
       -v or --version	version
	      Filters the returned JVMs  by  the  major  platform  version  in
	      "JVMVersion" form. Example versions: "1.5+", or "1.6*".


       -a or --arch  architecture
	      Filters  the  returned  JVMs  by	the architecture they support.
	      Example architectures: "i386", "x86_64", or "ppc".


       -d or --datamodel  datamodel
	      Filters the returned JVMs capable of running  in	32  or	64-bit
	      mode.  Supported	datamodels:  "-d32"  and  "-d64". Specifying a
	      datamodel is synonymous with specifying a  particular  architec-
	      ture.


       -t or --task  task
	      Selects from the list of JVMs which can run a specific task. The
	      order of each of these lists is  set  by	the  Java  Preferences
	      application.   Supported	tasks:	"Applets",  "WebStart",  "Bun-
	      dledApp", "JNI" and "CommandLine". The default task is "Command-
	      Line".


       -F or --failfast
	      Immediately  fails  when	filters return no JVMs; does not print
	      out the path to the default $JAVA_HOME.


       --exec  command ...
	      Executes the command at $JAVA_HOME/bin/<command> and passes  the
	      remaining arguments. Any arguments to select which $JAVA_HOME to
	      use must precede the --exec option.


       -X or --xml
	      Prints the list of selected JVMs and associated properties as an
	      XML plist to stdout.


       -V or --verbose
	      Prints the matching list of JVMs and architectures to stderr.


       -h or --help
	      Brief usage information.


USAGE
       /usr/libexec/java_home  helps  users set a $JAVA_HOME in their login rc
       files, or provides a way for command-line Java tools to	use  the  most
       appropriate  JVM  which	can  satisfy a minimum version or architecture
       requirement. The --exec argument  can  invoke  tools  in  the  selected
       $JAVA_HOME/bin  directory,  which  is useful for starting Java command-
       line tools from launchd plists without hardcoding the full path to  the
       Java command-line tool.


       Usage for bash-style shells:
	      $ export JAVA_HOME=`/usr/libexec/java_home`

       Usage for csh-style shells:
	      % setenv JAVA_HOME `/usr/libexec/java_home`




				04 August 2010			

```

`sqldeveloper.sh`と照らし合わせてみます。
`-v`オプションでは指定したバージョンの`JAVA_PATH`を返します。しかし，指定したバージョンよりも新しいJDKがあればそのパスを返してしまいます。
そのため，`-F`オプションを付けることで指定したバージョンのJDKがないときに`JAVA_HOME`を返さないようにしているようです。

ちなみに`-V`オプションを付けるとインストールされたJDKの一覧を見れます。

## まとめ
ということでSQL DeveloperのJDKバージョンをチェックする仕組みを調べてみました。macOSでは`java_home`を使うのが良さそうに思えました。