{"record":{"id":"74a830e9ae3af161","repo":"languagetool-org/languagetool","slug":"language-was-already-instantiated-see-the-cause-s-74a830","errorCode":null,"errorMessage":"Language was already instantiated, see the cause stacktrace below.","messagePattern":"Language was already instantiated, see the cause stacktrace below\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-language-modules/zh/src/main/java/org/languagetool/language/Chinese.java","lineNumber":49,"sourceCode":"import org.languagetool.tagging.Tagger;\nimport org.languagetool.tagging.zh.ChineseTagger;\nimport org.languagetool.tokenizers.SentenceTokenizer;\nimport org.languagetool.tokenizers.Tokenizer;\nimport org.languagetool.tokenizers.zh.ChineseSentenceTokenizer;\nimport org.languagetool.tokenizers.zh.ChineseWordTokenizer;\n\nimport java.io.IOException;\nimport java.util.*;\n\npublic class Chinese extends LanguageWithModel {\n  private static final String LANGUAGE_SHORT_CODE = \"zh-CN\";\n\n  private static volatile Throwable instantiationTrace;\n\n  public Chinese() {\n    Throwable trace = instantiationTrace;\n    if (trace != null) {\n      throw new RuntimeException(\"Language was already instantiated, see the cause stacktrace below.\", trace);\n    }\n    instantiationTrace = new Throwable();\n  }\n\n  /**\n   * This is a fake constructor overload for the subclasses. Public constructors can only be used by the LT itself.\n   */\n  protected Chinese(boolean fakeValue) {\n  }\n\n\n  @Override\n  public String getShortCode() {\n    return \"zh\";\n  }\n\n  @Override\n  public String getName() {","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-language-modules/zh/src/main/java/org/languagetool/language/Chinese.java#L31-L67","documentation":"Chinese is a singleton-style Language class that guards against multiple instantiation by recording a Throwable on first construction; a second constructor call throws this RuntimeException, with the first instantiation's stacktrace as the cause. This protects internal caching assumptions that Language objects are created once.","triggerScenarios":"Calling new Chinese() a second time, e.g. code instantiating the language directly instead of using Languages.getLanguageForShortCode(\"zh\"), or reflection/plugin code re-creating it.","commonSituations":"Custom server setups or tests that construct Chinese manually after LanguageTool has already registered it; copying instantiation patterns from other language classes.","solutions":["Use Languages.getLanguageForShortCode(\"zh\") or Chinese.getInstance() instead of new Chinese()","Inspect the cause stacktrace to find where the first instantiation happened","Remove any custom factory code that constructs Chinese directly"],"exampleFix":"// before\nLanguage zh = new Chinese();\n// after\nLanguage zh = Languages.getLanguageForShortCode(\"zh\");","handlingStrategy":"type-guard","validationCode":"Language lang = Languages.getLanguageForShortCode(\"zh\");\nif (lang instanceof Chinese) { /* reuse it */ }","typeGuard":"boolean chineseReady() {\n    return Languages.getLanguageForShortCode(\"zh\") instanceof Chinese;\n}","tryCatchPattern":"try {\n    Language zh = getOrCreateChinese();\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Language was already instantiated\")) {\n        zh = Languages.getLanguageForShortCode(\"zh\"); // reuse singleton\n    } else throw e;\n}","preventionTips":["Never construct Language subclasses directly; use the Languages registry","Use Chinese.getInstance() as the single access point","Read the cause stacktrace to find the first instantiation site","Keep custom factories in sync with LanguageTool's registration"],"tags":["java","singleton","languagetool"],"backgroundTag":"internal-invariant-violation","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}