Interface InternalResource


public interface InternalResource
Represents an internal resource of a language that can be lazily unpacked to a cache user directory.

A typical implementation of an InternalResource for a platform-specific library stored in the META-INF/resources/<language-id>/<resource-id>/<os>/<arch> looks like this:

 @InternalResource.Id("resource-id")
 final class NativeLibResource implements InternalResource {

     @Override
     public void unpackFiles(Env env, Path targetDirectory) throws IOException {
         Path base = Path.of("META-INF", "resources", "mylanguage", "resource-id",
                         env.getOS().toString(), env.getCPUArchitecture().toString());
         env.unpackResourceFiles(base.resolve("file-list"), targetDirectory, base);
     }

     @Override
     public String versionHash(Env env) {
         try {
             Path hashResource = Path.of("META-INF", "resources", "mylanguage", "resource-id",
                             env.getOS().toString(), env.getCPUArchitecture().toString(), "sha256");
             return env.readResourceLines(hashResource).get(0);
         } catch (IOException ioe) {
             throw CompilerDirectives.shouldNotReachHere(ioe);
         }
     }
 }
 
The resource files are listed in the META-INF/resources/<language-id>/<resource-id>/<os>/<arch>/file-list file. For the file list format, refer to unpackFiles(Env, Path). Additionally, the META-INF/resources/<language-id>/<resource-id>/<os>/<arch>/sha256 file contains an SHA-256 hash of the resource files. It is recommended to use non-encapsulated resource paths that include the component ID and resource ID, as this helps prevent ambiguity when the language or instrument is used in an unnamed module.
Since:
23.1
  • Method Details

    • unpackFiles

      void unpackFiles(InternalResource.Env env, Path targetDirectory) throws IOException
      Unpacks all resources to a given target directory. The target directory is guaranteed to be writable and the unpacking is synchronized by a file system lock. If a resource was previously cached then versionHash(Env) is invoked and the version string is compared. If it matches then unpackFiles(Env, Path) will not be invoked and the directory will be used as previously unpacked. The target directory is guaranteed to exist and guaranteed to be empty.

      Ideally the result of this method should be idempotent in order to be safely cacheable. Care should be taken, if system properties are used that change the result of this method. It is safe to use InternalResource.OS and InternalResource.CPUArchitecture enums as internal resources are never cached or moved across operating system architectures.

      No guest language code must run as part of this method.

      Parameters:
      targetDirectory - the target directory to extract files to
      Throws:
      IOException
      Since:
      23.1
    • versionHash

      String versionHash(InternalResource.Env env) throws IOException
      Returns the version hash to be used for this resource. It is the responsibility of the implementer to ensure that this version hash is unique. For example, an SHA-256 could be a good version identifier for file based resources. Since the version hash serves as a path component on the host filesystem, its length is restricted to a maximum of 128 bytes. If the version hash length exceeds this limit, an IOException will be thrown during unpacking.
      Throws:
      IOException
      Since:
      23.1