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

Duplicated resources on classpath may prevent magnolia from start with a NPE

    XMLWordPrintable

Details

    • Bug
    • Resolution: Obsolete
    • Major
    • None
    • 5.4.1, 5.4.2, 5.4.3
    • None
    • Basel 34
    • 8

    Description

      ... this can really be an headache for many users: if there are 2 classpath resources with the same name, one pointing to a directory and one to a file magnolia initialization fails with a NPE and without any useful message that could help to diagnose the problem.

      Sample test to reproduce the problem:

      • add a file named "test" to a jar/module
      • add a folder named "test" in WEB-INF/classes

      Magnolia will not start anymore with the following stacktrace:

      ERROR MagnoliaServletContextListener (MagnoliaServletContextListener.java:177) Oops, Magnolia could not be started
      com.google.inject.CreationException: Guice creation errors:
      
      1) Error injecting constructor, java.lang.NullPointerException
        at info.magnolia.resourceloader.DefaultResourceOrigins.<init>(DefaultResourceOrigins.java:64)
        at info.magnolia.resourceloader.DefaultResourceOrigins.class(DefaultResourceOrigins.java:52)
        while locating info.magnolia.resourceloader.DefaultResourceOrigins
      
      1 error
      	at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:435)
      	at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:183)
      	at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:109)
      	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:145)
      	at info.magnolia.objectfactory.guice.GuiceComponentProviderBuilder.build(GuiceComponentProviderBuilder.java:155)
      	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:4939)
      	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
      	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
      	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
      	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
      	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
      	at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:656)
      	at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1635)
      	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
      	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      	at java.lang.Thread.run(Thread.java:745)
      Caused by: java.lang.NullPointerException
      	at info.magnolia.resourceloader.classpath.ClasspathResource.addChild(ClasspathResource.java:125)
      	at info.magnolia.resourceloader.classpath.ClasspathResource.setParent(ClasspathResource.java:99)
      	at info.magnolia.resourceloader.classpath.ClasspathResourceOrigin.createResourcesFor(ClasspathResourceOrigin.java:330)
      	at info.magnolia.resourceloader.classpath.ClasspathResourceOrigin.collectResources(ClasspathResourceOrigin.java:229)
      	at info.magnolia.resourceloader.classpath.ClasspathResourceOrigin.<init>(ClasspathResourceOrigin.java:100)
      	at info.magnolia.resourceloader.classpath.ClasspathResourceOriginFactory.create(ClasspathResourceOriginFactory.java:18)
      	at info.magnolia.resourceloader.DefaultResourceOrigins.<init>(DefaultResourceOrigins.java:70)
      	at info.magnolia.resourceloader.DefaultResourceOrigins$$FastClassByGuice$$6454fe2d.newInstance(<generated>)
      	at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40)
      	at com.google.inject.internal.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:60)
      	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85)
      	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
      	at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
      	at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031)
      	at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
      	at com.google.inject.Scopes$1$1.get(Scopes.java:65)
      	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
      	at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:204)
      	at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:198)
      	at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024)
      	at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:198)
      	at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:179)
      	... 26 more
      

      Depending on the order of the resource loaded the error may be more informative, when the directory is loaded before the file you get something like:

      2015-11-15 12:02:34,463 ERROR ModuleManagerImpl (ModuleManagerImpl.java:380) Can't start module rendering
      java.lang.IllegalArgumentException: Multiple entries with same key: /LICENSE=ClasspathResource{origin=classpath,path=/LICENSE,(directory)} and /LICENSE=ClasspathResource{origin=classpath,path=/LICENSE,file}
      

      The first situation (file caught first) is definitively more problematic since it's really hard to debug... and unfortunately it may happen pretty easily if you have any dependency which contains files in the root folder.

      Checklists

        Acceptance criteria

        Attachments

          Issue Links

            Activity

              People

                Unassigned Unassigned
                fgiust Fabrizio Giustina
                Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:

                  Checklists

                    Bug DoR
                    Task DoD

                    Time Tracking

                      Estimated:
                      Original Estimate - 5d Original Estimate - 5d
                      5d
                      Remaining:
                      Time Spent - 7d 4.5h Remaining Estimate - 1d
                      1d
                      Logged:
                      Time Spent - 7d 4.5h Remaining Estimate - 1d
                      7d 4.5h