{"record":{"id":"6a51ef9f625a26ae","repo":"openzipkin/zipkin","slug":"datasource-null","errorCode":null,"errorMessage":"datasource == null","messagePattern":"datasource == null","errorType":"validation","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"zipkin-storage/mysql-v1/src/main/java/zipkin2/storage/mysql/v1/MySQLStorage.java","lineNumber":59,"sourceCode":"\n    @Override public Builder strictTraceId(boolean strictTraceId) {\n      this.strictTraceId = strictTraceId;\n      return this;\n    }\n\n    @Override public Builder searchEnabled(boolean searchEnabled) {\n      this.searchEnabled = searchEnabled;\n      return this;\n    }\n\n    @Override public Builder autocompleteKeys(List<String> keys) {\n      if (keys == null) throw new NullPointerException(\"keys == null\");\n      this.autocompleteKeys = keys;\n      return this;\n    }\n\n    public Builder datasource(DataSource datasource) {\n      if (datasource == null) throw new NullPointerException(\"datasource == null\");\n      this.datasource = datasource;\n      return this;\n    }\n\n    public Builder settings(Settings settings) {\n      if (settings == null) throw new NullPointerException(\"settings == null\");\n      this.settings = settings;\n      return this;\n    }\n\n    public Builder listenerProvider(@Nullable ExecuteListenerProvider listenerProvider) {\n      this.listenerProvider = listenerProvider;\n      return this;\n    }\n\n    public Builder executor(Executor executor) {\n      if (executor == null) throw new NullPointerException(\"executor == null\");\n      this.executor = executor;","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin-storage/mysql-v1/src/main/java/zipkin2/storage/mysql/v1/MySQLStorage.java#L41-L77","documentation":"MySQLStorage.Builder.datasource throws NullPointerException when the DataSource argument is null. The DataSource is the single mandatory dependency of the MySQL storage: every query goes through jOOQ over this connection pool. The builder rejects null immediately so the failure happens at configuration time rather than at first query.","triggerScenarios":"Calling builder.datasource(null), e.g. wiring a DataSource bean that failed to be created or a DI field that is still null at builder time.","commonSituations":"Spring/Boot wiring where the DataSource bean is missing or conditional (test profile without a database), refactoring constructor order, or copy-pasted setup code where the datasource variable name changed.","solutions":["Supply a live javax.sql.DataSource (HikariDataSource, MysqlDataSource, etc.) before build().","If using DI, verify the DataSource bean exists in the active profile and is injected before the storage bean is constructed.","For tests, point a HikariDataSource at a MySQL container (e.g. Testcontainers) instead of leaving the field null."],"exampleFix":"// before\nMySQLStorage storage = builder.build(); // datasource never set -> NPE later at line 102 only if datasource(null) called\nbuilder.datasource(null);\n\n// after\nHikariDataSource ds = new HikariDataSource();\nds.setJdbcUrl(\"jdbc:mysql://localhost:3306/zipkin\");\nbuilder.datasource(ds);","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(dataSource, \"dataSource must be configured before building MySQLStorage\");\nbuilder.datasource(dataSource);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Wire the DataSource bean as a required dependency of the storage bean so DI fails early and clearly","Keep storage construction in a single factory method that always sets the datasource"],"tags":["mysql","storage","builder","null-pointer","datasource","configuration"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}