languagetool-org/languagetool · error · IllegalStateException
DatabaseAccess.init() has not been called yet or failed
Error message
DatabaseAccess.init() has not been called yet or failed
What it means
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.
Source
Thrown at languagetool-server/src/main/java/org/languagetool/server/DatabaseAccess.java:79
try {
Class<DatabaseAccess> clazz = (Class<DatabaseAccess>) JLanguageTool.getClassBroker().forName(className);
instance = clazz.getConstructor(HTTPServerConfig.class).newInstance(config);
} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
static synchronized void reset() {
if (instance != null) {
instance.sqlSessionFactory = null;
}
instance = null;
}
static synchronized DatabaseAccess getInstance() {
if (instance == null) {
throw new IllegalStateException("DatabaseAccess.init() has not been called yet or failed");
}
return instance;
}
/**
* @since 5.7
* Test if instance is configured and can be used
*/
static synchronized boolean isReady() {
return instance != null;
}
/**
* For tests, to avoid waiting for the invalidation period.
*/
abstract void invalidateCaches();
abstract boolean addWord(String word, Long userId, String groupName);View on GitHub (pinned to 2e990059ce)
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.
Example fix
// before
DatabaseAccess db = DatabaseAccess.getInstance(); // IllegalStateException if init not called
// after
if (!DatabaseAccess.isInitialized()) { // check or ensure init ran at startup
DatabaseAccess.init(sqlSessionFactoryConfig);
}
DatabaseAccess db = DatabaseAccess.getInstance(); Defensive patterns
Strategy: try-catch
Validate before calling
if (!databaseConfigured()) {
throw new IllegalStateException("Server started without database config; DatabaseAccess will be unavailable");
} Type guard
boolean dbAvailable() { try { DatabaseAccess.getInstance(); return true; } catch (IllegalStateException e) { return false; } } Try / catch
try {
DatabaseAccess db = DatabaseAccess.getInstance();
// use db
} catch (IllegalStateException e) {
// fall back to anonymous/no-auth request or surface 'database not configured'
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- dbLogging can only be true if dbDriver, dbUrl, dbUsername, a
- WrongParameterNumberException
- listUnknownWords is set to false, unknown words not stored
- Unknown mode: <mode>
- Text checking was stopped due to too many errors (more than
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/c8ad899d12f926f2.
Report an issue: GitHub.