APISupport - wysohn/GeneralLib GitHub Wiki

APISupport

Yet another abstract class that is responsible for interacting with other plugins.

Creating APISupport

Like other classes, you will have to create a new class extending APISupport abstract class.

public class VaultSupport extends APISupport {

    public VaultSupport(PluginBase base) {
        super(base);
    }

    @Override
    public void init() throws Exception {

    }
}

This is the empty APISupport, and you can add some more to this class.

Why Do We Use It Though?

Before start, I think you might wonder why are we even using this class when you can simply support other plugins using Bukkit's PluginManager or etc. The answer is that the plugin you support might not exist when your plugin loads. In that case, if you have any class that is loaded and import the unloaded class, it will spit out the NoClassDefFoundError. This is something different than ClassNotFoundException; NoClassDefFoundError occurs when the class will be loaded, not when Class.forName() is invoked. Because of that reason, the usual try catch approach for usual exception doesn't work.

The only solution is this: you first consult Bukkit's PluginManager and see if the plugin is loaded -> then if plugin is loaded, create new instance. But if not loaded, don't create the new instance.

What I found is that putting the constructor call in the if/else statement still cause the NoClassDefFoundError because the Error happens in byte code analysis, I assume, so what I came up with is that let all the other plugins' imports in just one class, and instanciate it using reflection only when it is available to do so.

But if you have no idea what I'm talking about here, just follow the instruction. It makes your life much easier.

Example

I decided that it might be easier to just show how actual class will be look like. You will first want to look at the structure of the VaultSupport

So the idea is this: you never put anything from other plugin into your actual plugin. All of them should be handled in this VaultSupport class. Do not ever import those other plugin's class in your plugin. That will only work when the plugin you are trying to support is actually present. But if you place everything inside the 'support class', it will be only instanciated when the plugin is actually loaded.

Register The Class

! Like the ordinary plugin creation, you have to specify the plugin to support in the softdepend section of plugin.yml

main: ...
softdepend: ["Vault"]

Like PluginManager, you first have to register your newly created class. To do so, in PluginBase, there is a field called APISupport. Use hookAPI() method to register it.

base.APISupport.hookAPI("Vault", VaultSupport.class);

args0 -- obviously the name of the plugin to support. This should match exactly with the name of the plugin to support.

args1 -- the support class you just made.

How to use it

Just like PluginManager, the PluginBase has a field called APISupport. All you need to do is call this method and get your API, just like you did with PluginBase through getManager() method.

VaultSupport vsupport = base.APISupport.getAPI("Vault");   

However, if the plugin with given name is not loaded, it will return null instead. If you prefer boolean instead of null checking, use isHook() method.

if(base.APISupport.isHook("Vault"))
    ...