cannot start in PROD mode when assigning port explicitly with ebean
See original GitHub issuePlay Version (2.5.x / etc)
2.5.x
API (Scala / Java / Neither / Both)
Java
Operating System (Ubuntu 15.10 / MacOS 10.10 / Windows 10)
CentOS 7
JDK (Oracle 1.8.0_72, OpenJDK 1.8.x, Azul Zing)
openJDK 1.8.x
Library Dependencies
ebean
Expected Behavior
when I run:
applicationName/target/universal/stage/bin/applicationName -Dconfig.resource=production.conf -Dplay.evolutions.db.default.autoApply=true
The application works well.
However, when I run:
applicationName/target/universal/stage/bin/applicationName -Dhttp.port=9000 -Dconfig.resource=production.conf -Dplay.evolutions.db.default.autoApply=true
application cannot start.
Please describe the expected behavior of the issue, starting from the first action.
Actual Behavior
[error] c.a.ebean.Ebean - Error trying to create the default EbeanServer
java.lang.RuntimeException: DataSource user is null?
at org.avaje.datasource.pool.ConnectionPool.<init>(ConnectionPool.java:204)
at org.avaje.datasource.Factory.createPool(Factory.java:12)
at com.avaje.ebeaninternal.server.core.DefaultContainer.getDataSourceFromConfig(DefaultContainer.java:309)
at com.avaje.ebeaninternal.server.core.DefaultContainer.setDataSource(DefaultContainer.java:262)
at com.avaje.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:105)
at com.avaje.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:77)
at com.avaje.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:44)
at com.avaje.ebean.EbeanServerFactory.create(EbeanServerFactory.java:55)
at com.avaje.ebean.Ebean$ServerManager.getWithCreate(Ebean.java:201)
at com.avaje.ebean.Ebean$ServerManager.<init>(Ebean.java:159)
Oops, cannot start the server.
com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Error injecting constructor, java.lang.NoClassDefFoundError: Could not initialize class com.avaje.ebean.Ebean
at play.db.ebean.EbeanDynamicEvolutions.<init>(EbeanDynamicEvolutions.java:55)
at play.db.ebean.EbeanDynamicEvolutions.class(EbeanDynamicEvolutions.java:44)
while locating play.db.ebean.EbeanDynamicEvolutions
at play.db.ebean.EbeanModule.bindings(EbeanModule.java:24):
Binding(class play.api.db.evolutions.DynamicEvolutions to ConstructionTarget(class play.db.ebean.EbeanDynamicEvolutions) eagerly) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
while locating play.api.db.evolutions.DynamicEvolutions
Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.avaje.ebean.Ebean
at com.avaje.ebean.EbeanServerFactory.create(EbeanServerFactory.java:73)
at play.db.ebean.EbeanDynamicEvolutions.lambda$start$2(EbeanDynamicEvolutions.java:118)
at java.util.HashMap.forEach(HashMap.java:1288)
at play.db.ebean.EbeanDynamicEvolutions.start(EbeanDynamicEvolutions.java:114)
at play.db.ebean.EbeanDynamicEvolutions.<init>(EbeanDynamicEvolutions.java:58)
at play.db.ebean.EbeanDynamicEvolutions$$FastClassByGuice$$52c94231.newInstance(<generated>)
at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40)
at com.google.inject.internal.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:61)
at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:105)
at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85)
at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:267)
at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103)
at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:145)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:56)
at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103)
at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:145)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:205)
at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:199)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092)
at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:199)
at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:180)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110)
at com.google.inject.Guice.createInjector(Guice.java:96)
at com.google.inject.Guice.createInjector(Guice.java:84)
at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:181)
at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:123)
at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
at play.core.server.ProdServerStart$.start(ProdServerStart.scala:47)
at play.core.server.ProdServerStart$.main(ProdServerStart.scala:22)
at play.core.server.ProdServerStart.main(ProdServerStart.scala)
Issue Analytics
- State:
- Created 7 years ago
- Reactions:6
- Comments:35 (8 by maintainers)
Top Results From Across the Web
Play framework 2.3 - cannot start in production - Stack Overflow
This is a known issue caused by long variables beying generated when the project directory structure is too long.
Read more >Play Change Log
Ebean is (also) its own project! HikariCP is the default connection pool; WS supports Server Name Identification (SNI). Highlights · Migration Guide ·...
Read more >sbt Reference Manual — Combined Pages
You can also run sbt in batch mode, passing sbt commands directly from the ... Note: You cannot have a project subdirectory or...
Read more >3.12 - The history of jOOQ. From 2009 to 2022
#9287, Parser cannot handle enum literals that are invalid java ... This is why, starting from jOOQ 3.12, we are now offering some...
Read more >Modern Best Practices for Testing in Java - Philipp Hauer's Blog
Write dumb tests by avoiding the reuse of production code and ... Moreover, you can easily run into situations where you can't use...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Essentially it’s not loading the EbeanDynamicEvolutions if you create your repository class like this you can make it work
` private final EbeanServer ebeanServer; private final DatabaseExecutionContext executionContext; private final EbeanDynamicEvolutions ebeanDynamicEvolutions;
`
Taken from in here :: https://github.com/playframework/play-ebean/issues/51
After banging my head against this issue for way too long, I have a theory. This is running play 2.6.7, but I think it probably applies to earlier versions as well.
The
DataSource user is null?
message gets printed when creating anEbeanServer
.EbeanServer
instances are created, and registered, through the staticEbean
class.The Play framework (at least in most examples) tries to create EbeanServers according to application config in
EbeanDynamicEvolutions
. This happens in the constructor, which is called by Guice (again, at least in most examples).The thing that I think bites many people is that the examples,
Ebean.getServer(name)
is called in the constructor of Repository classes (e.g. CompanyRepository.java). This is again, called by Guice. The important thing here is that thegetServer(name)
method will try to create the ebean server if it does not exist.Since, afaik, Guice has no pre-defined order when instantiating classes, the repository class might be created before the
EbeanDynamicEvolutions
instance. This leads to the repository class trying to create a server without any config, and thus the error. Since this depends on the rather arbitrary guice injection order + timing, a lot of the weird ‘causes’ in the comments above kind of makes sense.I have been able to make this error stop happening by starting to use the
Ebean.getServer(name)
when accessing the database, instead of in repository constructors. E.g:I believe that either the docs should be updated with this, or that the race condition at DI should be resolved somehow. I don’t know which though 😉