[MAGNOLIA-6442] Guice context initialization doesn't handle dependency problems/runtime exceptions properly Created: 16/Nov/15 Updated: 01/Jul/21 Resolved: 08/Jun/21 |
|
| Status: | Closed |
| Project: | Magnolia |
| Component/s: | None |
| Affects Version/s: | 5.4.1, 5.4.3, 5.5.5, 5.5.6, 5.5.7 |
| Fix Version/s: | 5.7.11, 6.2.10 |
| Type: | Bug | Priority: | Critical |
| Reporter: | Fabrizio Giustina | Assignee: | Oanh Thai Hoang |
| Resolution: | Fixed | Votes: | 14 |
| Labels: | VN-Implementation, maintenance, papercut | ||
| Remaining Estimate: | 0d | ||
| Time Spent: | 3.25h | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||
| Template: |
|
||||
| Patch included: |
Yes
|
||||
| Acceptance criteria: |
Empty
|
||||
| Task DoD: |
[X]*
Doc/release notes changes? Comment present?
[X]*
Downstream builds green?
[Federico Grilli]
[X]*
Solution information and context easily available?
[X]*
Tests
[X]*
FixVersion filled and not yet released
[ ] 
Architecture Decision Record (ADR)
|
||||
| Bug DoR: |
[X]*
Steps to reproduce, expected, and actual results filled
[X]*
Affected version filled
|
||||
| Release notes required: |
Yes
|
||||
| Date of First Response: | |||||
| Sprint: | Maintenance 61, Maintenance 62 | ||||
| Story Points: | 3 | ||||
| Description |
|
Use case: build a magnolia webapp with a missing dependency which should be used by module (e.g. take the enterprise webapp bundle and remove the geoip2-0.7.0 jar used by the personalization module). Try to start magnolia and the error log you will get is: ERROR info.magnolia.init.MagnoliaServletContextListener contextInitialized (MagnoliaServletContextListener.java:177) Oops, Magnolia could not be started java.lang.NullPointerException at info.magnolia.objectfactory.guice.GuiceUtils.hasExplicitBindingFor(GuiceUtils.java:155) at info.magnolia.objectfactory.guice.GuiceComponentProvider.getComponent(GuiceComponentProvider.java:99) at info.magnolia.objectfactory.Components.getComponent(Components.java:97) at info.magnolia.context.ContextFactory.getInstance(ContextFactory.java:72) at info.magnolia.context.MgnlContext.getSystemContext(MgnlContext.java:368) at info.magnolia.context.MgnlContext.release(MgnlContext.java:629) at info.magnolia.context.MgnlContext.doInSystemContext(MgnlContext.java:395) at info.magnolia.init.MagnoliaServletContextListener.startServer(MagnoliaServletContextListener.java:247) at info.magnolia.init.MagnoliaServletContextListener.contextInitialized(MagnoliaServletContextListener.java:173) at info.magnolia.init.MagnoliaServletContextListener.contextInitialized(MagnoliaServletContextListener.java:127) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4992) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5490) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) No clue about what's wrong, no info about missing classes... just a non-initialized context which has not been loaded for some reason, really hard to debug. In order to provide a meaningful feedback I would change the build() method in GuiceComponentProviderBuilder which only catches CreationException: try
{
Injector injector = Guice.createInjector(resolveStageToUse(), module);
return (GuiceComponentProvider) injector.getInstance(ComponentProvider.class);
}
catch (CreationException e)
{
log.error(
"Magnolia failed to load module configuration with types " + configuration
.getTypeMapping() + " and components " + configuration
.getComponents() + ". Please ensure you don't have any legacy modules present in your web application.",
e);
throw e;
}
with a catch-all ( catch (Throwable e) )... with this patch the error is definitively more useful (NB the original uncatched exception seemed to be swallowed somewhere): ERROR info.magnolia.objectfactory.guice.GuiceComponentProviderBuilder build (GuiceComponentProviderBuilder.java:177) Magnolia failed to load module configuration with types [...] com.google.inject.internal.util.$ComputationException: com.google.inject.internal.util.$ComputationException: java.lang.NoClassDefFoundError: Lcom/maxmind/geoip2/DatabaseReader; at com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:553) at com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:419) at com.google.inject.internal.util.$CustomConcurrentHashMap$ComputingImpl.get(CustomConcurrentHashMap.java:2041) at com.google.inject.internal.FailableCache.get(FailableCache.java:50) at com.google.inject.internal.ConstructorInjectorStore.get(ConstructorInjectorStore.java:49) at com.google.inject.internal.ConstructorBindingImpl.initialize(ConstructorBindingImpl.java:125) at com.google.inject.internal.InjectorImpl.initializeBinding(InjectorImpl.java:507) at com.google.inject.internal.AbstractBindingProcessor$Processor$1.run(AbstractBindingProcessor.java:159) at com.google.inject.internal.ProcessedBindingData.initializeBindings(ProcessedBindingData.java:44) at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:122) at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:106) at com.google.inject.Guice.createInjector(Guice.java:95) at com.google.inject.Guice.createInjector(Guice.java:83) at info.magnolia.objectfactory.guice.GuiceComponentProviderBuilder.build(GuiceComponentProviderBuilder.java:171) at info.magnolia.objectfactory.guice.GuiceComponentProviderBuilder.build(GuiceComponentProviderBuilder.java:189) at info.magnolia.cms.beans.config.ConfigLoader.load(ConfigLoader.java:153) at info.magnolia.init.MagnoliaServletContextListener$1.doExec(MagnoliaServletContextListener.java:250) at info.magnolia.context.MgnlContext$VoidOp.exec(MgnlContext.java:421) at info.magnolia.context.MgnlContext$VoidOp.exec(MgnlContext.java:418) at info.magnolia.context.MgnlContext.doInSystemContext(MgnlContext.java:392) at info.magnolia.init.MagnoliaServletContextListener.startServer(MagnoliaServletContextListener.java:247) at info.magnolia.init.MagnoliaServletContextListener.contextInitialized(MagnoliaServletContextListener.java:173) at info.magnolia.init.MagnoliaServletContextListener.contextInitialized(MagnoliaServletContextListener.java:127) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4992) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5490) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) The current behavior could really be a problem for many users, especially for anybody not using maven or integrating magnolia in complex webapps... |
| Comments |
| Comment by Frank Sommer [ 05/Jul/16 ] |
|
I don't need the location trait, so I want to exclude the geoip library. It works in Magnolia 5.3.14. Why not in M5.4.7? |
| Comment by Thomas Duffey [ 06/Aug/20 ] |
|
This would be a welcome small change in 6.x as well where I just spent hours tracking down why Magnolia wouldn't start. |
| Comment by Ji Yang [ 04/Dec/20 ] |
|
Ya, I have the same problem in the latest version. The build() method is only handling CreationException, the rest of exception and useful information is just swallowed by the program. Also in class GuiceUtils, method hasExplicitBindingFor(), should we check the target==null at the first step? The NullPointerException always happens like this, basic mistake in java programming: public static boolean hasExplicitBindingFor(Injector injector, Key<?> key) { |
| Comment by Oanh Thai Hoang [ 16/Jun/21 ] |
|
Hi akhamis, Here is the solution for this ticket.
|