# Java

Java 是一種廣泛使用的電腦程式設計語言，擁有跨平台、物件導向、泛型程式設計的特性，廣泛應用於企業級Web應用開發和行動應用開發。

# jpackage in Java 14

**jpackage** is a command-line tool to create native installers and packages for Java applications.

#### Install OpenJDK 14

On Ubuntu 20.04/18.04

```shell
curl -O https://download.java.net/java/GA/jdk14/076bab302c7b4508975440c56f6cc26a/36/GPL/openjdk-14_linux-x64_bin.tar.gz
tar xvf openjdk-14_linux-x64_bin.tar.gz
mv jdk-14 $HOME/opt/
```

On Mac  
Download: [https://jdk.java.net/14/](https://jdk.java.net/14/)

```shell
cd ~/Downloads
tar xf openjdk-14_osx-x64_bin.tar.gz

sudo mv jdk-14.jdk /Library/Java/JavaVirtualMachines/
java -version
```

#### Packing JAR as .deb/.dmg

將可以直接執行的單一 jar 檔封裝成 Debin-based 安裝檔。

```shell
mkdir {icons,input,output,temp}

tree -L 3 --dirsfirst --filelimit 10 --sort=name
.
├── icons
│   └── CloudCoin_Wallet-Dark.png
├── input
│   └── CloudCoin.D.3.0.15.jar
├── output
│   ├── CloudCoin_Wallet-Dark
│   │   ├── bin
│   │   └── lib
│   └── cloudcoin-wallet-dark_3.0.15-1_amd64.deb
├── temp
├── build.sh
└── license.txt

7 directories, 5 files
```

檔案目錄說明：

- icons: App 的圖示檔(\*.png), size 256x256
- input: 原始的 jar 檔
- output: 封裝後的 .deb 檔案
- temp: 封裝過程中會用到的暫存檔
- build.sh: 封裝啟動檔
- license.txt: App 的使用授權宣告

build.sh for deb：

```shell
export PATH="$PATH:~/opt/jdk-14/bin"

[ -d temp ] && rm -rf temp/*
jpackage \
--type deb \
--name CloudCoin_Wallet-Dark \
--description "CloudCoin Wallet - Dark Edition. Homepage: https//cloudcoin.global." \
--vendor "CloudCoin Consortium" \
--app-version 3.0.15 \
--input input --dest output --temp temp \
--icon icons/CloudCoin_Wallet-Dark.png \
--license-file license.txt \
--copyright "CloudCoin™ Global Consortium © 2020 The Future of Currency" \
--main-jar CloudCoin.D.3.0.15.jar \
--linux-deb-maintainer alang.hsu@gmail.com \
--linux-app-category misc \
--linux-shortcut
```

- PATH：JDK 14 的安裝目錄，也就是 jpackage 的儲存目錄。
- 第 3 行：每次封裝前，先清除目錄 temp。
- --type：封裝檔的類型。
- --name：應用程式名稱。
- --description：應用程式更多描述。
- --vendor：來源製造商。
- --input：input 目錄路徑。
- --dest：output 目錄路徑。
- --temp：temp 目錄路徑。
- --icon：App 圖示檔路徑。
- --license-file：使用授權宣告檔。
- --main-jar：原始 jar 檔名。
- --linux-deb-maintainer：維護者名稱。
- --linux-app-category：應用程式類型。
- --linux-shortcut：建立應用程式啟動檔。

build.sh for dmg：

```shell
export PATH="$PATH:/Library/Java/JavaVirtualMachines/jdk-14.0.1.jdk/Contents/Home/bin"

[ -d temp ] && rm -rf temp/*
jpackage \
--type dmg \
--name CloudCoin_Wallet-Dark \
--main-jar CloudCoin.D.3.0.22.jar \
--input input --dest output --temp temp \
--app-version 3.0.22 \
--icon icons/CloudCoin_Wallet-Dark.icns \
--vendor "CloudCoin Consortium"
```

開始封裝

```shell
bash build.sh
```

- 封裝完成的安裝檔（.deb，.dmg）會儲存在目錄 output。
- 封裝後的 DMG 檔並沒有經過 Mac 軟體的簽署，安裝時必須先手動執行指令。

安裝沒有簽署的 DMG

```shell
sudo spctl --master-disable

# Install the DMG app

sudo spctl --master-enable
```

檢查 .dmg 是否已簽署

```shell
codesign -dvv CloudCoin_Wallet-$VERSION.dmg
# or
spctl -a -v CloudCoin_Wallet-$VERSION.dmg
```

如何簽署 DMG

- [Distribute outside the Mac App Store (macOS)](https://help.apple.com/xcode/mac/current/#/dev033e997ca)
- [Sign a Mac Installer Package with a Developer ID certificate](https://help.apple.com/xcode/mac/current/#/deve51ce7c3d)
- [Create, export, and delete signing certificates](https://help.apple.com/xcode/mac/current/#/dev154b28f09)
- Sample: [https://github.com/rokstrnisa/.../package.sh](https://github.com/rokstrnisa/slimbox/blob/d0a7491fe70e038f209420ba8fcb8660e9e657e3/package.sh)

#### Packing jar as AppImage

要將可以執行的單一 jar 檔封裝成 AppImage 格式。

1. 使用 jpackage，先將 jar 封裝成 `--type app-image`。
2. 使用 appimagetool，將上述的 image 目錄編譯為 AppImage 格式。

##### With jpackage)

```shell
mkdir {icons,input,output,temp}

tree -L 3 --dirsfirst --filelimit 10 --sort=name
.
├── icons
│   └── CloudCoin_Wallet-Dark.png
├── input
│   └── CloudCoin.D.3.0.15.jar
├── output
│   ├── CloudCoin_Wallet-Dark
│   │   ├── bin
│   │   └── lib
│   └── cloudcoin-wallet-dark_3.0.15-1_amd64.deb
├── temp
├── build.sh
└── license.txt

7 directories, 5 files
```

build.sh：

```shell
export PATH="$PATH:~/opt/jdk-14/bin"

[ -d temp ] && rm -rf temp/*
jpackage \
--type "app-image" \
--name CloudCoin_Wallet-Dark \
--description "CloudCoin Wallet - Dark Edition. For more information please visit https//cloudcoin.global." \
--vendor "CloudCoin Consortium" \
--app-version 3.0.15 \
--input input --dest output --temp temp \
--icon icons/CloudCoin_Wallet-Dark.png \
--copyright "CloudCoin™ Global Consortium © 2020 The Future of Currency" \
--main-jar CloudCoin.D.3.0.15.jar
```

開始封裝

<p class="callout info"> 封裝完成後會產生一個免安裝執行的程式目錄，儲存位置在 output 目錄下。</p>

```shell
bash build.sh
```

##### With appimagetool)

1\. 下載 appimagetool

Download: [https://appimage.github.io/appimagetool/](https://appimage.github.io/appimagetool/)

2\. 建立專案需要的目錄

```shell
mkdir CloudCoin_Wallet-Dark.AppDir
mkdir -p CloudCoin_Wallet-Dark.AppDir/usr/share/applications
mkdir -p CloudCoin_Wallet-Dark.AppDir/usr/share/icons/hicolor/256x256/apps
```

3\. 複製 jpackage 封裝後程式目錄內的內容至 usr/ 底下

4\. 複製 App 圖示檔（.png）

<p class="callout info">不同的 distributions 預設的 App Icon 路徑不大相同，如果發現有特定版本無法正常顯示 App 圖示，試試加上其他 icon 的路徑。</p>

- 圖檔路徑： 
    - `CloudCoin_Wallet-Dark.AppDir/usr/share/icons/hicolor/256x256/CloudCoin_Wallet-Dark.png`
    - `CloudCoin_Wallet-Dark.AppDir/usr/share/icons/hicolor/256x256/apps/CloudCoin_Wallet-Dark.png`
- 圖檔 size：256 x 256

5\. 建立 App 啟動捷徑（.desktop）

CloudCoin\_Wallet-Dark.desktop：

```
[Desktop Entry]
Name=CloudCoin Wallet(Dark-3.0.15)
Icon=CloudCoin_Wallet-Dark
Exec=CloudCoin_Wallet-Dark %F
Type=Application
Categories=Finance;
Comment=CloudCoin Wallet - Dark Edition
Terminal=false
StartupNotify=true
NoDisplay=false
Name[zh_TW]=CloudCoin Wallet(Dark-3.0.15)
```

- Icon - 圖示檔的檔名
- Exec - 程式執行檔的檔名
- 捷徑檔路徑 - `CloudCoin_Wallet-Dark.AppDir/usr/share/applications/CloudCoin_Wallet-Dark.desktop`

6\. 新增幾個連結檔

```shell
cd CloudCoin_Wallet-Dark.AppDir
ln -s usr/bin/CloudCoin_Wallet-Dark AppRun
ln -s usr/share/applications/CloudCoin_Wallet-Dark.desktop ./
ln -s usr/share/icons/hicolor/256x256/CloudCoin_Wallet-Dark.png ./
cd ../
```

完成後，目錄樹架構如下：

<p class="callout info">usr/bin 與 usr/lib 的內容是 jpackage 產生的。</p>

```shell
tree --dirsfirst --filelimit 10 --sort=name
.
├── CloudCoin_Wallet-Dark.AppDir
│   ├── usr
│   │   ├── bin
│   │   │   └── CloudCoin_Wallet-Dark
│   │   ├── lib
│   │   │   ├── app
│   │   │   │   ├── CloudCoin.D.3.0.15.jar
│   │   │   │   └── CloudCoin_Wallet-Dark.cfg
│   │   │   ├── runtime
│   │   │   │   ├── conf
│   │   │   │   │   ├── management
│   │   │   │   │   │   ├── jmxremote.access
│   │   │   │   │   │   ├── jmxremote.password.template
│   │   │   │   │   │   └── management.properties
│   │   │   │   │   ├── sdp
│   │   │   │   │   │   └── sdp.conf.template
│   │   │   │   │   ├── security
│   │   │   │   │   │   ├── policy
│   │   │   │   │   │   │   ├── limited
│   │   │   │   │   │   │   │   ├── default_local.policy
│   │   │   │   │   │   │   │   ├── default_US_export.policy
│   │   │   │   │   │   │   │   └── exempt_local.policy
│   │   │   │   │   │   │   ├── unlimited
│   │   │   │   │   │   │   │   ├── default_local.policy
│   │   │   │   │   │   │   │   └── default_US_export.policy
│   │   │   │   │   │   │   └── README.txt
│   │   │   │   │   │   ├── java.policy
│   │   │   │   │   │   └── java.security
│   │   │   │   │   ├── logging.properties
│   │   │   │   │   ├── net.properties
│   │   │   │   │   └── sound.properties
│   │   │   │   ├── legal [63 entries exceeds filelimit, not opening dir]
│   │   │   │   ├── lib [47 entries exceeds filelimit, not opening dir]
│   │   │   │   └── release
│   │   │   ├── CloudCoin_Wallet-Dark.png
│   │   │   └── libapplauncher.so
│   │   └── share
│   │       ├── applications
│   │       │   └── CloudCoin_Wallet-Dark.desktop
│   │       └── icons
│   │           └── hicolor
│   │               └── 256x256
│   │                   ├── apps
│   │                   │   └── CloudCoin_Wallet-Dark.png
│   │                   └── CloudCoin_Wallet-Dark.png
│   ├── AppRun -> usr/bin/CloudCoin_Wallet-Dark
│   ├── CloudCoin_Wallet-Dark.desktop -> usr/share/applications/CloudCoin_Wallet-Dark.desktop
│   └── CloudCoin_Wallet-Dark.png -> usr/share/icons/hicolor/256x256/CloudCoin_Wallet-Dark.png
├── appimagetool-x86_64.AppImage
├── CloudCoin_Wallet-Dark.3.0.22-x86_64.AppImage
```

7\. 開始編譯

```shell
chmod u+x appimagetool-x86_64.AppImage
./appimagetool-x86_64.AppImage CloudCoin_Wallet-Dark.AppDir CloudCoin_Wallet-Dark-x86_64.AppImage
```

# Build with Maven

##### Download Maven

[https://maven.apache.org/install.html](https://maven.apache.org/install.html)

```
wget https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz
tar xzf apache-maven-3.8.6-bin.tar.gz
cd apache-maven-3.8.6/bin
mvn -v
```

##### Install JDK (not JRE)

RedHat 8:

```bash
dnf install java-1.8.0-openjdk java-1.8.0-openjdk-devel
```

##### Get/Build the JAVA project

```bash
git clone https://github.com/kevinboone/amqutil.git
cd amqutil
<path-to-mvn> package
```