Skip to content
Platform > Plugins

Installing Plugins

A plugin is installed by copying its bundle into the plugins directory and restarting the server. This page covers where that directory is, which files the server accepts, and how to upgrade or remove a bundle safely.

For a first install from start to finish, see the Quickstart.

Where to put a bundle

Bundles go in the directory named by ami.plugins.dir, which ships as ./plugins:

# Comma-delimited list of directories, or bundle files, to scan for plugins at startup
ami.plugins.dir=./plugins
  • Relative paths resolve against the server's working directory. The Linux start script and the Windows launcher both run the server from the installation root, so ./plugins is the installation's plugins/ directory.
  • The directory may not exist yet. The Linux start script creates plugins/ at startup; the Windows launcher does not. The server never creates it, and a listed directory that does not exist is skipped without any log message.
  • Subdirectories are scanned too. A bundle anywhere below a listed directory is found.
  • An entry can be a single bundle file as well as a directory.

To scan more than one location, list them separated by commas, with no spaces:

ami.plugins.dir=./plugins,/opt/3forge/shared-plugins

Warning

Do not put a space after a comma in ami.plugins.dir. The space becomes part of the path, and the location after it is silently ignored.

If ami.plugins.dir is removed or left empty, the server loads no plugin bundles and logs MISSING ami.plugins.dir PROPERTY SO EXTERNAL PLUGINS WILL NOT BE LOADED.

Which files the server accepts

The server treats these files as bundles, matching the extension in any letter case:

  • .tar.gz
  • .zip
  • .jar

Any other file in the directory is ignored without a message, including a .tgz or .tar archive. Bundles from 3forge are delivered as .tar.gz files containing a lib/ directory of jars.

A .tar.gz or .zip bundle can contain several jars, and all of them load together. A .jar bundle cannot: a jar nested inside a .jar is not loaded.

Why a bundle must not be extracted

Copy the bundle file into plugins/ as it was delivered. The server reads the archive directly, and each bundle loads in isolation from the server and from other bundles, so that the libraries inside it cannot clash with anyone else's.

Extracting a bundle defeats that isolation. Each jar from the archive loads as a separate bundle, so the plugin can no longer see the libraries it depends on. The result looks like a successful install and then fails on first use:

  • The startup log shows a LOADING BUNDLE line for every jar instead of one for the archive.
  • The plugin still registers and is still enabled.
  • The plugin fails when it first runs, with a NoClassDefFoundError or ClassNotFoundException naming a class from one of its own libraries. For the Kafka feed handler: java.lang.NoClassDefFoundError: org/apache/kafka/common/errors/WakeupException.

To recover:

  1. Stop the server.
  2. Delete the extracted files from the plugins directory.
  3. Copy the original archive back into plugins/.
  4. Start the server.

Stop the server first. On Windows, a running server keeps its loaded jars open, so they cannot be deleted until it stops. If the archive is copied back while the extracted jars are still present, the next start fails because the plugin is found twice. See Upgrading a bundle.

Restarting after a change

Plugins are read only when the server starts. After adding, replacing, or removing a bundle, restart the server for the change to take effect. A bundle copied in while the server is running is not picked up until the next start.

Upgrading a bundle

To upgrade, replace the old bundle file with the new one, so only one copy remains in the plugins directory, then restart.

Two copies of the same plugin stop the server from starting, even when the files have different names. The server exits and names both files:

Error processing Plugin: amikafka_old.tar.gz
The same plugin class exists twice: RELAY_FEEDHANDLER>KAFKA (com.f1.ami.relay.fh.kafka.AmiKafkaFeedHandlerPlugin @ 31968.dev loaded from amikafka.tar.gz ==> ...) vs RELAY_FEEDHANDLER>KAFKA (com.f1.ami.relay.fh.kafka.AmiKafkaFeedHandlerPlugin @ 31968.dev loaded from amikafka_old.tar.gz ==> ...)

Delete one of the named files and start again. Keep any backup copy of an old bundle outside every directory listed in ami.plugins.dir.

Removing a bundle

To remove a plugin:

  1. Remove its plugin ID from any plugin list that names it explicitly, such as ami.relay.feedhandler.plugins=*,KAFKA. Lists that only use * need no change, and an exclusion such as !KAFKA left behind is harmless.
  2. Delete the bundle file from the plugins directory.
  3. Restart the server.

Step 1 comes first because a plugin list that names an ID which is no longer installed stops the server from starting:

Plugin not found: KAFKA  (available RELAY_FEEDHANDLER plugins: AMI_RTCLIENT,AMI_RTSERVER)

See Enabling and disabling plugins.

To stop a plugin being used without removing it, exclude it instead, as described in Enabling and disabling plugins.