[jboss-jira] [JBoss JIRA] (WFLY-10539) ServletContainerInitializer instances aren't invoked in the specified order (WarMetaData order)

Paulo Silva (JIRA) issues at jboss.org
Fri Jun 8 07:40:00 EDT 2018


     [ https://issues.jboss.org/browse/WFLY-10539?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Paulo Silva updated WFLY-10539:
-------------------------------
    Workaround Description: 
In ServletContainerInitializerDeploymentProcessor, update the following code to use a LinkedHashSet:

{code:java}
if (scis == null) {
   scis = new LinkedHashSet<ServletContainerInitializer>();
   scisMetaData.setScis(scis);
}
{code}

  was:
In ServletContainerInitializerDeploymentProcessor, update the code to use a LinkedHashSet:

{code:java}
if (scis == null) {
   scis = new LinkedHashSet<ServletContainerInitializer>();
   scisMetaData.setScis(scis);
}
{code}



> ServletContainerInitializer instances aren't invoked in the specified order (WarMetaData order)
> -----------------------------------------------------------------------------------------------
>
>                 Key: WFLY-10539
>                 URL: https://issues.jboss.org/browse/WFLY-10539
>             Project: WildFly
>          Issue Type: Bug
>          Components: Web (Undertow)
>    Affects Versions: 12.0.0.Final, 13.0.0.Final
>            Reporter: Paulo Silva
>            Assignee: Stuart Douglas
>
> After several tests I've found that ServletContainerInitializer instances aren't being called in a deterministic order, even when an absolute-ordering is configured in web.xml.
> Stepping through the code, on wildfly startup, I've found that ServletContainerInitializer instances are being collected to ScisMetaData.The problem is that they are being stored in a HashSet, and that makes no guarantees of the iteration order!
> The set is being initialized here:
> {code:java}
> Set<ServletContainerInitializer> scis = scisMetaData.getScis();
> Set<Class<? extends ServletContainerInitializer>> sciClasses = new HashSet<>();
> if (scis == null) {
>    scis = new HashSet<ServletContainerInitializer>();
>    scisMetaData.setScis(scis);
> }
> {code}
> And the ServletContainerInitializer implementations that are found in jars are being added here:
> {code:java}
>         // Find local ServletContainerInitializer services
>         List<String> order = warMetaData.getOrder();
>         Map<String, VirtualFile> localScis = warMetaData.getScis();
>         if (order != null && localScis != null) {
>             for (String jar : order) {
>                 VirtualFile sci = localScis.get(jar);
>                 if (sci != null) {
>                     scis.addAll(loadSci(classLoader, sci, jar, true, sciClasses));
>                 }
>             }
>         }
> {code}
> and later iterated and added to the DeployementInfo here (they are added to a List!):
> {code:java}
>            if (scisMetaData != null && scisMetaData.getHandlesTypes() != null) {
>                 for (final ServletContainerInitializer sci : scisMetaData.getScis()) {
>                     final ImmediateInstanceFactory<ServletContainerInitializer> instanceFactory = new ImmediateInstanceFactory<>(sci);
>                     d.addServletContainerInitalizer(new ServletContainerInitializerInfo(sci.getClass(), instanceFactory, scisMetaData.getHandlesTypes().get(sci)));
>                 }
>             }
> {code}
> +But+, since scisMetaData.getScis() returns a HashSet, there is absolutely no guarantee that the iteration order is the same as the insertion order (the order that is imposed by warMetaData.getOrder()).
> So a simple fix is to use a LinkedHashSet instead of a HashSet:
> The ServletContainerInitializer instances are later iterated (List iteration) and called in DeployementManagerImpl:
> {code:java}
> //then run the SCI's
> for (final ServletContainerInitializerInfo sci : deploymentInfo.getServletContainerInitializers()) {
>     final InstanceHandle<? extends ServletContainerInitializer> instance = sci.getInstanceFactory().createInstance();
>     try {
>         instance.getInstance().onStartup(sci.getHandlesTypes(), servletContext);
>     } finally {
>         instance.release();
>     }
> }
> {code}



--
This message was sent by Atlassian JIRA
(v7.5.0#75005)


More information about the jboss-jira mailing list