Skip to content
Henri Schubin edited this page Jul 5, 2024 · 10 revisions

How to apply for Bukkit

Maven Central Sonatype Nexus (Snapshots)

Due to Bukkit not exposing a way to load dependencies in during runtime, we need to have our own ClassLoader load them in, for that we'll need that ClassLoader to load in our plugin's code (that's going to use those dependencies) as well.

This guide is for Gradle, that is also the only way to use the DependencyDownload metadata generation plugin

Loader

bukkit/loader/build.gradle

 plugins {
     id 'java'
     id 'com.github.johnrengerlman.shadow' version '7.0.0'
 }

 repositories {
     mavenCentral()
     maven {
         url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/'
     }
 }

 dependencies {
     compileOnly 'org.bukkit:bukkit:1.16.5-R0.1-SNAPSHOT'
+    implementation 'dev.vankka:minecraftdependencydownload-bukkit-loader:VERSION'
 }

 jar {
     finalizedBy shadowJar
 }

 shadowJar {
+    from {
+        findProject(':bukkit').tasks.shadowJar.archiveFile
+    }
 }

If the main part of the plugin is the root project, you can use rootProject instead of findProject(':bukkit')

bukkit/loader/src/main/java/com/example/bukkit/loader/BukkitLoader.java

 package com.example.bukkit.loader;

...

-public class BukkitLoader extends JavaPlugin {
+public class BukkitLoader extends dev.vankka.mcruntimedependencydownload.bukkit.loader.BukkitLoader {
    
+    @Override
+    public String getBootstrapClassName() {
+        return "com.example.bukkit.bootstrap.BukkitBootstrap";
+    }

+    @Override
+    public URL getJarInJarResource() {
+        return getClassLoader().getResource("bukkit.jarinjar");
+    }

-    @Override
-    public void onEnable() {
-        // plugin enable logic
-    }
}

bukkit/loader/src/main/resources/plugin.yml

 name: ExamplePlugin
 version: 1.0
+main: com.example.bukkit.loader.BukkitLoader

Bootstrap

bukkit/build.gradle

 plugins {
     id 'java'
     id 'com.github.johnrengerlman.shadow' version '7.0.0'
+    id 'dev.vankka.dependencydownload.plugin' version 'VERSION'
 }

 repositories {
     mavenCentral()
     maven {
         url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/'
     }
 }

 dependencies {
     compileOnly 'org.bukkit:bukkit:1.16.5-R0.1-SNAPSHOT'
+    implementation 'dev.vankka:minecraftdependencydownload-bukkit:VERSION'
 }

 jar {
+    dependsOn generateRuntimeDownloadResourceForRuntimeDownload
     finalizedBy shadowJar
 }

 shadowJar {
+    archiveFileName = 'bukkit.jarinjar'
 }

bukkit/src/main/java/com/example/bukkit/bootstrap/BukkitBootstrap.java

package com.example.bukkit.bootstrap;

...

public class BukkitBootstrap extends dev.vankka.mcruntimedependencydownload.bukkit.bootstrap.BukkitBootstrap {

    // Do not change the parameters on this constructor
    public BukkitBootstrap(JarInJarClassLoader classLoader, JavaPlugin plugin) {
        super(classLoader, plugin);
    }

    @Override
    public void onLoad() {
        // Download dependencies from the file generated by the gradle plugin
        try {
            Executor executor = Executors.newCachedThreadPool();

            DependencyManager manager = new DependencyManager(new File(getPlugin().getDataFolder(), "cache").toPath());
            dependencyManager.loadFromResource(getClassLoader().getResource("runtimeDownload.txt"));
            dependencyManager.downloadAll(executor, Collections.singletonList(new StandardRepository("https://repo.example.com/maven2"))).join();
            dependencyManager.relocateAll(executor).join();
            dependencyManager.loadAll(executor, getClasspathAppender()).join();
        } catch (Throwable t) {
            getPlugin().getLogger().severe("Failed to load dependencies");
            e.printStackTrace();
            getPlugin().getServer().getPluginManager().disablePlugin(getPlugin());
        }
    }

    @Override
    public void onEnable() {
        // plugin enable logic
    }
}