JettyTester should not cause eager initalization
andrus opened this issue · comments
JettyTester currently calls initOnStartup()
on Jetty, causing full stack initialization. Depending on how the app is written, it may trigger premature initialization of the full stack of services, way before other BQTestTool
tools are ready (e.g. DbTester
), causing exceptions.
For now the workaround is to wrap failing services in Providers
so that they themselves are initialized lazily. But this puts the burden on the app users, and is not ideal.
Upgrade Notes
The fix is implemented internally via command decoration. This changes the behavior of JettyTester
. Now you can only call JettyTester.getUrl()
or JettyTester.getPort()
when the app is actually started with --server
command. Previously these methods worked on test runtimes before they were started. The new behavior is correct, and the old one was not, and this change should not affect normal uses.
Exception
[7] resolving key <BindingKey: java.util.Set[io.bootique.jetty.MappedServlet]>
-> Resolving set element 0
[8] resolving key <BindingKey: io.bootique.jetty.server.ServerHolder>
-> Get argument 2 for provider method 'provideServerHolder()' of module 'io.bootique.jetty.JettyModule'
[9] resolving key <BindingKey: io.bootique.jetty.junit5.tester.JettyTesterBootiqueHook>
-> Injecting field 'serverHolder' of class io.bootique.jetty.junit5.tester.JettyTesterBootiqueHookProvider
Caused by: org.apache.cayenne.configuration.server.DataDomainLoadException:
[v.4.1 Jul 14 2020 10:26:08] DataDomain startup failed: 'dbUrl' not initialized. Called outside of JUnit lifecycle?
at org.apache.cayenne.configuration.server.DataDomainProvider.get(DataDomainProvider.java:123)
at org.apache.cayenne.configuration.server.DataDomainProvider.get(DataDomainProvider.java:60)
at org.apache.cayenne.di.spi.CustomProvidersProvider.get(CustomProvidersProvider.java:39)
at org.apache.cayenne.di.spi.FieldInjectingProvider.get(FieldInjectingProvider.java:43)
at org.apache.cayenne.di.spi.DefaultScopeProvider.get(DefaultScopeProvider.java:50)
at org.apache.cayenne.di.spi.DefaultInjector.getInstance(DefaultInjector.java:139)
...
Caused by: java.lang.NullPointerException: 'dbUrl' not initialized. Called outside of JUnit lifecycle?
at java.util.Objects.requireNonNull(Objects.java:228)
at io.bootique.jdbc.junit5.datasource.DataSourceHolder.getDbUrl(DataSourceHolder.java:77)
at io.bootique.jdbc.junit5.DbTester.getDbUrl(DbTester.java:69)
at io.bootique.jdbc.junit5.tester.TestDataSourceFactory.lambda$create$0(TestDataSourceFactory.java:48)
at io.bootique.jdbc.managed.ManagedDataSourceStarter.getUrl(ManagedDataSourceStarter.java:49)
at io.bootique.jdbc.LazyDataSourceFactory.createManagedDataSource(LazyDataSourceFactory.java:90)
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
at io.bootique.jdbc.LazyDataSourceFactory.forName(LazyDataSourceFactory.java:65)
at io.bootique.cayenne.v41.BQCayenneDataSourceFactory.mappedBootiqueDataSource(BQCayenneDataSourceFactory.java:130)
at io.bootique.cayenne.v41.BQCayenneDataSourceFactory.mappedBootiqueDataSource(BQCayenneDataSourceFactory.java:121)
at io.bootique.cayenne.v41.BQCayenneDataSourceFactory.getDataSource(BQCayenneDataSourceFactory.java:58)