batch-jberet/src/main/java/org/wildfly/extension/batch/jberet/deployment/WildFlyJobXmlResolver.java
public static WildFlyJobXmlResolver forDeployment(final DeploymentUnit deploymentUnit) throws DeploymentUnitProcessingException {
        // If this deployment unit already has a resolver, just use it
        if (deploymentUnit.hasAttachment(BatchAttachments.JOB_XML_RESOLVER)) {
            return deploymentUnit.getAttachment(BatchAttachments.JOB_XML_RESOLVER);
        }
        // Get the module for it's class loader
        final Module module = deploymentUnit.getAttachment(Attachments.MODULE);
        final ClassLoader classLoader = module.getClassLoader();
        WildFlyJobXmlResolver resolver;
        // If we're an EAR we need to skip sub-deployments as they'll be process later, however all sub-deployments have
        // access to the EAR/lib directory so those resources need to be processed
        if (DeploymentTypeMarker.isType(DeploymentType.EAR, deploymentUnit)) {
            // Create a new WildFlyJobXmlResolver without jobs from sub-deployments as they'll be processed later
            final List<ResourceRoot> resources = new ArrayList<>();
            for (ResourceRoot r : deploymentUnit.getAttachmentList(Attachments.RESOURCE_ROOTS)) {
                if (! SubDeploymentMarker.isSubDeployment(r)) {
                    resources.add(r);
                }
            }
            resolver = create(classLoader, resources);
            deploymentUnit.putAttachment(BatchAttachments.JOB_XML_RESOLVER, resolver);
        } else {
            // Create a new resolver for this deployment
            if (deploymentUnit.hasAttachment(Attachments.RESOURCE_ROOTS)) {
                resolver = create(classLoader, deploymentUnit.getAttachmentList(Attachments.RESOURCE_ROOTS));
            } else {
                resolver = create(classLoader, Collections.singletonList(deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT)));
            }
            deploymentUnit.putAttachment(BatchAttachments.JOB_XML_RESOLVER, resolver);
            // Process all accessible sub-deployments
            final List<DeploymentUnit> accessibleDeployments = deploymentUnit.getAttachmentList(Attachments.ACCESSIBLE_SUB_DEPLOYMENTS);
            for (DeploymentUnit subDeployment : accessibleDeployments) {
                // Skip our self
                if (deploymentUnit.equals(subDeployment)) {
                    continue;
                }
                if (subDeployment.hasAttachment(BatchAttachments.JOB_XML_RESOLVER)) {
                    final WildFlyJobXmlResolver toCopy = subDeployment.getAttachment(BatchAttachments.JOB_XML_RESOLVER);
                    WildFlyJobXmlResolver.merge(resolver, toCopy);
                } else {
                    // We need to create a resolver for the sub-deployment and merge the two
                    final WildFlyJobXmlResolver toCopy = forDeployment(subDeployment);
                    subDeployment.putAttachment(BatchAttachments.JOB_XML_RESOLVER, toCopy);
                    WildFlyJobXmlResolver.merge(resolver, toCopy);
                }
            }
        }
        return resolver;
    }
public static WildFlyJobXmlResolver forDeployment(final DeploymentUnit deploymentUnit) throws DeploymentUnitProcessingException {
        // If this deployment unit already has a resolver, just use it
        if (deploymentUnit.hasAttachment(BatchAttachments.JOB_XML_RESOLVER)) {
            return deploymentUnit.getAttachment(BatchAttachments.JOB_XML_RESOLVER);
        }
        // Get the module for it's class loader
        final Module module = deploymentUnit.getAttachment(Attachments.MODULE);
        final ClassLoader classLoader = module.getClassLoader();
        WildFlyJobXmlResolver resolver;
        // If we're an EAR we need to skip sub-deployments as they'll be process later, however all sub-deployments have
        // access to the EAR/lib directory so those resources need to be processed
        if (DeploymentTypeMarker.isType(DeploymentType.EAR, deploymentUnit)) {
            // Create a new WildFlyJobXmlResolver without jobs from sub-deployments as they'll be processed later
            final List<ResourceRoot> resources = new ArrayList<>();
            for (ResourceRoot r : deploymentUnit.getAttachmentList(Attachments.RESOURCE_ROOTS)) {
                if (! SubDeploymentMarker.isSubDeployment(r)) {
                    resources.add(r);
                }
            }
            resolver = create(classLoader, resources);
            deploymentUnit.putAttachment(BatchAttachments.JOB_XML_RESOLVER, resolver);
        } else {
            // Create a new resolver for this deployment
            if (deploymentUnit.hasAttachment(Attachments.RESOURCE_ROOTS)) {
                resolver = create(classLoader, deploymentUnit.getAttachmentList(Attachments.RESOURCE_ROOTS));
            } else {
                resolver = create(classLoader, Collections.singletonList(deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT)));
            }
            deploymentUnit.putAttachment(BatchAttachments.JOB_XML_RESOLVER, resolver);
            // Process all accessible sub-deployments
            final List<DeploymentUnit> accessibleDeployments = deploymentUnit.getAttachmentList(Attachments.ACCESSIBLE_SUB_DEPLOYMENTS);
            for (DeploymentUnit subDeployment : accessibleDeployments) {
                // Skip our self
                if (deploymentUnit.equals(subDeployment)) {
                    continue;
                }
                if (subDeployment.hasAttachment(BatchAttachments.JOB_XML_RESOLVER)) {
                    final WildFlyJobXmlResolver toCopy = subDeployment.getAttachment(BatchAttachments.JOB_XML_RESOLVER);
                    WildFlyJobXmlResolver.merge(resolver, toCopy);
                } else {
                    // We need to create a resolver for the sub-deployment and merge the two
                    final WildFlyJobXmlResolver toCopy = forDeployment(subDeployment);
                    subDeployment.putAttachment(BatchAttachments.JOB_XML_RESOLVER, toCopy);
                    WildFlyJobXmlResolver.merge(resolver, toCopy);
                }
            }
        }
        return resolver;
    }
Creates the {@linkplain JobXmlResolver resolver} for the deployment inheriting any visible resolvers and job XML
files from dependencies.

@param deploymentUnit the deployment to process

@return the resolve

@throws DeploymentUnitProcessingException if an error occurs processing the deployment