io7m | single-page | multi-page | epub | Montarre User Manual 1.0.0-beta0001
6.4. com.io7m.montarre.msi
Previous
6. Packagers
Up
7. Package Format 1.0 Specification
Next

# 6.5. com.io7m.montarre.shell

- 6.5.1. Overview
- 6.5.2. Description
- 6.5.3. Batch File
- 6.5.4. Shell Script
- 6.5.5. Launch Jar
  - 6.5.5.1. Overview
  - 6.5.5.2. Get-Arch
  - 6.5.5.3. Get-OS
  - 6.5.5.4. Check-Java-Version
  - 6.5.5.5. Get-Module-Path
- 6.5.6. Outputs

## 6.5.1. Overview

1
The com.io7m.montarre.shell packager creates platform-independent shell distributions.

## 6.5.2. Description

1
The com.io7m.montarre.shell packager takes a montarre package and produces a platform-independent shell distribution. The term shell is used here to indicate that the distribution is really nothing more than simply running the system's java command on the jar files contained within the package using the system's shell.
2
A shell distribution is a tar file [1] containing the following files (where ${SHORT_NAME} is the short name of the application):

### 6.5.2.3. Files

File | Description
--- | ---
${SHORT_NAME}/META-INF/MONTARRE/PACKAGE.XML | The original package declaration taken from the input package.
${SHORT_NAME}/bin/launch.jar | The launch jar.
${SHORT_NAME}/bin/${SHORT_NAME} | The shell script for POSIX-like systems.
${SHORT_NAME}/bin/${SHORT_NAME}.bat | The batch file for Windows-like systems.
${SHORT_NAME}/lib/*.jar | The platform-neutral jar files for the application.
${SHORT_NAME}/lib/${ARCH}/${OS}/*.jar | The platform-specific jar files for the application, organized by architecture and operating system.
${SHORT_NAME}/meta/* | The metadata files taken from the input package.

4
Assuming that the current hardware architecture is ${ARCH}, the operating system is ${OS}, the application's main class is ${MAIN_CLASS}, and the short name of the application is ${SHORT_NAME}, then the application can be trivially executed with the following java invocation:

### 6.5.2.5. Example Invocation

    $ java -p "${SHORT_NAME}/lib:${SHORT_NAME}/lib/${ARCH}/${OS}" -m "${MAIN_CLASS}"

6
However, the simplicity of the above invocation hides a few important details:

### 6.5.2.7. Missing Details

- How does the caller assign a suitable value for ${ARCH}?
- How does the caller assign a suitable value for ${OS}?
- What happens on a system that uses ; as a module path separator instead of : ?
- What happens on a system that uses \ as a file path separator instead of / ?
- What happens if the package requires JDK 21, but the user is only running JDK 20 (or some other insufficient version)?

8
To solve the above problems, the packager provides a batch file (for Windows-like systems), and a shell script (for POSIX-like systems) that perform the above invocations in a platform-appropriate way, making calls into an included launch jar that knows how to fetch hardware architecture names in a system-independent manner, fetch operating system names in a system-independent manner, build module paths correctly, and check for the correct Java version.

## 6.5.3. Batch File

1
The shell distribution contains a Windows batch file that can be used to execute the application on Windows-like platforms. The batch file is generated based on the Java version requirement given in the input package, and the short name of the application. The short name is converted to uppercase and suffixed with the string _HOME to produce the name of an environment variable that will be consulted to find the location of the unpacked distribution. For example, in an application named montarre, the environment variable named MONTARRE_HOME will be consulted and is expected to contain the full path to the unpacked shell distribution. The application would therefore be executed as follows:

### 6.5.3.2. Example Batch

    c:> cd montarre

    c:\montarre> dir
     Volume in drive C has no label.
     Volume Serial Number is 187C-D7E2

     Directory of c:\montarre

    13/10/2024  18:34    <DIR>          .
    13/10/2024  18:34    <DIR>          ..
    13/10/2024  16:03    <DIR>          bin
    13/10/2024  16:03    <DIR>          lib
    13/10/2024  16:03    <DIR>          meta
    13/10/2024  15:34    <DIR>          META-INF
                   6 Dir(s)  485,913,133,056 bytes free

    c:\montarre> bin\montarre.bat
    MONTARRE_HOME is unset

    c:\montarre> set MONTARRE_HOME=c:\montarre

    c:\montarre> bin\montarre.bat
    montarre: usage: montarre [command] [arguments ...]

      The montarre command-line application.
    ...

3
As an example, the batch file generated for the montarre application looks like this:

### 6.5.3.4. Example Batch File

    @echo off

    REM Auto generated: Do not edit.
    REM This is a launch script for Windows-like platforms.

    if NOT DEFINED MONTARRE_HOME (
      echo MONTARRE_HOME is unset
      exit /b 1
    )

    REM Check that the available Java runtime is suitable.
    java -jar "%MONTARRE_HOME%/bin/launch.jar" check-java-version 21
    if %errorlevel% neq 0 exit /b 1

    REM Build a module path.
    for /f %%i in ('java -jar %MONTARRE_HOME%\bin\launch.jar get-module-path %MONTARRE_HOME%') do set MONTARRE_MODULE_PATH=%%i
    if %errorlevel% neq 0 exit /b 1

    REM Run the application.
    java -p %MONTARRE_MODULE_PATH% -m com.io7m.montarre.cmdline/com.io7m.montarre.cmdline.MMain %*
    if %errorlevel% neq 0 exit /b 1

## 6.5.4. Shell Script

1
The shell distribution contains a POSIX bourne shell script that can be used to execute the application on POSIX-like platforms. The shell script is generated based on the Java version requirement given in the input package, and the short name of the application. The short name is converted to uppercase and suffixed with the string _HOME to produce the name of an environment variable that will be consulted to find the location of the unpacked distribution. For example, in an application named montarre, the environment variable named MONTARRE_HOME will be consulted and is expected to contain the full path to the unpacked shell distribution. The application would therefore be executed as follows:

### 6.5.4.2. Example Batch

    $ cd montarre

    $ ls
    META-INF  bin  lib  meta

    $ ./bin/montarre
    MONTARRE_HOME is unset

    $ export MONTARRE_HOME=$(realpath .)

    $ ./bin/montarre
    montarre: usage: montarre [command] [arguments ...]

      The montarre command-line application.
    ...

3
As an example, the shell script generated for the montarre application looks like this:

### 6.5.4.4. Example Shell Script

    #!/bin/sh
    # Auto generated: Do not edit.
    # This is a launch script for UNIX-like platforms.

    if [ -z "${MONTARRE_HOME}" ]
    then
      echo "MONTARRE_HOME is unset" 1>&2
      exit 1
    fi

    #
    # Check that the available Java runtime is suitable.
    #

    /usr/bin/env java -jar "${MONTARRE_HOME}/bin/launch.jar" \
      check-java-version 21 || exit 1

    #
    # Build a module path. This is guaranteed to be:
    #   ${MONTARRE_HOME}/lib
    #   ${MONTARRE_HOME}/lib/${ARCH}/${OS}
    #

    MONTARRE_MODULE_PATH=$(/usr/bin/env java -jar "${MONTARRE_HOME}/bin/launch.jar" \
      get-module-path "${MONTARRE_HOME}") || exit 1

    #
    # Run the application.
    #

    exec /usr/bin/env java \
      -p "${MONTARRE_MODULE_PATH}" \
      -m com.io7m.montarre.cmdline/com.io7m.montarre.cmdline.MMain \
      "$@"

## 6.5.5. Launch Jar

## 6.5.5.1. Overview

1
The launch jar is a tiny jar file that exposes a command-line interface to perform some necessary startup tasks in a platform-independent manner.
2
The launch jar is compiled as JDK 9 bytecode and is not supported on systems running Java versions older than that.

## 6.5.5.2. Get-Arch

1
The Get-Arch command returns the name of the current hardware architecture.

### 6.5.5.2.2. Example

    $ java -jar bin/launch.jar Get-Arch
    x86_64

    C:> java -jar bin\launch.jar Get-Arch
    x86_64

## 6.5.5.3. Get-OS

1
The Get-OS command returns the name of the current operating system.

### 6.5.5.3.2. Example

    $ java -jar bin/launch.jar Get-OS
    linux

    C:> java -jar bin\launch.jar Get-OS
    windows

## 6.5.5.4. Check-Java-Version

1
The Check-Java-Version command checks to see if the current Java runtime version is greater than or equal to the provided major version argument. If the current Java runtime version is sufficient, the command says nothing.

### 6.5.5.4.2. Example

    $ java --version
    openjdk 21.0.4 2024-07-16
    OpenJDK Runtime Environment (build 21.0.4+7)
    OpenJDK 64-Bit Server VM (build 21.0.4+7, mixed mode, sharing)

    $ java -jar bin/launch.jar Check-Java-Version 21

    $ java -jar bin/launch.jar Check-Java-Version 11

    $ java -jar bin/launch.jar Check-Java-Version 22
    Exception in thread "main" java.lang.RuntimeException: At least Java 22 is required, but this Java runtime is version 21.0.4+7
    	at com.io7m.montarre.launchstub.MLSMain.doCheckJava(MLSMain.java:102)
    	at com.io7m.montarre.launchstub.MLSMain.main(MLSMain.java:70)

## 6.5.5.5. Get-Module-Path

1
The Get-Module-Path command constructs a module path given a base directory.

### 6.5.5.5.2. Example

    $ java -jar bin/launch.jar Get-Module-Path /example
    /example/lib:/example/lib/x86_64/linux

    C:> java -jar bin\launch.jar Get-Module-Path c:\example
    c:\example\lib;c:\example\lib\x86_64\windows

## 6.5.6. Outputs

1
Given a package name, version number, architecture name, and operating system name, the output of the packager will be ${PACKAGE_NAME}-${PACKAGE_VERSION}-${ARCH_NAME}-${OS_NAME}-any.txz unconditionally.
2
An example output of the packager is com.io7m.montarre-0.0.1-SNAPSHOT-any.txz.

## Footnotes

1 | The tar format is used because it is necessary to preserve the executable permissions on files in the archive when running in POSIX-like systems. The more common zip format does not contain a standard mechanism to preserve this information. References to this footnote: 1

6.4. com.io7m.montarre.msi
Previous
6. Packagers
Up
7. Package Format 1.0 Specification
Next
io7m | single-page | multi-page | epub | Montarre User Manual 1.0.0-beta0001