Skip to content

Libraries

Paper and Nukkit do not support specifying libraries directly in the plugin description file. plugin-yml still allows defining dependencies as paperLibrary and nukkitLibrary but these dependencies are not exported by default. Additional runtime plugin code is needed to set them up and load them. To simplify this, plugin-yml can export them in a paper-libraries.json / nukkit-libraries.json file with the following structure:

{
    "repositories": {"MavenRepo": "https://repo.maven.apache.org/maven2/"},
    "dependencies": ["com.google.code.gson:gson:2.10.1"]
}

This file is only generated after setting generateLibrariesJson to true, e.g.:

paper {
    // generate paper-libraries.json
    generateLibrariesJson = true
}

The JSON file is included in the plugin JAR and can be parsed at runtime to load the additional libraries.

Paper

Define a custom PluginLoader inside your plugin code, for example:

Example PluginLoader
paper {
    loader = "com.example.testplugin.PluginLibrariesLoader"
    generateLibrariesJson = true
}
import com.google.gson.Gson;
import io.papermc.paper.plugin.loader.PluginClasspathBuilder;
import io.papermc.paper.plugin.loader.PluginLoader;
import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.repository.RemoteRepository;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

public class PluginLibrariesLoader implements PluginLoader {
    @Override
    public void classloader(@NotNull PluginClasspathBuilder classpathBuilder) {
        MavenLibraryResolver resolver = new MavenLibraryResolver();
        PluginLibraries pluginLibraries = load();
        pluginLibraries.asDependencies().forEach(resolver::addDependency);
        pluginLibraries.asRepositories().forEach(resolver::addRepository);
        classpathBuilder.addLibrary(resolver);
    }

    public PluginLibraries load() {
        try (var in = getClass().getResourceAsStream("/paper-libraries.json")) {
            return new Gson().fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), PluginLibraries.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private record PluginLibraries(Map<String, String> repositories, List<String> dependencies) {
        public Stream<Dependency> asDependencies() {
            return dependencies.stream()
                    .map(d -> new Dependency(new DefaultArtifact(d), null));
        }

        public Stream<RemoteRepository> asRepositories() {
            return repositories.entrySet().stream()
                    .map(e -> new RemoteRepository.Builder(e.getKey(), "default", e.getValue()).build());
        }
    }
}

Nukkit

(No example code available yet)

Bukkit/Bungee

generateLibrariesJson is also supported on Bukkit/Bungee (to generate bukkit-libraries.json/bungee-libraries.json). However, since these two allow specifying libraries directly inside the plugin.yml the option is generally not needed there.