{"record":{"id":"c8ad899d12f926f2","repo":"languagetool-org/languagetool","slug":"databaseaccess-init-has-not-been-called-yet-or-f","errorCode":null,"errorMessage":"DatabaseAccess.init() has not been called yet or failed","messagePattern":"DatabaseAccess\\.init\\(\\) has not been called yet or failed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"languagetool-server/src/main/java/org/languagetool/server/DatabaseAccess.java","lineNumber":79,"sourceCode":"      try {\n        Class<DatabaseAccess> clazz = (Class<DatabaseAccess>) JLanguageTool.getClassBroker().forName(className);\n        instance = clazz.getConstructor(HTTPServerConfig.class).newInstance(config);\n      } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {\n        throw new RuntimeException(e);\n      }\n    }\n  }\n\n  static synchronized void reset() {\n    if (instance != null) {\n      instance.sqlSessionFactory = null;\n    }\n    instance = null;\n  }\n\n  static synchronized DatabaseAccess getInstance() {\n    if (instance == null) {\n      throw new IllegalStateException(\"DatabaseAccess.init() has not been called yet or failed\");\n    }\n    return instance;\n  }\n\n  /**\n   * @since 5.7\n   * Test if instance is configured and can be used\n   */\n  static synchronized boolean isReady() {\n    return instance != null;\n  }\n\n  /**\n   * For tests, to avoid waiting for the invalidation period.\n   */\n  abstract void invalidateCaches();\n\n  abstract boolean addWord(String word, Long userId, String groupName);","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-server/src/main/java/org/languagetool/server/DatabaseAccess.java#L61-L97","documentation":"DatabaseAccess.getInstance() is a singleton accessor that throws IllegalStateException when the static `instance` field is null. The field is only populated by the static init() method, so this error means the server-side database layer was never initialized (or init() failed and reset instance to null). It is an internal lifecycle error: some code path tried to use the database before setup completed.","triggerScenarios":"Any call to DatabaseAccess.getInstance() before DatabaseAccess.init(...) has run, or after init() failed and set `instance = null`. In practice: server code reaching authentication/word-list features on a server that was started without database configuration.","commonSituations":"Running languagetool-server without the database/MyBatis config arguments (or premium setup) while a request still hits an endpoint that requires user data; init() throwing during startup (bad DB connection settings) so the singleton stays null; calling DatabaseAccess APIs from custom embedding code without calling init() first.","solutions":["Ensure the server is started with the required database configuration so DatabaseAccess.init(...) is invoked during startup (or call DatabaseAccess.init(...) explicitly in embedded setups).","Check server startup logs for an exception thrown by DatabaseAccess.init(); fix the underlying DB connection/config problem, since a failed init resets instance to null.","Guard calls with a null/state check or only use DatabaseAccess-dependent endpoints after the server reports it is ready.","If you only need the basic (non-database) server, make sure requests do not use premium/username+apiKey features that touch DatabaseAccess."],"exampleFix":"// before\nDatabaseAccess db = DatabaseAccess.getInstance(); // IllegalStateException if init not called\n// after\nif (!DatabaseAccess.isInitialized()) { // check or ensure init ran at startup\n  DatabaseAccess.init(sqlSessionFactoryConfig);\n}\nDatabaseAccess db = DatabaseAccess.getInstance();","handlingStrategy":"try-catch","validationCode":"if (!databaseConfigured()) {\n  throw new IllegalStateException(\"Server started without database config; DatabaseAccess will be unavailable\");\n}","typeGuard":"boolean dbAvailable() { try { DatabaseAccess.getInstance(); return true; } catch (IllegalStateException e) { return false; } }","tryCatchPattern":"try {\n  DatabaseAccess db = DatabaseAccess.getInstance();\n  // use db\n} catch (IllegalStateException e) {\n  // fall back to anonymous/no-auth request or surface 'database not configured'\n}","preventionTips":["Always start the server with the required database arguments, or never call DatabaseAccess-dependent endpoints.","Log and fail fast if DatabaseAccess.init() throws during startup.","Add a startup readiness check before accepting authenticated traffic."],"tags":["java","singleton-not-initialized","lifecycle","database"],"backgroundTag":"module-init-failed","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"}