grails-database-migration icon indicating copy to clipboard operation
grails-database-migration copied to clipboard

provide an alternative name for the --dataSource argument

Open zyro23 opened this issue 6 years ago • 0 comments

Task List

  • [x] Steps to reproduce provided
  • [x] Stacktrace (if present) provided
  • [ ] Example that reproduces the problem uploaded to Github
  • [x] Full description of the issue provided (see below)

Steps to Reproduce

  1. try to run a dbmGormDiff via gradle with -Pargs=--dataSource=mySecondDs
  2. see stacktrace

Expected Behaviour

no exception

Actual Behaviour

  • the --dataSource arg is processed by CommandLinePropertySource which is added by SpringApplication#configurePropertySources by default
    • https://github.com/spring-projects/spring-boot/blob/v2.1.10.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java#L496-L497
  • so, --dataSource actually overrides the dataSource configuration for the primary dataSource with a string
  • and that again results in the follwing stacktrace because the dataSource config is now broken
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.grails.orm.hibernate.HibernateDatastore]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: wrong number of arguments
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:184)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:300)
	... 101 common frames omitted
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282)
	at org.grails.datastore.mapping.config.ConfigurationBuilder.buildRecurse(ConfigurationBuilder.groovy:360)
	at org.grails.datastore.mapping.config.ConfigurationBuilder.buildRecurse(ConfigurationBuilder.groovy:286)
	at org.grails.datastore.mapping.config.ConfigurationBuilder.buildRecurse(ConfigurationBuilder.groovy:286)
	at org.grails.datastore.mapping.config.ConfigurationBuilder.buildInternal(ConfigurationBuilder.groovy:111)
	at org.grails.datastore.mapping.config.ConfigurationBuilder.build(ConfigurationBuilder.groovy:92)
	at org.grails.orm.hibernate.connections.HibernateConnectionSourceSettingsBuilder.build(HibernateConnectionSourceSettingsBuilder.groovy:37)
	at org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory.buildSettings(AbstractHibernateConnectionSourceFactory.java:70)
	at org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory.buildSettings(AbstractHibernateConnectionSourceFactory.java:23)
	at org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory.create(AbstractConnectionSourceFactory.java:63)
	at org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory.create(AbstractConnectionSourceFactory.java:52)
	at org.grails.datastore.mapping.core.connections.ConnectionSourcesInitializer.create(ConnectionSourcesInitializer.groovy:24)
	at org.grails.orm.hibernate.HibernateDatastore.<init>(HibernateDatastore.java:200)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:172)
	... 103 common frames omitted

misc

  • unfortunately, there is no way to use SpringApplication#setAddCommandLineProperties(false) because GrailsApplicationContextCommandRunner does not allow customization
    • https://github.com/spring-projects/spring-boot/blob/v2.1.10.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java#L993
    • https://github.com/grails/grails-core/blob/v4.0.1/grails-console/src/main/groovy/grails/ui/command/GrailsApplicationContextCommandRunner.groovy#L55

i guess there are two more or less obvious solutions to this issue:

  • add an alternative name to --dataSource like --dbmDataSource
    • this change would be within this plugin
  • or: support GrailsApplicationContextCommandRunner customization
    • that would have to happen in grails-core

workaround

using the grails shell/cli directly. that does not use GrailsApplicationContextCommandRunnerbut invokes the command class directly. however, the grails-cli has other issues like it is non-trivial to pass system properties along.

ideally, it should be possible to use the database-migration plugin with gradle only, not having a need for the grails shell/cli at all.

Environment Information

  • Operating System: winx64
  • Grails Version: 4.0.1
  • Plugin Version: 3.0.4
  • Database: postgresql-12
  • JDK Version: openjdk-11

Example Application

n/a

zyro23 avatar Nov 11 '19 20:11 zyro23