Is it possible to abstract away Sponge Plugin specific fields and methods

As a way to clean up my code and focus more on my intended algorithms vs all the overhead needed to set up a plugin, I tried placing all the @Inject modifiers in an abstract superclass. Since I also have a suite of plugins I’m developing, I decided to have each plugin’s main class implement a standardized interface, and extend this abstract ‘plugin’ class. However it seems like this causes sponge/Forge to freak out:

I also tried making two separate but identical abstract classes instead, having each plugin’s main class implement the following interface and the following abstract class:

Interface: and Abstract Class:

Basically my aim here is to make the main class more human readable. So my question is, can I do what I’m trying to do? or is there something specific to @Inject/Guava that makes this a fruitless endeavor?

From the error log it appears you have two plugins with the same ID ‘geoworld’. Are you sure you’ve changed the ID in the @Plugin annotation?

Here are the two plugins @Plugin annotations: for GeoWorld and for IgneousPack

Additionally the and gradle.settings files are:
For Igneous Pack,
For GeoWorld,

so, yes, they’re different.

I do this for KatLib and related plugins through a constructor annotated with @Inject, and then pass the objects on to the super class. Not sure if it’s exactly what you need, but it’s a thing.

Do be careful about extending classes for the main plugin though. If the abstract plugin class is in another jar from the implementation it might fail to load if the jar with the abstract plugin class hasn’t been loaded yet. This is AFAIK only a problem with SpongeForge, not SpongeVanilla.

could you show me an example of annotating the constructor with @Inject?

It’s scala, but sure. I’ll try to explain a bit about how stuff works.

Here is the plugin that uses this. In scala the constructor is defined on the same line as the class name. Any field that take more annotations (path for example), get that annotation added in the constructor. A nice thing with this approach as well is that I can say that those variables are final.

Here is the super class.

If I were to use the super class from java it would probably look something like this.

public class HomeSweetHome extends ImplKatPlugin {

	public HomeSweetHome(Logger logger, @ConfigDir(sharedRoot = false) Path configDir, PluginContainer container) {
		super(logger, configDir, configDir);


Finally gitted it all to gh.
Relevant packages :
“Master” Plugin

“Slave/Side” Plugin

Slave Plugin:

Main Plugin:

I still have that same ID conflict unfortunately : /