Details
Description
this bug still exists since early alphas, as seen in MNG-3379.
customConverters is not synchronized, making the converter lookup class itself not threadsafe since this is used concurrently in two methods:
- registerConverter
- lookupConverterForType
This flows on to BasicComponentConfigurator, which calls in sequence:
converterLookup.registerConverter( new ClassRealmConverter( containerRealm ) );
and:
converter.processConfiguration( converterLookup, component, containerRealm.getClassLoader(), configuration,
expressionEvaluator, listener );
so the configureComponent method itself cannot be called concurrently. However, BasicComponentConfigurator is a singleton.
synchronizing the custom converters would help but I don't think that's correct.
the problem is more in the BasicComponentConfigurator that registers a converter permanently for a classrealm that was only passed in to that method. It should instead pass the custom converters into the lookup method and remove the permanent one - or the lookup should be instantiated each time.
Would this issue result in a stack trace like this one below? This is from Apache Geronimo but I would say we get this error once every couple hundred builds at my company (and we run more than a couple hundred builds every week). The stack trace that follows is the exact one we see.
http://old.nabble.com/-BUILD--trunk:-Failed-for-Revision:-891409-td26817690s134.html
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] null
[INFO] ------------------------------------------------------------------------
[INFO] Trace
java.lang.NullPointerException
at org.codehaus.plexus.component.configurator.converters.lookup.DefaultConverterLookup.findConverterForType(DefaultConverterLookup.java:115)
at org.codehaus.plexus.component.configurator.converters.lookup.DefaultConverterLookup.lookupConverterForType(DefaultConverterLookup.java:92)
at org.codehaus.plexus.component.configurator.converters.composite.CollectionConverter.fromConfiguration(CollectionConverter.java:175)
at org.codehaus.plexus.component.configurator.converters.ComponentValueSetter.configure(ComponentValueSetter.java:247)
at org.codehaus.plexus.component.configurator.converters.composite.ObjectWithFieldsConverter.processConfiguration(ObjectWithFieldsConverter.java:137)
at org.codehaus.plexus.component.configurator.BasicComponentConfigurator.configureComponent(BasicComponentConfigurator.java:56)
at org.codehaus.plexus.component.configurator.AbstractComponentConfigurator.configureComponent(AbstractComponentConfigurator.java:54)
at org.codehaus.plexus.component.configurator.AbstractComponentConfigurator.configureComponent(AbstractComponentConfigurator.java:47)
at org.codehaus.plexus.personality.plexus.lifecycle.phase.AutoConfigurePhase.execute(AutoConfigurePhase.java:39)
at org.codehaus.plexus.lifecycle.AbstractLifecycleHandler.start(AbstractLifecycleHandler.java:101)
at org.codehaus.plexus.component.manager.AbstractComponentManager.startComponentLifecycle(AbstractComponentManager.java:105)
at org.codehaus.plexus.component.manager.AbstractComponentManager.createComponentInstance(AbstractComponentManager.java:95)
at org.codehaus.plexus.component.manager.ClassicSingletonComponentManager.getComponent(ClassicSingletonComponentManager.java:92)
at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:331)
at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:312)
at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:440)
at org.apache.maven.plugin.DefaultPluginManager.getPluginComponent(DefaultPluginManager.java:1595)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.findExtension(DefaultLifecycleExecutor.java:1438)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.findMappingsForLifecycle(DefaultLifecycleExecutor.java:1346)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.bindLifecycleForPackaging(DefaultLifecycleExecutor.java:1292)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.constructLifecycleMappings(DefaultLifecycleExecutor.java:1275)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:534)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)