Skip to content

A support library for loading and writing TurnKey bundles.

Notifications You must be signed in to change notification settings

tudo-aqua/turnkey-support

Repository files navigation

GitHub Workflow Status JavaDoc Maven Central

TurnKey Support Library

This is a support library for loading and writing TurnKey bundles. A TurnKey bundle is a Java library that depends on a native library which is included in the JAR archive and unpacked at runtime. This requires distributing the library and its dependencies for all supported platforms inside the JAR.

However, loading libraries in the JVM is only possible if these libraries are present in the file system. Therefore, all required libraries are unpacked to a temporary directory by the support library. Additionally, loading of dependencies can not be done in a fully platform-agnostic way: for some platforms, libraries can be (re-) linked to search for their dependencies in the same directory, while for others, the dependencies must be explicitly loaded by the JVM beforehand. A TurnKey bundle therefore includes a metadata file that a) lists all required libraries and b) lists the required library load commands for the target platform in order.

A TurnKey bundle is identified by a prefix, which should correspond to the package name used by the library's Java code (e.g., a JNI binding) to avoid namespace conflicts.

Loading TurnKey Bundles

The support library is published as a Maven artifact on Maven Central and can be included in every Maven-supporting build tool.

The library defines a single entry point for loading bundles, TurnKey.load. This method accepts the bundle prefix and a function that can be used to load libraries, usually the loading class' getResourceAsStream method. The latter is necessary to handle Java modularity, sind the libraries can only be accessed from code in the same module, not the support library.

A sensible place for calling this method is the static initializer of, e.g., a JNI wrapper class:

package com.acme.example;

import tools.aqua.turnkey.support.TurnKey;

class Example {
    static {
        TurnKey.load("com/acme/example", Example.class::getResourceAsStream);
    }
}

Authoring TurnKey Bundles

A TurnKey bundle can be constructed by placing all required files in a specific structure and adding a metadata file. Supported platforms are defined by operating system and CPU architecture. The JAR file should then contain all required files at $prefix/$os/$arch.

For each supported platform, the file turnkey.xml must be present. It can be authored via the TurnKeyMetadata class.

Metadata File

The turnkey.xml file defines all metadata for the required support files. It is a Java Properties XML file that stores collections of items as follows: for the list key k, the contents of k are stored as k.0, k.1, etc. Each metadata file contains:

  • the set bundled-libraries, containing all files that must be unpacked from the support file directory for the native code to work,
  • the set system-libraries, containing all system libraries that are not bundled but must be present for the library to work (at the moment, this information is not used by the support library), and
  • the list load-command, listing the required libraries in load order. If the platform support linking to libraries in the same directory, this will usually only contain a “root” library, if not, it will contain the dependency graph in inverse topological order.

Layout Example

For the library libexample.so by ACME, Inc., a TurnKey bundle might contain:

com/acme/example/Example.class            # JNI binding
com/acme/example/windows/x86/turnkey.xml  # Windows x86 metadata
com/acme/example/windows/x86/example.dll  # Windows x86 library file
com/acme/example/linux/amd64/turnkey.xml  # Linux AMD64 metadata
com/acme/example/linux/amd64/example.so   # Linux AMD64 library file

Java, JPMS Support, and Nullability

The library requires Java 8. It can be used as a Java module on Java 9+ via the multi-release JAR mechanism as the tools.aqua.turnkey.support module. It uses JSpecify annotations to declare nullability metadata.

License

The support library's runtime code is released under the ISC License. Tests and other non-runtime code are licensed under the Apache Licence, Version 2.0. Standalone documentation is licensed under the Creative Commons Attribution 4.0 International License. The library uses JSpecify annotations, which are licensed under the Apache Licence, Version 2.0.

See Also

The turnkey-gradle-plugin provides facilities for rewriting non-TurnKey library files as well as modifying Java source code (to insert calls to this library) via Gradle.

At the moment, two libraries are using this infrastructure: Z3-TurnKey and cvc5-TurnKey.

About

A support library for loading and writing TurnKey bundles.

Resources

Stars

Watchers

Forks

Languages