This is probably a quirk of TeamCity, Spring and classpaths, but I thought I'd try here first in case there was a suggestion on how to work around this.
Is there a way to tell eBean about DataSource classes, in a similar way to how models are specified?
Or is there other suggestions on how to make the server aware of the provided jar?
Long story.I am developing a plugin for the TeamCity (TC) build server. TC has an API which is based on Spring. The plugin will be installed on user's servers, and I don't know in advance where the H2 file be will stored, so I am
building the DataSourceConfig from a combination of Spring injected plugin location, and
ebean.properties using the following code...
ServerConfig config = new ServerConfig();
config.setName("db");
config.loadFromProperties();
DataSourceConfig dsConfig = config.getDataSourceConfig();
dsConfig.setUrl(
"jdbc:h2:file:" + myDataDir.getAbsolutePath() + File.separator + "tcDebRepositoryDB;DB_CLOSE_ON_EXIT=FALSE");
config.setDataSourceConfig(dsConfig); The
EbeanServer is instantiated by
Spring's XML configuration (which is started by Teamcity's plugin manager somehow).
My
junit test runs fine in junit's classpath, but loading the plugin inside TC gives the following stack trace.
Caused by: java.lang.IllegalStateException: No DataSourceFactory service implementation found in class path. Probably missing dependency to avaje-datasource?
at com.avaje.ebeaninternal.server.core.DefaultContainer.getDataSourceFromConfig(DefaultContainer.java:288)
at com.avaje.ebeaninternal.server.core.DefaultContainer.setDataSource(DefaultContainer.java:252)
at com.avaje.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:97)
at com.avaje.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:42)
at com.avaje.ebean.EbeanServerFactory.createInternal(EbeanServerFactory.java:108)
at com.avaje.ebean.EbeanServerFactory.create(EbeanServerFactory.java:67)
at debrepo.teamcity.ebean.server.EbeanServerProvider.createEbeanServerInstance(EbeanServerProvider.java:56)
at debrepo.teamcity.ebean.server.EbeanServerProvider.<init>(EbeanServerProvider.java:19)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
So I explicitly added avaje-datasource to the
maven POM.
<dependency>
<groupId>org.avaje</groupId>
<artifactId>avaje-datasource</artifactId>
<version>1.1.4</version>
</dependency>But, that has not made any difference. Full stacktrace follows.
ERROR - gins.spring.SpringPluginLoader - Failed to initialize spring context for plugin tcdebrepo
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ebeanServerProvider' defined in Byte array resource [plugin: tcdebrepo#tcdebrepo-server-1.0-SNAPSHOT.jar!/META-INF/build-server-plugin-tcdebrepo.xml]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [debrepo.teamcity.ebean.server.EbeanServerProvider]: Constructor threw exception; nested exception is java.lang.IllegalStateException: No DataSourceFactory service implementation found in class path. Probably missing dependency to avaje-datasource?
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:275)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at jetbrains.buildServer.plugins.spring.SpringPluginLoader.pluginClassesLoaded(SpringPluginLoader.java:95)
at sun.reflect.GeneratedMethodAccessor59.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at jetbrains.buildServer.util.EventDispatcher.dispatch(EventDispatcher.java:121)
at jetbrains.buildServer.util.EventDispatcher$2.invoke(EventDispatcher.java:68)
at com.sun.proxy.$Proxy16.pluginClassesLoaded(Unknown Source)
at jetbrains.buildServer.plugins.PluginManagerImpl$2.visitPlugin(PluginManagerImpl.java:140)
at jetbrains.buildServer.plugins.PluginsCollection.foreachLoadedPlugins(PluginsCollection.java:222)
at jetbrains.buildServer.plugins.PluginManagerImpl.firePluginClassesLoaded(PluginManagerImpl.java:138)
at jetbrains.buildServer.plugins.PluginManagerImpl.loadPlugins(PluginManagerImpl.java:84)
at jetbrains.buildServer.web.plugins.PluginManagerConfigurator.initializePlugins(PluginManagerConfigurator.java:9)
at jetbrains.buildServer.web.impl.BuildServerConfigurator.loadConfiguration(BuildServerConfigurator.java:68)
at java.util.concurrent.CopyOnWriteArrayList.forEach(CopyOnWriteArrayList.java:890)
at jetbrains.buildServer.serverSide.impl.BuildServerLifecycleProcessor.doStartup(BuildServerLifecycleProcessor.java:30)
at jetbrains.buildServer.maintenance.TeamCityDispatcherServlet$WebApplicationCreatorAndDestroyer.createApplication(TeamCityDispatcherServlet.java:25)
at jetbrains.buildServer.maintenance.StartupProcessor.doApplicationStarting(StartupProcessor.java:141)
at jetbrains.buildServer.maintenance.StartupProcessor.processConcreteStage(StartupProcessor.java:556)
at jetbrains.buildServer.maintenance.StartupProcessor.processConcreteStageSafe(StartupProcessor.java:744)
at jetbrains.buildServer.maintenance.StartupProcessor.processTeamCityLifecycle(StartupProcessor.java:811)
at jetbrains.buildServer.maintenance.StartupProcessor.access$000(StartupProcessor.java:15)
at jetbrains.buildServer.maintenance.StartupProcessor$1.run(StartupProcessor.java:2)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [debrepo.teamcity.ebean.server.EbeanServerProvider]: Constructor threw exception; nested exception is java.lang.IllegalStateException: No DataSourceFactory service implementation found in class path. Probably missing dependency to avaje-datasource?
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:122)
at jetbrains.buildServer.spring.InstantiationStrategySelector$1.instantiate(InstantiationStrategySelector.java:77)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:267)
... 34 more
Caused by: java.lang.IllegalStateException: No DataSourceFactory service implementation found in class path. Probably missing dependency to avaje-datasource?
at com.avaje.ebeaninternal.server.core.DefaultContainer.getDataSourceFromConfig(DefaultContainer.java:288)
at com.avaje.ebeaninternal.server.core.DefaultContainer.setDataSource(DefaultContainer.java:252)
at com.avaje.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:97)
at com.avaje.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:42)
at com.avaje.ebean.EbeanServerFactory.createInternal(EbeanServerFactory.java:108)
at com.avaje.ebean.EbeanServerFactory.create(EbeanServerFactory.java:67)
at debrepo.teamcity.ebean.server.EbeanServerProvider.createEbeanServerInstance(EbeanServerProvider.java:56)
at debrepo.teamcity.ebean.server.EbeanServerProvider.<init>(EbeanServerProvider.java:19)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
... 37 more