bootique / bootique-jetty

Provides Jetty integration with Bootique

Home Page:https://bootique.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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)