Skip to content

v5 Migration Guide

Jake-Moore edited this page Sep 2, 2025 · 7 revisions

Welcome to KamiCommon v5 🚀

This guide will help you migrate your project from v4 to v5. Please review the changes below to ensure a smooth transition.

Note: This is not a new API guide. If you are looking for New APIs, please refer to the v5 New APIs. Note: This is not a summary of v5 changes. If you are looking for a summary of changes, please refer to the v5 Changes Summary. Note: If you have migrated to a v5 pre-release version, and need update instructions within v5, check the sidebar for version-specific guides.

Relocated Classes (Names Preserved)

These classes were moved to a different package, but kept their original names:

  • com.kamikazejam.kamicommon.configuration.spigot.ConfigObservercom.kamikazejam.kamicommon.configuration.spigot.observe.ConfigObserver
  • com.kamikazejam.kamicommon.modules.Modulecom.kamikazejam.kamicommon.subsystem.module.Module
  • com.kamikazejam.kamicommon.modules.ModuleConfigcom.kamikazejam.kamicommon.subsystem.module.ModuleConfig
  • com.kamikazejam.kamicommon.modules.ModuleManagercom.kamikazejam.kamicommon.subsystem.module.ModuleManager
  • com.kamikazejam.kamicommon.modules.commands.CmdModulescom.kamikazejam.kamicommon.subsystem.module.commands.CmdModules
  • com.kamikazejam.kamicommon.modules.commands.UnmatchedCommandcom.kamikazejam.kamicommon.subsystem.module.commands.UnmatchedCommand
  • com.kamikazejam.kamicommon.modules.integration.CitizensIntegrationcom.kamikazejam.kamicommon.subsystem.integration.CitizensIntegration
  • com.kamikazejam.kamicommon.modules.integration.ItemsAdderIntegrationcom.kamikazejam.kamicommon.subsystem.integration.ItemsAdderIntegration
  • com.kamikazejam.kamicommon.modules.integration.MythicMobsIntegrationcom.kamikazejam.kamicommon.subsystem.integration.MythicMobsIntegration

Renamed Classes

These classes were renamed, and possibly relocated as well:

  • PositionSlotPositionIconSlot (in com.kamikazejam.kamicommon.menu.api.icons.slots)
    • Renamed for consistency with other slot class names
  • com.kamikazejam.kamicommon.modules.integration.ModuleIntegrationcom.kamikazejam.kamicommon.subsystem.integration.SubsystemIntegration

Internal Dependencies Changes

  • REMOVED: Jackson (jackson-databind and jackson-annotations)
    • Jackson is no longer used internally, or shaded for use in KamiCommon
    • If you were using Jackson directly, you will need to add your own dependency
  • REMOVED: Citizens Plugin API
    • The Citizens integration has been removed, and this API no longer relies on or uses any Citizens classes.
    • This includes the removal of the Citizens soft plugin dependency
  • REMOVED: ItemsAdder Plugin API
    • The ItemsAdder integration has been removed, and this API no longer relies on or uses any ItemsAdder classes.
    • This includes the removal of the ItemsAdder soft plugin dependency
  • REMOVED: MythicMobs Plugin API
    • The MythicMobs integration has been removed, and this API no longer relies on or uses any MythicMobs classes.
    • This includes the removal of the MythicMobs soft plugin dependency

Removed APIs

  • REMOVED Class: com.kamikazejam.kamicommon.util.JacksonUtil (from shared-jar)
    • Jackson no longer shaded internally
  • REMOVED Class: com.kamikazejam.kamicommon.command.Lang
    • See v5 New APIs for the configuration system replacing this
  • REMOVED Class: com.kamikazejam.kamicommon.command.type.CompletableType
    • This was a poor attempt in v4 to support async code in the types system for commands. Bukkit Commands are sync and therefore don't truly support async code. You will need to develop your own solutions or workarounds if you require async logic within a Type
  • REMOVED Static Constants from com.kamikazejam.kamicommon.command.type.TypeAbstract<T>
    • NULL, EMPTY, UNKNOWN, COLOR_DEFAULT, and TAB_LIST_UUID_THRESHOLD
    • All variables were unused, but they were static, so this could be a breaking change for some
  • REMOVED Static Constants from com.kamikazejam.kamicommon.command.type.TypeAbstractChoice<T>
    • MESSAGE_MATCH_NOTHING, MESSAGE_MATCH_AMBIGUOUS, MESSAGE_AVAILABLE_EMPTY, MESSAGE_COLON_AMBIGUOUS, MESSAGE_COLON_ALL, MESSAGE_COLON_SIMILAR, MESSAGE_SUGGESTIONS_EMPTY, MESSAGE_SUGGESTIONS_MUCH
    • All variables were refactored to follow the new configuration format (See New APIs)
    • Review TypeAbstractChoice.Config for static getters and setters that replace these
  • REMOVED: Method KamiCommand#applyPuzzler
  • REMOVED: Sub Class com.kamikazejam.kamicommon.menu.api.struct.MenuEvents.MenuEventsModification
  • REMOVED: Sub Class com.kamikazejam.kamicommon.menu.api.struct.MenuOptions.MenuOptionsModification
  • REMOVED: Sub Class com.kamikazejam.kamicommon.menu.api.struct.oneclick.OneClickMenuOptions.OneClickMenuOptionsModification
  • REMOVED: Sub Class com.kamikazejam.kamicommon.menu.api.struct.paginated.PaginatedMenuOptions.PaginatedMenuOptionsModification
  • REMOVED Class: com.kamikazejam.kamicommon.nms.util.data.MaterialData (from spigot-nms)
    • Removal from prior deprecation, Migrate to XMaterialData instead.
  • REMOVED Class: com.kamikazejam.kamicommon.nms.abstraction.event.EventManager (from spigot-nms)
    • Modules spigot-utils and spigot-jar are both affected, this API has been removed.
  • REMOVED Class: com.kamikazejam.kamicommon.nms.provider.EventManagerProvider (from spigot-nms)
    • Modules spigot-utils and spigot-jar are both affected, this API has been removed.
  • REMOVED: Method NmsAPI#getEventManager
    • The EventManager nms feature has been removed, so this method is no longer available
  • REMOVED: Method NmsAPI#getEventManagerProvider
    • The EventManager nms feature has been removed, so this method is no longer available
  • REMOVED: Class com.kamikazejam.kamicommon.item.IAItemBuilder (from spigot-utils)
    • The ItemsAdder integration is no longer available
    • See the Javadoc class comment on ItemBuilder for recommendations on integrating with ItemsAdder
  • REMOVED: Method ConfigurationSection#setItemBuilder(String key, IBuilder builder)
    • This method was always an alias for setItemStack(String key, ItemStack item) and has been removed for clarity
    • Use setItemStack(String key, ItemStack item) instead after building your ItemStack with ItemBuilder
  • REMOVED: Method ConfigurationSection#getItemBuilder(String key, IBuilder builder)
    • This method was always an alias that wrapped getItemStack(String key) into an ItemBuilder and has been removed for clarity
    • Use new ItemBuilder(ItemStack) instead with the ItemStack returned from getItemStack(String key)

Removals (from prior deprecations)

In v4 the following classes and methods were deprecated, and have now been removed in v5:

  • ModuleManager.get(Class<T> moduleClass) (use your own singleton management on modules instead)
  • KamiPlugin.getModule(Class<M> moduleClass) (use your own singleton management on modules instead)

⚠️ BREAKING Redis Changes

  • RedisChannelCallback<T> changed to RedisChannelCallback
    • onMessage(String channel, T message) changed to onMessage(String channel, String message)
  • RedisAPI
    • REFACTORED: registerChannel(Class<T> clazz, String channel)registerChannel(String channel)
    • REFACTORED: registerMultiChannel(Class<T> clazz, String... channels)registerMultiChannel(String... channels)
    • REMOVED: registerChannelRaw(String channel)
      • USE: registerChannel(String channel)
  • RedisChannel<T> changed to RedisChannel
    • REMOVED: Class<T> argument from constructor
    • UPDATED: #subscribe to use RedisChannelCallback (no generics)
    • REFACTORED: publishSync(T message)publishSync(String message)
    • REFACTORED: publishAsync(T message)publishAsync(String message)
    • REFACTORED: publish(T message, boolean sync)publish(String message, boolean sync)
    • REMOVED: publishRawSync(String message)
      • USE: publishSync(String message)
    • REMOVED: publishRawAsync(String message)
      • USE: publishAsync(String message)
    • REMOVED: publishRaw(String message, boolean sync)
      • USE: publish(String message, boolean sync)
  • REMOVED: RedisChannelRaw
    • USE: RedisChannel now
  • RedisManager
    • REFACTORED: subscribe(RedisChannelCallback<T> callback, Class<T> clazz, String... channels)subscribe(RedisChannelCallback callback, String... channels)
    • REMOVED: #subscribeRaw
      • USE: #subscribe now
    • REFACTORED: publish(String channel, T message, boolean sync)publish(String channel, String message, boolean sync)
    • REMOVED: #publishRaw
      • USE: #publish now
  • RedisMultiChannel<T> changed to RedisMultiChannel
    • REMOVED: Class<T> argument from constructor
    • UPDATED: #subscribe to use RedisChannelCallback (no generics)
    • REFACTORED: publishSync(String channel, T message)publishSync(String channel, String message)
    • REFACTORED: publishAsync(String channel, T message)publishAsync(String channel, String message)
    • REFACTORED: publish(String channel, T message, boolean sync)publish(String channel, String message, boolean sync)
    • REMOVED: publishRawSync(String channel, String message)
      • USE: publishSync(String channel, String message)
    • REMOVED: publishRawAsync(String channel, String message)
      • USE: publishAsync(String channel, String message)
    • REMOVED: publishRaw(String channel, String message, boolean sync)
      • USE: publish(String channel, String message, boolean sync)

⚠️ BREAKING KamiConfig Changes

Changes include updated constructors and better control over how and when KamiConfig applies defaults from your defaultsStream (i.e. jar resource).

Constructor Changes for KamiConfig (mirrored in KamiConfigExt)

  • REFACTORED: KamiConfig(JavaPlugin, File, boolean addDefaults)KamiConfig(JavaPlugin, File, @Nullable Supplier<InputStream> defaultsStream)
    • v4 code calling new KamiConfig(plugin, file, false) should be updated to new KamiConfig(plugin, file, null)
    • v4 code using new KamiConfig(plugin, file, true) should be simplified to new KamiConfig(plugin, file)
  • REMOVED: KamiConfig(JavaPlugin, File, boolean addDefaults, boolean strictKeys)
    • The temporary strict keys feature was removed. Treat the migration as if you were using the constructor without strict keys
  • REMOVED: KamiConfig(JavaPlugin, File, boolean addDefaults, Supplier<InputStream>)
    • If you were using addDefaults=false, migrate to new KamiConfig(plugin, file, null)
    • If you were using addDefaults=true, migrate to new KamiConfig(plugin, file, yourSupplier)

Constructor Changes for StandaloneConfig (mirrored in StandaloneConfigExt)

  • REFACTORED: StandaloneConfig(File)StandaloneConfig(LoggerService, File)
    • A logger is required for logging errors and warnings. Create your own LoggerService if you do not have one
  • REFACTORED: StandaloneConfig(File, boolean addDefaults)StandaloneConfig(LoggerService, File, @Nullable Supplier<InputStream> defaultsStream)
    • v4 code calling new StandaloneConfig(file, false) should be updated to new StandaloneConfig(yourLogger, file, null)
    • v4 code using new StandaloneConfig(file, true) should be updated to new StandaloneConfig(yourLogger, file, yourSupplier)
  • REFACTORED: StandaloneConfig(File, Supplier<InputStream>)StandaloneConfig(LoggerService, File, @Nullable Supplier<InputStream> defaultsStream)
    • v4 code using new StandaloneConfig(file, yourSupplier) should be updated to new StandaloneConfig(yourLogger, file, yourSupplier)
  • REFACTORED: StandaloneConfig(File, boolean addDefaults, Supplier<InputStream>)StandaloneConfig(LoggerService, File, @Nullable Supplier<InputStream> defaultsStream)
    • v4 code calling new StandaloneConfig(file, false, yourSupplier) should be updated to new StandaloneConfig(yourLogger, file, null)
    • v4 code using new StandaloneConfig(file, true, yourSupplier) should be updated to new StandaloneConfig(yourLogger, file, yourSupplier)

Constructor Changes for AbstractYamlHandler

  • REFACTORED: Constructor AbstractYamlHandler(AbstractConfig, File)AbstractYamlHandler(AbstractConfig, File, @Nullable Supplier<InputStream>)
    • v4 code using new YamlHandler(config, file) should be updated to new YamlHandler(config, file, null)
  • REMOVED: Constructor AbstractYamlHandler(AbstractConfig, File, String fileName)
    • This functionality is no longer supported, the file name is derived from the File object passed in
  • REFACTORED: Method #loadConfig(boolean addDefaults, @Nullable Supplier<InputStream>)#loadConfig()
    • The boolean flag is now a null-check on the supplier
    • The supplier is provided in the constructor, and does not need to be passed in here again
  • REMOVED: Methods #getIS() and #getIS(Supplier<InputStream>)
    • The supplier is provided in the constructor, this backup logic is no longer necessary

Changes for YamlHandler Class

These changes aim to remove the dependence on JavaPlugin, and require the defaults stream to be passed into the constructor:

  • REMOVED: Constructor YamlHandler(AbstractConfig, JavaPlugin, File)
  • REMOVED: Constructor YamlHandler(AbstractConfig, JavaPlugin, File, String)
  • ADDED: Constructor YamlHandler(AbstractConfig, LoggerService, File, @Nullable Supplier<InputStream>)
    • The dependence on JavaPlugin was removed, and replaced with LoggerService since we only need logging functionality
  • REMOVED: Method YamlHandler#getIS()
    • Config system was reworked to use dependency injection, passing the defaults supplier through constructors
    • This method to provide a backup input stream is no longer necessary. There is no replacement

Changes for YamlHandlerStandalone Class

These changes aim to remove the dependence on JavaPlugin, and require the defaults stream to be passed into the constructor:

  • REMOVED: Constructor YamlHandler(AbstractConfig, File)
  • REMOVED: Constructor YamlHandler(AbstractConfig, File, String)
  • ADDED: Constructor YamlHandler(AbstractConfig, LoggerService, File, @Nullable Supplier<InputStream>)
    • A dependence on LoggerService was added because we need logging functionality

Changes for AbstractConfig Class

  • REMOVED: Method AbstractConfig#isAddDefaults()
    • This method was redundant and relied on another boolean flag that was removed
    • Instead of using the boolean flag, the system now checks if the defaults stream supplier is null or not

⚠️ BREAKING Command System Paging Changes

Pagination Methods for Commands, located in Txt were reworked into a dedicated class: CommandPaging

com.kamikazejam.kamicommon.command.util.CommandPaging

See v5 New APIs for the new methods.

The following breaking changes were made to Txt:

  • REMOVED: Txt.getPage(List<KMessageSingle>, int, String, KamiCommand)
    • REPLACED with: CommandPaging.getPage(KamiCommand, List<KMessageSingle> lines, int pageNum, String title)
  • REMOVED: Txt.getPage(List<KMessageSingle>, int, String, CommandSender, KamiCommand)
    • No direct replacement
  • REMOVED: Txt.getPage(List<KMessageSingle>, int, String, int, KamiCommand, List<String>)
    • REPLACED with: CommandPaging.getPage(KamiCommand, List<KMessageSingle> lines, int pageNum, String title, int pageheight)
  • REMOVED: Txt.getMessageEmpty()
    • REPLACED with: CommandPaging.Config#noPagesMessage
  • REMOVED: getMessageInvalid(int)
    • REPLACED with:
      • CommandPaging.Config#invalidPageMessage
      • CommandPaging.Config#onlyOnePageMessage
  • REMOVED: Txt.titleizedPageTitle(String, int, int, KamiCommand, List<String>)
    • REPLACED with: CommandPaging.titleizedPageTitle(KamiCommand, String title, int pageNum, int pageCount)
  • REMOVED: Txt.getKamiCommandHelp() (was unused, replace with your own construction of the KamiCommandHelp class)
  • MOVED: Txt.PAGEHEIGHT_PLAYERCommandPaging.PAGEHEIGHT_PLAYER
  • MOVED: Txt.PAGEHEIGHT_CONSOLECommandPaging.PAGEHEIGHT_CONSOLE

⚠️ BREAKING Menu Framework Changes

Menu Clicks Consolidation

Menu Clicks have been consolidated using new wrapper classes:

com.kamikazejam.kamicommon.menu.api.clicks.data.MenuClickData<M extends Menu<M>> com.kamikazejam.kamicommon.menu.api.clicks.data.PlayerClickData<M extends Menu<M>>

These classes offer the same data as before, but in a more extendable way. The player, click type, click event, clicked slot, menu object, and page (for MenuClickData) are all available in this wrapper via Getters.

These changes were to facilitate the restructuring of MenuClick, the following changes were made:

  • REFACTORED: MenuClickMenuClick<M extends Menu<M>>
  • REFACTORED: MenuClick#onClick(Player, ClickType)MenuClick#onClick(MenuClickData<M>)
    • MenuClick<M> is now the primary and only menu click interface, replacing all previous menu click interfaces
  • REFACTORED: PlayerSlotClick#onClick(Player, ClickType, int slot)PlayerSlotClick#onClick(PlayerClickData<M>)
    • PlayerSlotClick<M> is now the primary and only player click interface, replacing all previous player click interfaces

Removed Click Transform Classes

  • REMOVED: com.kamikazejam.kamicommon.menu.api.clicks.transform.paginated.IPaginatedClickTransform
  • REMOVED: com.kamikazejam.kamicommon.menu.api.clicks.transform.paginated.PaginatedMenuClickPageTransform
  • REMOVED: com.kamikazejam.kamicommon.menu.api.clicks.transform.simple.ISimpleClickTransform
  • REMOVED: com.kamikazejam.kamicommon.menu.api.clicks.transform.simple.SimpleMenuClickEventTransform
  • REMOVED: com.kamikazejam.kamicommon.menu.api.clicks.transform.simple.SimpleMenuClickTransform
  • REMOVED: com.kamikazejam.kamicommon.menu.api.clicks.transform.IClickTransform
    • Replaced by MenuClickTransform<M> (for MenuClick<M>) and PlayerSlotClickTransform<M> (for PlayerSlotClick<M>)

Added Click Transform Classes

  • ADDED: com.kamikazejam.kamicommon.menu.api.clicks.transform.MenuClickTransform<M extends Menu<M>>
    • Consolidated version of previous transforms, since the menu click wrapper contains all previous interface options
  • ADDED: com.kamikazejam.kamicommon.menu.api.clicks.transform.PlayerSlotClickTransform
    • Consolidated version of previous transforms, since the player click wrapper contains all previous interface options

Removed Click Classes

  • REMOVED: com.kamikazejam.kamicommon.menu.api.clicks.MenuClickEvent (replaced by MenuClick<M>)
  • REMOVED: com.kamikazejam.kamicommon.menu.api.clicks.MenuClickPage (replaced by MenuClick<M>)
  • REMOVED: com.kamikazejam.kamicommon.menu.api.clicks.OneClickMenuTransform (replaced by MenuClick<M>)

Menu Click Registration Method Updates

These changes mean that all menu click registration methods were updated:

  • REFACTORED: IPageIconAccess#setMenuClick(String id, MenuClick click)IPageIconAccess<M>#setMenuClick(String id, MenuClick<M> click)
  • REMOVED: IPageIconAccess#setMenuClick(String id, MenuClickPage click) (replaced by MenuClick<M>)
  • REMOVED: IPageIconAccess#setMenuClick(String id, MenuClickEvent click) (replaced by MenuClick<M>)
  • REFACTORED: IMenuIconsAccess#setMenuClick(String id, MenuClick click)IMenuIconsAccess<M>#setMenuClick(String id, MenuClick<M> click)
  • REMOVED: IMenuIconsAccess#setMenuClick(String id, MenuClickPage click) (replaced by MenuClick<M>)
  • REMOVED: IMenuIconsAccess#setMenuClick(String id, MenuClickEvent click) (replaced by MenuClick<M>)
  • REFACTORED: MenuIcon#setMenuClick(MenuClick click)MenuIcon<M>#setMenuClick(MenuClick<M> click)
  • REMOVED: MenuIcon#setMenuClick(MenuClickPage click) (replaced by MenuClick<M>)
  • REMOVED: MenuIcon#setMenuClick(MenuClickEvent click) (replaced by MenuClick<M>)

Menu Type Safety Changes

Several classes had their signatures changed to add a generic type parameter for the specific Menu type. This allowed the specific menu type to be preserved and known in these classes, allowing access to that specific menu in more places.

  • REFACTORED: MenuMenu<M extends Menu<M>>
  • REFACTORED: MenuIconMenuIcon<M extends Menu<M>>
  • REFACTORED: IMenuIconsAccessIMenuIconsAccess<M extends Menu<M>>
  • REFACTORED: MenuIconsAccessMenuIconsAccess<M extends Menu<M>>
  • REFACTORED: IPageIconsAccessIPageIconsAccess<M extends Menu<M>>
  • REFACTORED: PageIconsAccessPageIconsAccess<M extends Menu<M>>
  • REFACTORED: PrioritizedMenuIconPrioritizedMenuIcon<M extends Menu<M>>
  • REFACTORED: PrioritizedMenuIconMapPrioritizedMenuIconMap<M extends Menu<M>>
  • REFACTORED: MenuOptionsMenuOptions<M extends Menu<M>>

Menu Modification Interface Changes

The modification interfaces created for certain menu classes were deemed unnecessary and needlessly confusing. They have been removed and their functionality replaced by Java Consumer functional interfaces.

  • REFACTORED: AbstractMenuBuilder#options(MenuOptions.MenuOptionsModification)AbstractMenuBuilder#options(Consumer<MenuOptions<M>>)
  • REFACTORED: AbstractMenuBuilder#events(MenuEvents.MenuEventsModification)AbstractMenuBuilder#events(Consumer<MenuEvents<M>>)
  • REFACTORED: PaginatedMenu.Builder#paginationOptions(PaginatedMenuOptions.PaginatedMenuOptionsModification)PaginatedMenu.Builder#paginationOptions(Consumer<PaginatedMenuOptions>)
  • REFACTORED: OneClickMenu.Builder#oneClickOptions(OneClickMenuOptions.OneClickMenuOptionsModification)OneClickMenu.Builder#oneClickOptions(Consumer<OneClickMenuOptions>)

Misc Menu Changes

  • REFACTORED: MenuIcon#getDefaultFillerIcon
    • Now uses MenuIcon.Config configuration class to supply the ItemBuilder for the filler icon
  • REFACTORED: Menu#reopenMenu(Player)Menu#reopenMenu()
    • Player is available in the menu instance, we do not need to pass it in ourselves, that just promotes misuse by passing in a different player
  • REFACTORED: Menu#reopenMenu(Player, boolean)Menu#reopenMenu(boolean)
    • Player is available in the menu instance, we do not need to pass it in ourselves, that just promotes misuse by passing in a different player
  • REMOVED: Constructor AbstractMenuBuilder(MenuSize)
    • Constructor was not possible to use due to new menu generic type parameter
    • MenuEvents<M> and MenuOptions<M> are required to create the builder, and must be created externally by a builder who knows the type

⚠️ BREAKING KamiCommand Changes

A few minor (but BREAKING) changes were made to KamiCommand:

  • RENAMED: KamiCommand.helpKamiCommand.helpComments
    • This better reflects the purpose of the variable, which is to allow a list of lines to be added atop the help output in chat
    • ALSO RENAMED: #setHelp(List<KMessageSingle> help)#setHelpComments(List<KMessageSingle> helpComments)
    • ALSO RENAMED: #setHelp(KMessageBlock block)#setHelpComments(KMessageBlock block)
  • REFACTORED: #execute(CommandSender sender, List<String> args)#execute(CommandSender sender, String label, List<String> args)
  • REMOVED: #getTemplateClickSuggest(boolean addDesc, boolean onlyFirstAlias, boolean onlyOneSubAlias, CommandSender sender)
    • Internal reworks left this method unused, so it was removed
    • See alternate methods like #getSuggestionClickable which offer similar functionality
  • REMOVED: #getTemplateClickRun(boolean addDesc, boolean onlyFirstAlias, boolean onlyOneSubAlias, CommandSender sender)
    • Internal reworks left this method unused, so it was removed. No direct replacement
  • REFACTORED: #getTemplate(boolean addDesc, boolean onlyFirstAlias, boolean onlyOneSubAlias, CommandSender sender)#getFullTemplate(... same args ...)
  • REMOVED: #getTemplateWithArgs(CommandSender, String...) and #getTemplateWithArgs(CommandSender, List<String>)
    • Internal reworks left this method unused, so it was removed. No direct replacement
  • REMOVED: #getTemplateChain(boolean onlyFirstAlias, CommandSender sender)
    • USE: #getTemplateChain(boolean onlyFirstAlias, boolean onlyOneSubAlias, CommandSender sender) instead
  • REMOVED: #getCommandLine(String... args)
    • USE: #getCommandLine(Iterable<String> args) instead
  • REMOVED: static KamiCommand.TEMPLATE_CORE
    • Replaced with configuration system, see KamiCommand.Config

⚠️ BREAKING ConfigObserver Changes

The Config Observer system was reconsidered and had some key modifications for clarity and extendibility.

  • ConfigObserver was relocated one package deeper, see Relocated Classes above
  • ADDED: com.kamikazejam.kamicommon.configuration.spigot.observe.ObservableConfig
    • This interface lays the foundation for any class that wishes to be observable by ConfigObservers
    • It requires registration management methods (of ConfigObservers) to be implemented

Existing Classes Marked as ObservableConfig

Existing Classes were marked as ObservableConfig, to standardize the way they are observed:

  • KamiConfig (and KamiConfigExt)
  • KamiPlugin
  • AbstractSubsystem

Module Class Updates

In addition, the Module class was updated to remove its custom config management, and to extend ObservableConfig instead:

  • REMOVED: Module#onConfigLoaded(ModuleConfig)
    • USE: Module#registerConfigObserver(ConfigObserver) with your own ConfigObserver implementation instead

KamiPlugin Class Updates

In addition, the KamiPlugin class was updated to remove its custom config management, and to extend ObservableConfig instead:

  • REMOVED: KamiPlugin#onConfigLoaded(KamiConfig)
    • USE: KamiPlugin#registerConfigObserver(ConfigObserver) with your own ConfigObserver implementation instead

⚠️ BREAKING CachedConfig Changes

The objective of the cached config classes were to more easily provide a framework for a class that contains cached config data. This system in v4 worked, but it quickly fell apart under the new ConfigObserver/ObservableConfig model, and with the addition of Features.

The following changes were made:

  • REMOVED: com.kamikazejam.kamicommon.modules.config.CachedModuleConfig<M>
  • REMOVED: com.kamikazejam.kamicommon.configuration.spigot.ICachedConfig<T>
    • CachedConfig is now its own class which only implements ConfigObserver
    • No other classes needed shared cache config functionality, so this interface was unnecessary
  • REFACTORED: CachedConfig#registerObserver()CachedConfig#register()
    • Renamed for clarity and to distinguish from ObservableConfig#registerConfigObserver(ConfigObserver)
  • REFACTORED: CachedConfig#loadConfig(T config)CachedConfig#loadCache(T config)
    • Renamed for clarity and to prevent confusion with the config load methods. This is for the cache, not the config itself

ICachedConfig Method Merges

ICachedConfig was removed, but its methods were merged into CachedConfig, with some changes:

  • REFACTORED: #registerObserver(ConfigObserver)#registerConfigObserver(ConfigObserver)
  • REFACTORED: #unregisterObserver(ConfigObserver)#unregisterConfigObserver(ConfigObserver)
    • While unregistration was not defined in ICachedConfig in v4, the method was present in implementations. It has been renamed for clarity

⚠️ BREAKING Changes from AbstractSubsystem Abstraction

In v5, the Module class and supporting classes were reworked to be based on a new AbstractSubsystem class. This was done to allow for future subsystem types, such as Feature. See v5 New APIs

  • REFACTORED: ModuleConfig.loadDefaultConfig()SubsystemConfig.addConfigDefaults()
  • REMOVED: ModuleConfig.getModule(Class<T> class)
    • Use your own state management if you want to keep track of your specific class instances
  • REFACTORED: ModuleConfig.getRawModule()ModuleConfig.getModule()
  • REMOVED: Module.getConfigName()
    • Was used internally, but its logic was moved to AbstractSubsystem#getConfigResourcePath() and AbstractSubsystem#getConfigFileDestination()
    • No replacement is available

LoggerService Integration

In v5, the AbstractSubsystem class was made into a LoggerService, which means it supports more advanced logging methods. Certain existing logging methods were removed, in favor of the default LoggerService methods:

  • REMOVED: Module#log(String) (use #info(String) instead)
  • REMOVED: Module#warnWithTrace(String msg)
    • No direct replacement is available, however you can use #warn(Throwable, String) to log a warning AND a stack trace
  • REMOVED: Module#errorWithTrace(String msg)
    • No direct replacement is available, however you can use #error(Throwable, String) to log an error AND a stack trace
  • REMOVED: Module#registerConfigObserver(ConfigObserver, KamiConfig)
    • This was an alias of KamiConfig#registerConfigObserver(ConfigObserver), use that method directly instead

⚠️ BREAKING IBuilder and ItemBuilder Changes

Version 5.0.0-alpha.17 introduces breaking changes to the IBuilder interface and the ItemBuilder class.

These changes were inspired by the new Paper Data Component API which has its own Prototype/Patch model.
These breaking changes implemented a similar prototype/patch model inside of ItemBuilder.

CONSTRUCTORS: The constructors for ItemBuilder have been reworked and simplified:

  • REMOVED: ItemBuilder()
    • You must now provide a prototype ItemStack when creating an ItemBuilder instance
  • RELOCATED: ItemBuilder(ConfigurationSection)
    • Use static method ItemBuilder.load(ConfigurationSection) instead
  • REMOVED: ItemBuilder(ConfigurationSection, @Nullable OfflinePlayer)
    • OfflinePlayer param was being used to set the skull owner, this can be done on your own after building the ItemBuilder
    • Use ItemBuilder(ConfigurationSection).setSkullOwner(OfflinePlayer.getName()) instead
  • RELOCATED: ItemBuilder(XMaterial, ConfigurationSection)
    • Use static method ItemBuilder.load(XMaterial, ConfigurationSection) instead
  • REMOVED: ItemBuilder(XMaterial, ConfigurationSection, @Nullable OfflinePlayer)
    • OfflinePlayer param was being used to set the skull owner, this can be done on your own after building the ItemBuilder
    • Use ItemBuilder.load(XMaterial, ConfigurationSection).setSkullOwner(OfflinePlayer.getName()) instead
  • RELOCATED: ItemBuilder(ItemStack, ConfigurationSection)
    • Use static method ItemBuilder.load(ItemStack, ConfigurationSection) instead
  • REMOVED: ItemBuilder(ItemStack, ConfigurationSection, @Nullable OfflinePlayer)
    • OfflinePlayer param was being used to set the skull owner, this can be done on your own after building the ItemBuilder
    • Use ItemBuilder.load(ItemStack, ConfigurationSection).setSkullOwner(OfflinePlayer.getName()) instead
  • REMOVED: ItemBuilder(XMaterial, short damage)
    • This legacy constructor for creating pre-1.13 items has been removed.
    • Create the desired legacy ItemStack variant and use the ItemBuilder(ItemStack) constructor instead
  • REMOVED: ItemBuilder(XMaterial, int amount)
    • This helper constructor was removed for clarity, as the amount can be set with #setAmount(int) after creation
    • Replace with new ItemBuilder(XMaterial).setAmount(int) instead
  • REMOVED: ItemBuilder(XMaterial, int amount, short damage)
    • This legacy constructor for creating pre-1.13 items has been removed.
    • Create the desired legacy ItemStack variant and then use new ItemBuilder(ItemStack).setAmount(int)
  • REMOVED: ItemBuilder(ItemStack, boolean clone)
    • This helper constructor was removed for clarity, as the user can clone the stack themselves before passing it in if desired
    • Replace with new ItemBuilder(itemStack.clone()) if you want to clone the stack before passing it in

Efforts were made to keep the ItemBuilder class and its methods as close to backwards compatible as possible, but there are still breaking changes:

  • IBuilder reworked from an abstract class to a sealed interface IBuilder<T extends IBuilder<T>>
    • Only permits the ItemBuilder class to implement it
  • REMOVED: Class IAItemBuilder (and all references to it)
    • The ItemsAdder integration is no longer available
    • See the Javadoc class comment on ItemBuilder for recommendations on integrating with ItemsAdder
  • REMOVED: Type/Material/Base Mutability
    • REMOVED: #setMaterial(Material), #setMaterial(XMaterial), #setType(XMaterial), and #setBase(ItemStack)
      • The new prototype/patch model defines an immutable prototype ItemStack that cannot be changed
      • To change the Material of an ItemBuilder, you must create a new ItemBuilder instance with the desired Material
      • Helper functions exist to copy all patches into a new ItemBuilder instance:
        • #cloneWithNewPrototype(...) (overloads for Material, XMaterial, and ItemStack)
        • Returns a new instance of ItemBuilder with the same patches applied to the new prototype
  • REFACTORED: #getBase()#getPrototype()
    • The base ItemStack is now referred to as the prototype ItemStack
    • The prototype ItemStack is immutable and cannot be changed after creation
    • It was also refactored into a final and non-null ItemStack
  • REFACTORED: short getDamage()int getDamage()
    • The ItemBuilder damage value no longer refers to the pre-1.13 data value which was removed in the flattening
    • The damage value now refers to the actual durability damage of the item (i.e. the 1.13+ Damageable interface value)
    • The damage value is now an int to match the Damageable interface
    • The old logic of mutating the ItemStack data value to edit its variant (like wool color) has been removed
      • You will need to supply the correct ItemStack variant as the prototype when creating the ItemBuilder
  • REFACTORED: List<ItemFlag> getItemFlags()Set<XItemFlag> getItemFlags()
    • The ItemBuilder now uses the XItemFlag enum from XSeries for better cross-version compatibility
    • Returns a set instead of a list, as item flags enums are unique and unordered
  • REMOVED: Method #getNbtData()
    • KamiCommon ships with the NBT-API as a transitive dependency, and shaded in the spigot-jar artifact
    • Migrate your nbt usage to apply NBT after building the ItemStack with #build()
  • REMOVED: Method #loadNBT(ConfigurationSection)
    • ItemBuilder no longer supports handling nbt data internally, and has removed support for defining NBT in configuration sections
    • NBT will have to be added in code, or with your own config parsing
    • (This was removed due to its poor type safety, lack of flexibility, and minimal integration by users)
  • REFACTORED: #getUnbreakable()#isUnbreakable()
    • Renamed to follow Java boolean naming conventions
  • REFACTORED: #addGlow(boolean glow)#setGlow(boolean glow)
    • Renamed to to better reflect behavior, the #addGlow() method has no params, while this one does
  • REMOVED: Method #loadTypes(ConfigurationSection)
    • This internal method was removed completely, due to the prototype/patch model having an immutable prototype
    • Use the new ItemTypeLoader class to load item types from configuration sections instead
    • If mutation of the prototype is needed, use the #cloneWithNewPrototype(...) methods to create a new instance with the desired prototype
  • REFACTORED: #addEnchantment(XEnchantment, Integer)#setEnchantment(XEnchantment, Integer)
    • Name better reflects behavior, enchantment level is being set, not added
  • REFACTORED: #addEnchantments(Map<XEnchantment, Integer>)#setEnchantments(Map<XEnchantment, Integer>)
    • Name better reflects behavior, enchantment levels are being set, not added
  • REFACTORED: #addFlag(ItemFlag)#addItemFlag(XItemFlag)
    • Name updated for clarity of the type being used
    • Now uses XItemFlag from XSeries for better cross-version compatibility
  • REMOVED: Method #build(Player, int amount)
    • Internal method that was not using the integer argument
    • Use #build(Player) instead for the exact same behavior
  • REMOVED: Method #loadClone(IBuilder)
    • Internal method that after refactor was no longer needed
    • Use #clone() if you need to clone an ItemBuilder instance
    • Use #cloneWithNewPrototype(...) if you need to clone an ItemBuilder instance with a new prototype
  • REMOVED: Methods #parseMaterial(String) and #parseXMaterial(String)
    • Internal methods that were not used after refactor
    • These methods just wrapped Material.getMaterial(String) and XMaterial.matchXMaterial(String) in a try-catch
    • If you need this functionality, you can mimic the behavior with your own try-catch handling

⚠️ BREAKING KamiCommon APIs that consumed IBuilder

In addition, some KamiCommon APIs that consumed IBuilder, have been updated to consume ItemBuilder instead:

  • REFACTORED: Method IPageIconsAccess#addPagedIcon(IBuilder)IPageIconsAccess#addPagedIcon(ItemBuilder)
  • REFACTORED: Method IPageIconsAccess#addPagedIcon(String, IBuilder)IPageIconsAccess#addPagedIcon(String, ItemBuilder)
  • REFACTORED: Method IMenuIconsAccess#setMenuIcon(IBuilder, int)IMenuIconsAccess#setMenuIcon(ItemBuilder, int)
  • REFACTORED: Method IMenuIconsAccess#setMenuIcon(IBuilder, IconSlot)IMenuIconsAccess#setMenuIcon(ItemBuilder, IconSlot)
  • REFACTORED: Method IMenuIconsAccess#setMenuIcon(String, IBuilder, int)IMenuIconsAccess#setMenuIcon(String, ItemBuilder, int)
  • REFACTORED: Method IMenuIconsAccess#setMenuIcon(String, IBuilder, IconSlot)IMenuIconsAccess#setMenuIcon(String, ItemBuilder, IconSlot)
  • REFACTORED: Method IMenuIconsAccess#setMenuIcon(IBuilder, int, int)IMenuIconsAccess#setMenuIcon(ItemBuilder, int, int)
  • REFACTORED: Method IMenuIconsAccess#setMenuIcon(String, IBuilder, int, int)IMenuIconsAccess#setMenuIcon(String, ItemBuilder, int, int)
  • REFACTORED: Class MenuIcon
    • REFACTORED: Method List<IBuilder> MenuIcon#getIBuilders()List<ItemBuilder> MenuIcon#getItemBuilders()
      • Backing variable was renamed for consistency, and the auto-generated getter updated accordingly
    • REFACTORED: Constructors that accepted IBuilder parameters now accept ItemBuilder parameters instead
    • REFACTORED: Methods that returned or consumed IBuilder parameters now return or consume ItemBuilder instead
  • REFACTORED: Method MenuHolder#setItem(int, IBuilder)MenuHolder#setItem(int, ItemBuilder)

⚠️ BREAKING MenuIconModifier interface Changes

The MenuIconModifier interface has been updated to use the new ItemBuilder class.
It also now has a requirement to return the desired ItemBuilder object that you wish the icon to use!!!

  • REFACTORED: Interface StatefulIconModifier
    • void modify(IBuilder, ItemStack, Player, int)ItemBuilder modify(ItemBuilder, ItemStack, Player, int)
  • REFACTORED: Interface StaticIconModifier
    • void modify(IBuilder)ItemBuilder modify(ItemBuilder)

This change is to facilitate the use of the new prototype/patch model in ItemBuilder, where the prototype is immutable and cannot be changed after creation.
Before, the interface only allowed changing patches on the existing ItemBuilder, but now you can return a completely new ItemBuilder instance with a different prototype if needed.

⚠️ BREAKING Integration Removals

The following integrations have been removed from KamiCommon:

  • REMOVED: Citizens Plugin API
  • REMOVED: ItemsAdder Plugin API
  • REMOVED: MythicMobs Plugin API

These removals have resulted in the following breaking changes (removed APIs):

  • REMOVED: Open Method: AbstractSubsystem#onItemsAdderLoaded()
    • Replace with your own bukkit event listening to ItemsAdderLoadDataEvent if needed
  • REMOVED: Open Method: AbstractSubsystem#onMythicMobsLoaded()
    • Replace with your own onEnable trigger + event listener for MythicReloadedEvent if needed
  • REMOVED: Open Method: AbstractSubsystem#onCitizensLoaded()
    • Replace with your own onEnable trigger + event listeners for CitizensEnableEvent and CitizensReloadEvent if needed
  • REMOVED: Static Method: KamiPlugin#hasItemsAdder()
    • Replace with your own plugin manager check for the "ItemsAdder" plugin if needed
  • REMOVED: Static Method: KamiPlugin#hasCitizens()
    • Replace with your own plugin manager check for the "Citizens" plugin if needed
  • REMOVED: Static Method: KamiPlugin#hasMythicMobs()
    • Replace with your own plugin manager check for the "MythicMobs" plugin if needed

These internal methods were also removed during the refactor:

  • REMOVED: Class com.kamikazejam.kamicommon.subsystem.integration.CitizensIntegration
  • REMOVED: Class com.kamikazejam.kamicommon.subsystem.integration.ItemsAdderIntegration
  • REMOVED: Class com.kamikazejam.kamicommon.subsystem.integration.MythicMobsIntegration
  • REMOVED: Method FeatureManager#onItemsAdderLoaded()
  • REMOVED: Method FeatureManager#onMythicMobsLoaded()
  • REMOVED: Method FeatureManager#onCitizensLoaded()
  • REMOVED: Method ModuleManager#onItemsAdderLoaded()
  • REMOVED: Method ModuleManager#onMythicMobsLoaded()
  • REMOVED: Method ModuleManager#onCitizensLoaded()

Last Updated: September 1, 2025, for commit a23c4493335e7e918479c3292e9a15afd1d80e4a

Clone this wiki locally