[MAGNOLIA-6440] Duplicated resources on classpath may prevent magnolia from start with a NPE Created: 15/Nov/15 Updated: 11/Mar/16 Resolved: 04/Mar/16 |
|
| Status: | Closed |
| Project: | Magnolia |
| Component/s: | None |
| Affects Version/s: | 5.4.1, 5.4.2, 5.4.3 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major |
| Reporter: | Fabrizio Giustina | Assignee: | Unassigned |
| Resolution: | Obsolete | Votes: | 0 |
| Labels: | papercut | ||
| Remaining Estimate: | 1d | ||
| Time Spent: | 7d 4.5h | ||
| Original Estimate: | 5d | ||
| Issue Links: |
|
||||||||||||||||
| Template: |
|
||||||||||||||||
| Acceptance criteria: |
Empty
|
||||||||||||||||
| Task DoD: |
[ ]*
Doc/release notes changes? Comment present?
[ ]*
Downstream builds green?
[ ]*
Solution information and context easily available?
[ ]*
Tests
[ ]*
FixVersion filled and not yet released
[ ] 
Architecture Decision Record (ADR)
|
||||||||||||||||
| Bug DoR: |
[ ]*
Steps to reproduce, expected, and actual results filled
[ ]*
Affected version filled
|
||||||||||||||||
| Date of First Response: | |||||||||||||||||
| Sprint: | Basel 34 | ||||||||||||||||
| Story Points: | 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:
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. |
| Comments |
| Comment by Ngoc Nguyenthanh [ 19/Nov/15 ] |
|
Steps to get the error:
|
| Comment by Ngoc Nguyenthanh [ 20/Nov/15 ] |
|
We have 2 class-paths
When we collect resources from class-paths info.magnolia.resourceloader.classpath.ClasspathResourceOrigin#collectResources by using org.reflections.Reflections#getResources. The method will return a Set<String> contains 2 paths above. |
| Comment by Ngoc Nguyenthanh [ 20/Nov/15 ] |
|
mgeljic Phew, The issue related to class paths, even the order of the paths list. |
| Comment by Ngoc Nguyenthanh [ 01/Dec/15 ] |
|
I fixed by:
|
| Comment by Ngoc Nguyenthanh [ 05/Jan/16 ] |
|
Copying comments from PR mgeljic equals() and hashCode() on ClasspathResource should be covered already with Lombok annotation @EqualsAndHashCode, but always worth double-checking/testing |
| Comment by Mikaël Geljić [ 04/Feb/16 ] |
|
Current progress was declined in favor of bigger fundamental changes in classpath resource-loading. Linking to related issue and reopening until we verify that the new implementation handles this case gracefully. |
| Comment by Mikaël Geljić [ 04/Mar/16 ] |
|
Closing that one as new implementation doesn't fail (it actually ignores the overlapping sub-directories, which is wrong as well)—see follow-up issue |