Uploaded image for project: 'Magnolia'
  1. Magnolia
  2. MAGNOLIA-6442

Guice context initialization doesn't handle dependency problems/runtime exceptions properly

XMLWordPrintable

    • Yes
    • Yes
    • Maintenance 61, Maintenance 62
    • 3

      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...

        Acceptance criteria

              oanh.thai Oanh Thai Hoang
              fgiust Fabrizio Giustina
              Votes:
              14 Vote for this issue
              Watchers:
              15 Start watching this issue

                Created:
                Updated:
                Resolved:

                  Bug DoR
                  Task DoD

                    Estimated:
                    Original Estimate - Not Specified
                    Not Specified
                    Remaining:
                    Remaining Estimate - 0d
                    0d
                    Logged:
                    Time Spent - 3.25h
                    3.25h