dromara/Sa-Token · error · SaTokenPluginException

插件不可为空

Error message

插件不可为空

What it means

SaTokenPluginException thrown by SaTokenPluginHolder.installPlugin(SaTokenPlugin) when the plugin argument is null. Installation would immediately NPE on plugin.getClass(), and a null plugin is always a caller bug, so the holder rejects it before touching any hook or install logic.

Source

Thrown at sa-token-core/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginHolder.java:198

				i--;
				consumeCount++;
			}
		}
		return consumeCount;
	}


	// ------------------- 插件 Install 与 Destroy -------------------

	/**
	 * 安装指定插件
	 * @param plugin /
	 */
	public synchronized SaTokenPluginHolder installPlugin(SaTokenPlugin plugin) {

		// 插件为空,拒绝安装
		if (plugin == null) {
			throw new SaTokenPluginException("插件不可为空");
		}

		// 插件已经被安装过了,拒绝再次安装
		if (isInstalledPlugin(plugin.getClass())) {
			throw new SaTokenPluginException("插件 [ " + plugin.getClass().getCanonicalName() + " ] 已安装,不可重复安装");
		}

		// 执行该插件的 install 前置钩子
		_consumeHooks(beforeInstallHooks, plugin.getClass());

		// 插件安装
		int consumeCount = _consumeHooks(installHooks, plugin.getClass());
		if (consumeCount == 0) {
			plugin.install();
		}

		// 执行该插件的 install 后置钩子
		_consumeHooks(afterInstallHooks, plugin.getClass());

View on GitHub (pinned to ac2c7f6e94)

Solutions

  1. Guard the call: if (plugin != null) holder.installPlugin(plugin)
  2. Fix the source of the null (bean definition, factory method) — a plugin that cannot be constructed should fail construction loudly
  3. In startup loops, filter nulls before registering

Example fix

// before
SaTokenPlugin p = env.isEnabled("x") ? new XPlugin() : null;
SaManager.getSaTokenPluginHolder().installPlugin(p); // -> 插件不可为空

// after
if (p != null) {
    SaManager.getSaTokenPluginHolder().installPlugin(p);
}
Defensive patterns

Strategy: validation

Validate before calling

if (plugin != null) {
    SaManager.getSaTokenPluginHolder().installPlugin(plugin);
}

Prevention

When it happens

Trigger: Calling saTokenPluginHolder.installPlugin(null) (directly or via SaManager.getSaTokenPluginHolder()) — e.g. registering a bean that a DI context failed to provide, or a conditionally constructed plugin that was null.

Common situations: Auto-configuration loops registering optional plugin beans without null checks; getBean returning null for an optional dependency; test code passing a mock that returned null; refactoring left a registration call but removed the construction.

Related errors


AI-assisted analysis of dromara/Sa-Token@ac2c7f6e94 (2026-08-14). Data as JSON: /api/errors/96c58ab7af8bf03d. Report an issue: GitHub.