Using External Java/Python Libraries¶
PySpigot allows you to use external Python and Java libraries when writing scripts. There are many open-source Python and Java libraries that simplify or otherwise hasten code writing. The Apache Commons Libraries, a collection of Java utility libraries that provide an abundance of useful utility functions, are one such example.
Of course, a more advanced usage of this functionality might include writing your own external libraries for frequently used or complicated code. See the Handy Usage of External Python Modules section below for more information on this.
General Information¶
PySpigot will create two folders (if they don't already exist) called python-libs
and java-libs
when it loads, where external libraries should be placed.
PySpigot automatically places a helper module called pyspigot.py
into the python-libs
folder on plugin load. For more information on this helper library, see the Writing Scripts page.
External Python Libraries¶
PySpigot currently supports the usage of a single-module file for use as an external library. Currently, fully-fledged libraries/packages (I.E. those with an __init__.py
) are not supported, but support for these is planned in a future release. Thus, from this point onwards, "external Python library" will be referred to as module.
Loading and Using an External Python Module¶
Using an external Python module is relatively simple and does not require usage of one of PySpigot's managers or any commands, unlike Java libaries. The external Python module you plan to use should be a single .py
file. To use it, drag and drop it into the python-libs
folder within PySpigot's main plugin folder. Then, simply import
the module into your script, and you're good to go.
Tip
Adding new modules or deleting old modules does not require a server restart or plugin reload. However, if the code of a module is changed, all scripts that use said module should be reloaded.
Handy Usage of External Python Modules¶
Suppose there is a certain piece of code that you use frequently, across multiple scripts. This code could be something like converting a player's location to a config-friendly dict
, formatting an str
, or sending a player a message in a neat format. Instead of writing the same code multiple times across different scripts, you might consider breaking this code out into its own external Python module, then add it to the python-libs
folder, so that you can access it from all your scripts.
External Java Libraries¶
Under normal circumstances, a Java library would be "shaded" into a Bukkit/Spigot plugin (with the end result sometimes called a "fat" Jar or "Uber" Jar) so that the plugin has access to the dependency at runtime. We obviously can't do this with scripts.
Instead, we can take advantage of Jython's capabilities. As stated before elsewhere in the documentation, Jython provides access to all loaded Java classes at runtime. Therefore, a collection of Java classes (the library) can be manually loaded into the classpath at runtime, which in turn gives scripts access to those classes. PySpigot's LibraryManager provides this functionality.
When a JAR library is loaded, PySpigot creates a copy of the library that ends with "-relocated". For example, the library jython-annotation-tools-0.9.0.jar
is copied to jython-annotation-tools-0.9.0-relocated.jar
. This is done not only to accommodate relocation rules (see the section on relocation rules below), but also to speed up loading of external libraries in future plugin loads. This behavior occurs even if you don't specify any relocation rules for the library.
Loading and Using Java Libraries¶
Warning
It's possible that another plugin on the server is already using the library/dependency that you'd like to use. You should check if this is the case before you attempt to load the library yourself. You can do this by trying to import
the dependency into your script. If you're able to import it, stop here! You won't need to load it yourself, as it is already loaded (likely by another plugin).
All Java libraries/dependencies should have a Jar file available for download somewhere, perhaps on its Github repository or on its official website. You may need to download it manually from the repository where the dependency is hosted. If you can't find the Jar file, reach out on PySpigot's Discord for help.
Once you have the physical Jar file for the dependency you'd like to use, drag and drop it into the java-libs
folder of the main PySpigot plugin folder. The dependency will be loaded when the PySpigot plugin is loaded and enabled (on server startup). From here, you can use import
statements in your script to import the desired code from the library.
Tip
All Jar files present in the java-libs
folder are loaded on plugin load (when the server starts). Loading new Jar files while PySpigot is already running requires usage of a command (see below), or a complete reload of the plugin (/ps reloadall
).
Loading a Java library when PySpigot is already running¶
Like before, obtain the Jar file for the library you would like to use. Then, drag and drop it into the java-libs
folder of the main PySpigot plugin folder.
Next, you'll need to load the library manually with the command /ps loadlibrary <filename>
, where <filename>
is the name of the Jar file you are loading. Be sure to include the .jar
extension in the file name. This will import the library.
The library should now be loaded, and you can use import
statements to import the desired code.
Notice
PySpigot does not have a way to unload previously loaded libraries due to limitations within Java's class loading system. Nevertheless, a library will not be loaded more than once; if it already loaded, PySpigot will not load it again.
Jar Relocation Rules¶
You may need to change the name/classpath of classes within a library/dependency. This is called "relocation". There are many reasons why you might want to do this, but that is beyond the scope of this documentation. If you need to relocate a classpath of your library/dependency, you'll likely know that you need to do so already. In that case, read on for information on how to specify relocation rules.
Within PySpigot's config.yml
, you'll find a library-relocations
value. You may specify your own relocations rules here. Relocation rules should be in the format <path>|<relocated-path>
. For example, to relocate com.apache.commons.lang3.stringutils
to lib.com.apache.commons.lang3.stringutils
:
An abbreviated list form is also permitted in YAML syntax:
To add multiple relocation rules in the abbreviated list form, separate each with a comma.
Tip
As stated previously, PySpigot creates a copy that ends with "-relocated" of every external JAR library. This file represents the relocated JAR, with all relocation rules applied to it. This copy is only created once, or, put differently, relocation rules are only applied once. In subsequent plugin loads, the relocated JAR library is loaded.
Therefore, if changes are made to the relocation rules, it is necessary to delete the "-relocated.jar" copy of the relevant library/libraries so that the updated relocation rules are applied.