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

Cannot deploy war file to Tomcat with mybatis-spring-boot on 3.0.0-SNAPSHOT #33325

Closed
kazuki43zoo opened this issue Nov 23, 2022 · 7 comments
Closed
Labels
status: declined A suggestion or change that we don't feel we should currently apply

Comments

@kazuki43zoo
Copy link
Contributor

kazuki43zoo commented Nov 23, 2022

When use the latest Spring Boot 3.0.0-SNAPSHOT together with mybatis-spring-boot 3.x(under development), we cannot deploy war file to the Tomcat 10. Until Spring Boot 3.0.0-RC2 it work fine.

Logs

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v3.0.0-SNAPSHOT)

2022-11-23T16:21:30.291+09:00  INFO 71116 --- [           main] s.mybatis.war.SampleWebApplication       : Starting SampleWebApplication using Java 17.0.1 with PID 71116 (/Users/shimizukazuki/git-me/spring-boot-starter/mybatis-spring-boot-samples/mybatis-spring-boot-sample-war/target/cargo/configurations/tomcat10x/webapps/mybatis-spring-boot-sample-war/WEB-INF/classes started by shimizukazuki in /Users/shimizukazuki/git-me/spring-boot-starter/mybatis-spring-boot-samples/mybatis-spring-boot-sample-war/target/cargo/configurations/tomcat10x)
2022-11-23T16:21:30.296+09:00  INFO 71116 --- [           main] s.mybatis.war.SampleWebApplication       : No active profile set, falling back to 1 default profile: "default"
2022-11-23T16:21:32.309+09:00  INFO 71116 --- [           main] .C.[.[.[/mybatis-spring-boot-sample-war] : Initializing Spring embedded WebApplicationContext
11月 23, 2022 4:21:32 午後 org.apache.catalina.core.ApplicationContext log
情報: Initializing Spring embedded WebApplicationContext
2022-11-23T16:21:32.313+09:00  INFO 71116 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1940 ms
2022-11-23T16:21:32.785+09:00  INFO 71116 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2022-11-23T16:21:33.322+09:00  INFO 71116 --- [           main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:ff60724f-b1e3-44a5-a108-6e4484a3d63b user=SA
2022-11-23T16:21:33.326+09:00  INFO 71116 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2022-11-23T16:21:33.463+09:00  WARN 71116 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cityRestController' defined in file [/Users/shimizukazuki/git-me/spring-boot-starter/mybatis-spring-boot-samples/mybatis-spring-boot-sample-war/target/cargo/configurations/tomcat10x/webapps/mybatis-spring-boot-sample-war/WEB-INF/classes/sample/mybatis/war/controller/CityRestController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'cityMapper' defined in file [/Users/shimizukazuki/git-me/spring-boot-starter/mybatis-spring-boot-samples/mybatis-spring-boot-sample-war/target/cargo/configurations/tomcat10x/webapps/mybatis-spring-boot-sample-war/WEB-INF/classes/sample/mybatis/war/mapper/CityMapper.class]: Cannot resolve reference to bean 'sqlSessionTemplate' while setting bean property 'sqlSessionTemplate'
2022-11-23T16:21:33.464+09:00  INFO 71116 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2022-11-23T16:21:33.467+09:00  INFO 71116 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
2022-11-23T16:21:33.484+09:00  INFO 71116 --- [           main] .s.b.a.l.ConditionEvaluationReportLogger : 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2022-11-23T16:21:33.548+09:00 ERROR 71116 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to bind properties under 'mybatis.configuration.environment' to org.apache.ibatis.mapping.Environment:

    Reason: java.lang.IllegalStateException: Failed to extract parameter names for public org.apache.ibatis.mapping.Environment(java.lang.String,org.apache.ibatis.transaction.TransactionFactory,javax.sql.DataSource)

Action:

Update your application's configuration
...
Caused by: org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties': Could not bind properties to 'MybatisProperties' : prefix=mybatis, ignoreInvalidFields=false, ignoreUnknownFields=true
	at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.bind(ConfigurationPropertiesBindingPostProcessor.java:92)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:78)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:420)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1743)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1405)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:880)
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:784)
	... 93 more
Caused by: org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'mybatis.configuration.environment' to org.apache.ibatis.mapping.Environment
	at org.springframework.boot.context.properties.bind.Binder.handleBindError(Binder.java:387)
	at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:347)
	at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:472)
	at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:98)
	at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:86)
	at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:62)
	at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:476)
	at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:590)
	at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:576)
	at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:474)
	at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:414)
	at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:343)
	at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:472)
	at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:98)
	at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:86)
	at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:62)
	at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:476)
	at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:590)
	at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:576)
	at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:474)
	at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:414)
	at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:343)
	at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:332)
	at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:262)
	at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:249)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.bind(ConfigurationPropertiesBinder.java:94)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.bind(ConfigurationPropertiesBindingPostProcessor.java:89)
	... 107 more
Caused by: java.lang.IllegalStateException: Failed to extract parameter names for public org.apache.ibatis.mapping.Environment(java.lang.String,org.apache.ibatis.transaction.TransactionFactory,javax.sql.DataSource)
	at org.springframework.util.Assert.state(Assert.java:97)
	at org.springframework.boot.context.properties.bind.ValueObjectBinder$DefaultValueObject.parseConstructorParameters(ValueObjectBinder.java:270)
	at org.springframework.boot.context.properties.bind.ValueObjectBinder$DefaultValueObject.<init>(ValueObjectBinder.java:264)
	at org.springframework.boot.context.properties.bind.ValueObjectBinder$DefaultValueObject.get(ValueObjectBinder.java:291)
	at org.springframework.boot.context.properties.bind.ValueObjectBinder$ValueObject.get(ValueObjectBinder.java:198)
	at org.springframework.boot.context.properties.bind.ValueObjectBinder.bind(ValueObjectBinder.java:67)
	at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:476)
	at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:590)
	at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:576)
	at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:474)
	at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:414)
	at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:343)
	... 132 more

Reproduce

Start the Tomcat server using argo plugin:

./mvnw clean package cargo:run -Dmaven.test.skip -Denforcer.skip=true -pl mybatis-spring-boot-samples/mybatis-spring-boot-sample-war

Access to API:

curl http://localhost:18080/mybatis-spring-boot-sample-war/cities/CA -D -
HTTP/1.1 404 
Content-Type: text/html;charset=utf-8
Content-Language: ja
Content-Length: 809
Date: Wed, 23 Nov 2022 07:32:51 GMT

<!doctype html><html lang="ja"><head><title>HTTPステータス 404 – 見つかりません。</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {fo} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTPステータス 404 – 見つかりません。</h1><hr class="lタイプ</b> ステータスレポート</p><p><b>説明</b> オリジンサーバーは、ターゲットリソースの現在の表現を見つけられなかったか、またはそれが存在することを開示するつもりはありません。</p><hr class="line" /><h3>Apache Tomcat

View container log file:

cat mybatis-spring-boot-samples/mybatis-spring-boot-sample-war/target/cargo/container.log

Downgrade to Spring Boot 3.0.0-RC2

Edit pom.xml stored the root directory as follow:

-    <spring-boot.version>3.0.0-SNAPSHOT</spring-boot.version>
+    <spring-boot.version>3.0.0-RC2</spring-boot.version>

Start the Tomcat server using argo plugin:

./mvnw clean package cargo:run -Dmaven.test.skip -Denforcer.skip=true -pl mybatis-spring-boot-samples/mybatis-spring-boot-sample-war

Access to API:

curl http://localhost:18080/mybatis-spring-boot-sample-war/cities/CA -D -
HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 23 Nov 2022 07:34:53 GMT

{"id":1,"name":"San Francisco","state":"CA","country":"US"}

Related issues

@wilkinsona
Copy link
Member

Thanks for trying the snapshots. Due to this change in Spring Framework that corrects an oversight in 6.0.0 you need to compile your code with -parameters.

@wilkinsona wilkinsona closed this as not planned Won't fix, can't repro, duplicate, stale Nov 23, 2022
@kazuki43zoo
Copy link
Contributor Author

@wilkinsona Thanks for your feedback!! I understand it!!

@wilkinsona
Copy link
Member

Looking more closely, MybatisProperties is using org.apache.ibatis.session.Configuration as a nested configuration property. Unfortunately, we don't really recommend binding to complex third-party types like this. Configuration has a getter and setter for org.apache.ibatis.mapping.Environment. To have configuration properties bound to this class, constructor binding must be used. The constructor's arguments are:

  • String
  • org.apache.ibatis.transaction.TransactionFactory
  • javax.sql.DataSource

Of these three arguments only String is a type that's suitable for configuration property binding. Both TransactionFactory and DataSource are interfaces so cannot be created from configuration properties.

I know it's quite a large amount of work but I would recommend that you stop trying to bind configuration properties directly to org.apache.ibatis.session.Configuration. Instead, you should bind to your own class designed specifically for configuration property binding and then create a Configuration instance using those properties. You can see an example of this in Boot's auto-configuration for Flyway.

This recommendation really applies for any version of Spring Boot as it makes configuration property binding more robust. Even if org.apache.ibatis.mapping.Environment had been compiled with -parameters, I would still recommend making these changes. In addition to addressing the problems described above, they allow you to control exactly what can and cannot be bound and for accurate metadata for the configuration properties to be generated. The recommendation becomes more important in 3.0 with the changes to parameter name discovery in Framework and also our GraalVM support.

@wilkinsona wilkinsona added status: declined A suggestion or change that we don't feel we should currently apply and removed status: waiting-for-triage An issue we've not yet triaged labels Nov 23, 2022
@kazuki43zoo
Copy link
Contributor Author

@wilkinsona Thanks for your advice!! We consider to rewrite a recommended style's code as soon as possible.

@kazuki43zoo
Copy link
Contributor Author

NOTE: Compile the mybatis core module with -parameters, it worked fine.

@snicoll
Copy link
Member

snicoll commented Nov 23, 2022

@kazuki43zoo thank you so much for testing the snapshot and reporting the issue.

@wilkinsona
Copy link
Member

@kazuki43zoo We've refined things in Spring Framework based on your feedback: spring-projects/spring-framework#29531, deferring the removal of LocalVariableTableParameterNameDiscoverer until Framework 6.1. This means that things will work as they did before without -parameters, albeit with a warning being logged each time parameter name discovery relies upon LocalVariableTableParameterNameDiscoverer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests

4 participants