Reputation: 87
I'm making a Spigot minecraft plugin with an API to allow other developers to hook into it. How can I create the API in a separate JAR file that will function the same as if it was in the plugin itself?
I need this because the plugin will not be openly distributed, but I need to allow access to certain methods/classes/objects within.
Desired outcome: Plugin.jar is running on the server. I have Plugin-API.jar sitting in a Maven repository for other developers to hook into that will allow interaction with plugin.jar.
I'm fairly new to creating my own APIs in general, so fully explained responses would be greatly appreciated. Thanks!
Upvotes: 4
Views: 1531
Reputation: 3507
Review
Allow me to rehash your question. You have a plugin - Special - whose distribution is limited/restricted for one reason or another). Instead, you want to provide a publicly available API - SpecialApi - to allow other developers to incorporate and/or use features provided by Special.
This is a common approach used by various plugins (e.g. Vault, Citizens2, PermissionsEx, etc.), though for different reasons than yours. The structural relationship of which is represented in the following component diagram.
Given that you mentioned submodules in the comments, let me digress for a moment as to why they may not be a good solution. A common use of submodules is to create a segregation of code based on some criteria. For example, a web application may be split functionally into modules for its GUI, business logic, data persistence, etc; whereas a “big data” service may have multiple modules segregating libraries for various techniques. A good example of modules in terms of plugins is PermissionsEx, which is split to support different target environments. It has one module containing common code; another module wrapping its core as a Bukkit plugin; and third module wrapping its core as a Sponge plugin.
Answer
Since your primary purpose is code isolation via an API, the easiest and most direct approach is to create two separate Maven projects – one for your plugin and one for your API.
SpecialApi Project
APIs should not be taken lightly. This may make more sense if you think of an API as a contract between you and developers that guarantees certain functionality. In short, keep these points in mind:
Your API project will define classes, interfaces, and data structures required
to interface with your plugin. Do not make the mistake of making the API a
plugin itself. You can certainly use SpigotAPI classes and interfaces, even to
the point of defining a plugin class; however, it should never have to be
loaded by Spigot. It is just a JAR that will be referenced as a provided
dependency by others but also deployed as part of your actual plugin.
How you provide the API JAR is up to you. If you have some spare space on a public web server, you can manually create a small repository without having to consider using a service such as Nexus, Artifactory, etc.
Special Plugin Project
The plugin project contains everything else. You are free to add, change, correct, or remove internal components, provided it does not affect the API. It is a regular and normal plugin except that in addition to its resources, classes, and data normally provided, it also includes the same for your API; often referred to as a fat JAR. Otherwise, you would have to load your API separately as a plugin or as an additional entry on the server’s classpath. These last two options just beg for version and configuration management issues.
Instead, you use maven-assembly-plugin or similar tools
to deliver plugin and API code in the same JAR. For example, this assembly configuration will combine any project dependency with a scope of compile
into a single JAR.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
For anything more complex than this, you will want to look into maven-shade-plugin.
Upvotes: 5