Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,17 @@ public Set<String> getBundledShopModes() {
private boolean setupEconomy() {
RegisteredServiceProvider<Economy> registration =
plugin.getServer().getServicesManager().getRegistration(Economy.class);
if (registration != null) {
economy = registration.getProvider();
return economy != null;
if (registration == null) {
plugin.getLogger().severe("No Vault economy provider is registered. Install an economy "
+ "plugin that provides a Vault economy service (e.g. EssentialsX, CMI).");
return false;
}

return plugin.getServer().getPluginManager().getPlugin("Vault") != null;
economy = registration.getProvider();
if (economy == null) {
plugin.getLogger().severe("Vault registered a null economy provider.");
return false;
}
return true;
}

private void saveDefaultResources() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private PlayerShopRepository createRepository(EzShopsPlugin plugin) {
plugin.getLogger().info("Player shops: using Jaloquent storage (JDBC adapter).");
return repo;
} catch (Exception ex) {
plugin.getLogger().severe("Failed to initialise Jaloquent for player shops; falling back to YAML. " + ex.getMessage());
plugin.getLogger().warning("Failed to initialise Jaloquent for player shops; falling back to YAML. " + ex.getMessage());
}
}
if ("mysql".equalsIgnoreCase(type)) {
Expand All @@ -136,7 +136,7 @@ private PlayerShopRepository createRepository(EzShopsPlugin plugin) {
plugin.getLogger().info("Player shops: using MySQL storage.");
return repo;
} catch (IllegalStateException ex) {
plugin.getLogger().severe("Failed to connect to MySQL for player shops; falling back to YAML. " + ex.getMessage());
plugin.getLogger().warning("Failed to connect to MySQL for player shops; falling back to YAML. " + ex.getMessage());
}
}
return new YmlPlayerShopRepository(plugin.getDataFolder(), plugin.getLogger());
Expand Down
28 changes: 28 additions & 0 deletions src/test/java/com/skyblockexp/ezshops/AbstractEzShopsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,27 @@ protected void loadProviderPlugin(Economy econ) {
}
}

/**
* Load a minimal plugin with the given name that registers no services.
* Used to simulate an environment where a hard dependency (e.g. Vault) is
* present but no economy provider is registered.
*/
protected void loadBarePlugin(String name) {
try {
PluginDescriptionFile description = new PluginDescriptionFile(
name, "1.0", BarePlugin.class.getName());
File dataFolder = Files.createTempDirectory("test-plugin-" + name).toFile();
BarePlugin plugin = (BarePlugin) getUnsafe().allocateInstance(BarePlugin.class);
plugin.init(server, description, dataFolder, new File(""),
BarePlugin.class.getClassLoader(), description,
Logger.getLogger(name));
server.getPluginManager().registerLoadedPlugin(plugin);
server.getPluginManager().enablePlugin(plugin);
} catch (IOException | InstantiationException e) {
throw new RuntimeException("Failed to load bare plugin " + name, e);
}
}

private static Unsafe getUnsafe() {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
Expand All @@ -111,6 +132,13 @@ private static Unsafe getUnsafe() {
}
}

public static class BarePlugin extends JavaPlugin {
@Override
public void onEnable() {
// Intentionally registers no services.
}
}

public static class TestProviderPlugin extends JavaPlugin {
static Economy econToRegister;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,16 @@ void servicesManager_registration_before_plugin_enable_allows_economy_detection(
assertNotNull(plugin);
assertTrue(plugin.isEnabled(), "EzShops should enable when an Economy provider is registered in ServicesManager");
}

@Test
void missingEconomyProvider_disablesPluginCleanly() {
// Vault present but no economy provider registered. This used to NPE in
// PlayerShopComponent.<init> because setupEconomy() returned true while
// the economy field was still null.
loadBarePlugin("Vault");

EzShopsPlugin plugin = assertDoesNotThrow(() -> loadPlugin(EzShopsPlugin.class));
assertFalse(plugin.isEnabled(),
"EzShops should disable cleanly when Vault has no economy provider");
}
}