infinilabs/analysis-ik · error · IllegalStateException
ik dict has not been initialized yet, please call initial…
Error message
ik dict has not been initialized yet, please call initial method first.
What it means
Dictionary is a singleton that must be primed by the static method Dictionary.initial(Configuration) before any dictionary-dependent API runs; getSingleton() throws IllegalStateException when that initialization has not happened. Most library code paths (CJKSegmenter, CN_QuantifierSegmenter, AnalyzeContext stopword filtering, Monitor reload) call Dictionary.getSingleton() internally, so the exception usually surfaces from inside a tokenization call rather than from user code directly.
Solutions
- Call Dictionary.initial(DefaultConfig.getInstance()) once at application/test startup (static initializer, @BeforeAll, or context-listener) before the first IKAnalyzer/IKTokenizer use
- For custom configuration (ext/remote dictionaries), build your Configuration (e.g. DefaultConfig with a known conf dir) and pass that to initial instead of the default
- If the error appears mid-run in a container environment, check for duplicate IK jars across classloaders and keep exactly one copy so the initialized singleton and the consumers are the same class
- Wrap first-use in a small ensureInitialized() helper so every entry point cheaply guarantees initial was called
Example fix
// before — throws IllegalStateException on first token IKAnalyzer analyzer = new IKAnalyzer(true); analyzer.tokenize(...); // after — initialize the singleton once before first use Dictionary.initial(DefaultConfig.getInstance()); IKAnalyzer analyzer = new IKAnalyzer(true); analyzer.tokenize(...);
Defensive patterns
Strategy: validation
Validate before calling
private static volatile boolean ikInitialized;
static void ensureIkInitialized() {
if (!ikInitialized) {
synchronized (IkInit.class) {
if (!ikInitialized) {
Dictionary.initial(DefaultConfig.getInstance());
ikInitialized = true;
}
}
}
}
// call ensureIkInitialized() before creating IKAnalyzer or touching Dictionary Try / catch
try {
Dictionary.getSingleton().addWords(words);
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().contains("not been initialized")) {
Dictionary.initial(DefaultConfig.getInstance());
Dictionary.getSingleton().addWords(words); // retry once after init
} else {
throw e;
}
} Prevention
- Initialize the dictionary in a static initializer or app lifecycle hook so it cannot be skipped
- In test suites, put Dictionary.initial in a shared @BeforeAll rather than each test constructing analyzers ad hoc
- Keep exactly one copy of the IK jar in the classpath/classloader hierarchy to avoid a second uninitialized Dictionary class
- Document that this fork requires explicit Dictionary.initial — older IK versions self-initialized lazily, so copied-in legacy code will break
When it happens
Trigger: Calling Dictionary.getSingleton(), or any API that reaches it — new IKAnalyzer(...)/IKTokenizer tokenization, addWords/removeWords, Dictionary.matchInMainDict — before Dictionary.initial(cfg) has run anywhere in the JVM. Because singleton is a static field, this also happens in tests that fork/reset state or when a classloader boundary creates a second, uninitialized copy of the Dictionary class (e.g. some plugin containers).
Common situations: Upgrading from a classic IK Analyzer version where getSingleton() lazily self-initialized with DefaultConfig to this fork, where initialization is explicit and lazy init was removed; unit tests that construct an IKAnalyzer without the shared TestUtils.initial step; embedding IK in an application server/OSGi bundle where a child classloader loads a fresh Dictionary class after the parent-initialized one; multi-threaded first use racing initialization is safe (initial is synchronized) but zero use before first tokenization is not.
Related errors
AI-assisted analysis of infinilabs/analysis-ik@6d2d70fd1a (2026-08-14).
Data as JSON: /api/errors/aba2facb27e123e9.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/wltea/analyzer/dic/Dictionary.java:293
}
}
}
return remoteExtStopWordDictFiles;
}
private String getDictRoot() {
return conf_dir.toAbsolutePath().toString();
}
/**
* 获取词典单子实例
*
* @return Dictionary 单例对象
*/
public static Dictionary getSingleton() {
if (singleton == null) {
throw new IllegalStateException("ik dict has not been initialized yet, please call initial method first.");
}
return singleton;
}
/**
* 批量加载新词条
*
* @param words
* Collection<String>词条列表
*/
public void addWords(Collection<String> words) {
if (words != null) {
for (String word : words) {
if (word != null) {
// 批量加载词条到主内存词典中
singleton._MainDict.fillSegment(word.trim().toCharArray());
}
View on GitHub (pinned to 6d2d70fd1a)