Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataSourceBuilder no longer invokes setUser on org.h2.jdbcx.JdbcDataSource #25263

Closed
gtsh opened this issue Feb 12, 2021 · 7 comments
Closed
Labels
type: regression A regression from a previous release
Milestone

Comments

@gtsh
Copy link

gtsh commented Feb 12, 2021

Up to Spring Boot 2.3.8, we used H2 as a stand in for our Oracle DB in local development.
When needing to look into the tables, we used /h2-console, without any problems.

This is no longer working starting with 2.4.x. Every attempt to log in fails with "Wrong userid or password 280000-200".

If tried back and forth a bit, tried to debug, but so far no luck, the only difference obvious to me being the Spring Boot version.

I cross checked by using the command line shell of H2, and there is exactly the same problem:
Login succeeds for a database, that was created by a 2.3.x service, but fails for a 2.4.x service.
I switched sequence, by deleting the database, and recreating it using the H2 shell, which forces the user to specify the new password - with the result I already suspected: in this case the server startup fails for the 2.4.x service, because now the service can not connect to the database.

My impression is, that the password somehow gets garbled in unpredictable, but consistent way, when Spring Boot passes it to H2.

It doesn't matter, whether I go with the default admin user "sa"/"" (empty password), or force my own password, e,g. "sa"/"sa".

Are there any debug switches that may highlight, what happens to the password?
Or any smart location for a break point to set?

Regards,
Thomas

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Feb 12, 2021
@wilkinsona
Copy link
Member

Have you checked the 2.4 release notes and, in particular, this section? Please let us know if that helps. If not, please provide a minimal sample that reproduces the problem and we can take another look.

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label Feb 12, 2021
@gtsh
Copy link
Author

gtsh commented Feb 16, 2021

Ok, tried to add spring.datasource.initialization-mode: ALWAYS, since I already had username=sa.

Anyway, the initilization-mode was probably not the problem, as the database gets started and successfully accessed by liquibase during startup in surefire and failsafe test, as well as when doing a spring-boot:run. I'm actually seeing lines

08:23:14.830 [restartedMain] INFO [-] o.s.b.autoconfigure.h2.H2ConsoleAutoConfiguration - H2 console available at '/h2-console'. Database available at 'jdbc:h2:./foobardb'

08:23:15.211 [restartedMain] INFO  [-] liquibase.lockservice - Changelog-Protokoll erfolgreich gesperrt.
08:23:15.463 [restartedMain] INFO  [-] liquibase.changelog - Creating database history table with name: PUBLIC.DATABASECHANGELOG

which confirm this.

I also should mention, that in the code, the datasource properties are relocated:

@Configuration
public class DatabaseConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.foobar")
    public DataSourceProperties szenarienDataSourceProperties() {
        return new DataSourceProperties();
    }

which is reflected in the configuration, which, after some experiments now looks like this:

app:
  datasource:
    foobar:
      url: jdbc:h2:./foobardb;AUTO_SERVER=TRUE;AUTO_SERVER_PORT=18084;MODE=Oracle;DB_CLOSE_DELAY=-1
      username: sa              <-- was already present 
      password: sa              <-- added this, in oder to test whether the password beeing empty (""? or null?) might have been a problem
      driver-class-name: org.h2.Driver
      type: org.h2.jdbcx.JdbcDataSource
      initialization-mode: always  <-- added this on your request as per documentation

spring:
   datasource:   <-- for good measure, also added this, just in case, but no joy there too. 
         username: sa             
         password: sa              
         initialization-mode: always  

So I'm going now to strip the project of all the things I'm not allowed to disclose, while also simplfying it (we use custom pom inheritance), which might take a moment.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Feb 16, 2021
@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Feb 16, 2021
@gtsh
Copy link
Author

gtsh commented Feb 16, 2021

issue-25263.zip

Above ZIP contains a small Spring Boot Service, that on a
mvn clean spring-boot:run
will create a h2 database 'myh2db' in its directory, allowing accces using the h2 web console at http://localhost:8080/h2-console with user/password sa/sa - if and only if your spring-boot-parent is a 2.3.x -Version.

Changing the Version to 2.4.0 or above will still bring up the web console, but login fails.

For the sake of an experiment, you may also switch the version, then do a mvn spring-boot:run (without clean!).
This will attempt to login into the existing database, and will again fail with a login failure, if it was created with the other version configured as a parent.

Looks as if something weired is happening to the password on its way to the h2 database.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Feb 16, 2021
@snicoll
Copy link
Member

snicoll commented Feb 16, 2021

Thank you for the sample @gtsh

H2 has a setUser method (and, typically, doesn't have a setUsername method) so we should have an alias for that. It does not work because the binder no longer set the configured user.

We've refactored how those aliases are registered and this may have introduced a regression in that area.

@snicoll snicoll added type: regression A regression from a previous release and removed status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged labels Feb 16, 2021
@snicoll snicoll added this to the 2.4.3 milestone Feb 16, 2021
@snicoll
Copy link
Member

snicoll commented Feb 17, 2021

It's not really regression strictly speaking. The sample "forces" the datasource to be org.h2.jdbcx.JdbcDataSource and Spring Boot does not support this datasource (per the reference guide).

The regression comes from the fact that the user -> username alias was applied previously regardless of the database type and we're now more selective.

@gtsh can you share why you're forcing the type there? Neither app.datasource.myh2db.type nor app.datasource.myh2db.driver-class-name are necessary given that initializeDataSourceBuilder is going to take care of that for you and use a connection pool / driver that's suitable based on your classpath.

snicoll added a commit to snicoll/spring-boot that referenced this issue Feb 17, 2021
@snicoll snicoll changed the title H2 password problems after upgrade to Spring Boot 2.4.x DataSourceBuilder no longer invoke setUser on org.h2.jdbcx.JdbcDataSource Feb 17, 2021
@snicoll snicoll changed the title DataSourceBuilder no longer invoke setUser on org.h2.jdbcx.JdbcDataSource DataSourceBuilder no longer invokes setUser on org.h2.jdbcx.JdbcDataSource Feb 17, 2021
@snicoll
Copy link
Member

snicoll commented Feb 17, 2021

I've also created #25333 to make it clearer in the doc what DataSourceProperties#intializeDataSourceBuilder supports.

@gtsh
Copy link
Author

gtsh commented Feb 23, 2021

@gtsh can you share why you're forcing the type there? Neither app.datasource.myh2db.type nor app.datasource.myh2db.driver-class-name are necessary given that initializeDataSourceBuilder is going to take care of that for you and use a connection pool / driver that's suitable based on your classpath.

Forcing driver & datasource is what I've seen on next to every installation I have come across so far, whether it was Spring Boot or other (JEE DDs for that matter). Also, wanting to use Oracle UCP for production, I haven't much use for Hikari or C3P0, so I culled those from the classpath in order to shrink the distributable as well as to keep the classpath clean.
This left me with the H2-datasource as the only option for local development, and forcing it seemed sensible also, because the Oracle DS has been configured as default.
So you may say, I didn't knew better.

Anyway, many thanks for your prompt effort, I just managed to test it with 2.4.3, so this is working now as intended

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: regression A regression from a previous release
Projects
None yet
Development

No branches or pull requests

4 participants