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

  1. Call Dictionary.initial(DefaultConfig.getInstance()) once at application/test startup (static initializer, @BeforeAll, or context-listener) before the first IKAnalyzer/IKTokenizer use
  2. 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
  3. 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
  4. 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

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)