Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WFCORE-7127] Replace Attachments.CLASS_PATH_ENTRIES #6312

Merged
merged 2 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
/**
* @author <a href="mailto:[email protected]">David M. Lloyd</a>
*/
@SuppressWarnings("deprecation")
public final class Attachments {

//
Expand Down Expand Up @@ -120,19 +119,9 @@ public final class Attachments {
*/
public static final AttachmentKey<Manifest> MANIFEST = AttachmentKey.create(Manifest.class);

/**
* Module identifiers for Class-Path information.
* <p/>
* <strong>Note: This is only meant for use within the server kernel.</strong>
*
* @deprecated this will either be changed incompatibly (to provide a string) or removed altogether in the next WildFly Core major.
*/
@Deprecated(forRemoval = true)
public static final AttachmentKey<AttachmentList<ModuleIdentifier>> CLASS_PATH_ENTRIES = AttachmentKey.createList(ModuleIdentifier.class);

/**
* Resource roots for additional modules referenced via Class-Path.
*
* <p/>
* These are attached to the resource root that actually defined the class path entry, and are used to transitively resolve
* the annotation index for class path items.
*/
Expand Down Expand Up @@ -231,7 +220,7 @@ public final class Attachments {

/**
* A service target that can be used to install services outside the scope of the deployment.
*
* <p/>
* These services will not be removed automatically on undeploy, so if this is used some other strategy must be used
* to handle undeployment.
*/
Expand Down Expand Up @@ -296,7 +285,7 @@ public final class Attachments {

/**
* Sub deployments that are visible from this deployments module loader, in the order they are accessible.
*
* <p/>
* This list includes the current deployment, which under normal circumstances will be the first item in the list
*/
public static final AttachmentKey<AttachmentList<DeploymentUnit>> ACCESSIBLE_SUB_DEPLOYMENTS = AttachmentKey.createList(DeploymentUnit.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public enum Phase {
* <p>
* In this phase, these phase attachments may be modified:
* <ul>
* <li>{@link Attachments#CLASS_PATH_ENTRIES} - class path entries found in the manifest and elsewhere.</li>
* <li>{@code ManifestClassPathProcessor#CLASS_PATH_MODULES} - class path entries found in the manifest and elsewhere.</li>
* <li>{@link Attachments#EXTENSION_LIST_ENTRIES} - extension-list entries found in the manifest and elsewhere.</li>
* </ul>
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import java.util.jar.Manifest;

import org.jboss.as.controller.ModuleIdentifierUtil;
import org.jboss.as.server.deployment.AttachmentKey;
import org.jboss.as.server.deployment.AttachmentList;
import org.jboss.as.server.logging.ServerLogger;
import org.jboss.as.server.deployment.Attachable;
import org.jboss.as.server.deployment.Attachments;
Expand Down Expand Up @@ -57,6 +59,11 @@
*/
public final class ManifestClassPathProcessor implements DeploymentUnitProcessor {

/**
* Module identifiers for Class-Path information.
*/
static final AttachmentKey<AttachmentList<String>> CLASS_PATH_MODULES = AttachmentKey.createList(String.class);

private static final String[] EMPTY_STRING_ARRAY = {};

/**
Expand All @@ -78,9 +85,9 @@ public synchronized void deploy(final DeploymentPhaseContext phaseContext) throw

//These are resource roots that are already accessible by default
//such as ear/lib jars an web-inf/lib jars
final Set<VirtualFile> existingAccessibleRoots = new HashSet<VirtualFile>();
final Set<VirtualFile> existingAccessibleRoots = new HashSet<>();

final Map<VirtualFile, ResourceRoot> subDeployments = new HashMap<VirtualFile, ResourceRoot>();
final Map<VirtualFile, ResourceRoot> subDeployments = new HashMap<>();
for (ResourceRoot root : DeploymentUtils.allResourceRoots(topLevelDeployment)) {
if (SubDeploymentMarker.isSubDeployment(root)) {
subDeployments.put(root.getRoot(), root);
Expand All @@ -91,7 +98,7 @@ public synchronized void deploy(final DeploymentPhaseContext phaseContext) throw
}
}

final ArrayDeque<RootEntry> resourceRoots = new ArrayDeque<RootEntry>();
final ArrayDeque<RootEntry> resourceRoots = new ArrayDeque<>();
if (deploymentUnit.getParent() != null) {
//top level deployments already had their exiting roots processed above
for (ResourceRoot root : DeploymentUtils.allResourceRoots(deploymentUnit)) {
Expand All @@ -113,10 +120,9 @@ public synchronized void deploy(final DeploymentPhaseContext phaseContext) throw
// build a map of the additional module locations
// note that if a resource root has been added to two different additional modules
// and is then referenced via a Class-Path entry the behaviour is undefined
final Map<VirtualFile, AdditionalModuleSpecification> additionalModules = new HashMap<VirtualFile, AdditionalModuleSpecification>();
final Map<VirtualFile, AdditionalModuleSpecification> additionalModules = new HashMap<>();
final List<AdditionalModuleSpecification> additionalModuleList = topLevelDeployment.getAttachmentList(Attachments.ADDITIONAL_MODULES);
// Must synchronize on list as subdeployments executing Phase.STRUCTURE may be concurrently modifying it
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (additionalModuleList) {
for (AdditionalModuleSpecification module : additionalModuleList) {
for (ResourceRoot additionalModuleResourceRoot : module.getResourceRoots()) {
Expand Down Expand Up @@ -148,7 +154,7 @@ public synchronized void deploy(final DeploymentPhaseContext phaseContext) throw
if (item.startsWith("/")) {
if (externalModuleService.isValidFile(item)) {
final ModuleIdentifier moduleIdentifier = externalModuleService.addExternalModule(item, phaseContext.getServiceRegistry(), externalServiceTarget);
target.addToAttachmentList(Attachments.CLASS_PATH_ENTRIES, moduleIdentifier);
target.addToAttachmentList(CLASS_PATH_MODULES, moduleIdentifier.toString());
ServerLogger.DEPLOYMENT_LOGGER.debugf("Resource %s added as external jar %s", classPathFile, resourceRoot.getRoot());
} else {
ServerLogger.DEPLOYMENT_LOGGER.classPathEntryNotValid(item, resourceRoot.getRoot().getPathName());
Expand Down Expand Up @@ -197,16 +203,16 @@ private void handlingExistingClassPathEntry(final ArrayDeque<RootEntry> resource
} else if (additionalModules.containsKey(classPathFile)) {
final AdditionalModuleSpecification moduleSpecification = additionalModules.get(classPathFile);
//as class path entries are exported, transitive dependencies will also be available
target.addToAttachmentList(Attachments.CLASS_PATH_ENTRIES, ModuleIdentifier.fromString(moduleSpecification.getModuleName()));
target.addToAttachmentList(CLASS_PATH_MODULES, moduleSpecification.getModuleName());
} else if (subDeployments.containsKey(classPathFile)) {
//now we need to calculate the sub deployment module identifier
//unfortunately the sub deployment has not been setup yet, so we cannot just
//get it from the sub deployment directly
final ResourceRoot otherRoot = subDeployments.get(classPathFile);
target.addToAttachmentList(Attachments.CLASS_PATH_ENTRIES, ModuleIdentifierProcessor.createModuleIdentifier(otherRoot.getRootName(), otherRoot, topLevelDeployment, topLevelRoot, false));
target.addToAttachmentList(CLASS_PATH_MODULES, ModuleIdentifierProcessor.createModuleIdentifier(otherRoot.getRootName(), otherRoot, topLevelDeployment, topLevelRoot, false).toString());
} else {
String identifier = createAdditionalModule(resourceRoot, topLevelDeployment, topLevelRoot, additionalModules, classPathFile, resourceRoots);
target.addToAttachmentList(Attachments.CLASS_PATH_ENTRIES, ModuleIdentifier.fromString(identifier));
target.addToAttachmentList(CLASS_PATH_MODULES, identifier);
}
}

Expand Down Expand Up @@ -252,7 +258,6 @@ private static String[] getClassPathEntries(final ResourceRoot resourceRoot) {
*
* @param file The file for which the resource root will be created
* @return Returns the created {@link ResourceRoot}
* @throws java.io.IOException
*/
private synchronized ResourceRoot createResourceRoot(final VirtualFile file, final DeploymentUnit deploymentUnit, final VirtualFile deploymentRoot) throws DeploymentUnitProcessingException {
try {
Expand All @@ -276,7 +281,7 @@ private synchronized ResourceRoot createResourceRoot(final VirtualFile file, fin
}
}

private class RootEntry {
private static class RootEntry {
private final ResourceRoot resourceRoot;
private final Attachable target;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
import org.jboss.modules.ModuleIdentifier;
import org.jboss.modules.ModuleLoader;

/**
Expand All @@ -29,26 +28,26 @@ public void deploy(final DeploymentPhaseContext phaseContext) throws DeploymentU
final ModuleSpecification moduleSpecification = deploymentUnit.getAttachment(Attachments.MODULE_SPECIFICATION);

final ModuleLoader moduleLoader = deploymentUnit.getAttachment(Attachments.SERVICE_MODULE_LOADER);
final AttachmentList<ModuleIdentifier> entries = deploymentUnit.getAttachment(Attachments.CLASS_PATH_ENTRIES);
final AttachmentList<String> entries = deploymentUnit.getAttachment(ManifestClassPathProcessor.CLASS_PATH_MODULES);
if (entries != null) {
for (ModuleIdentifier entry : entries) {
for (String entry : entries) {
//class path items are always exported to make transitive dependencies work
moduleSpecification.addLocalDependency(ModuleDependency.Builder.of(moduleLoader, entry.toString()).setExport(true).setImportServices(true).build());
moduleSpecification.addLocalDependency(ModuleDependency.Builder.of(moduleLoader, entry).setExport(true).setImportServices(true).build());
}
}

final List<AdditionalModuleSpecification> additionalModules = deploymentUnit.getAttachment(Attachments.ADDITIONAL_MODULES);
if (additionalModules != null) {
for (AdditionalModuleSpecification additionalModule : additionalModules) {
final AttachmentList<ModuleIdentifier> dependencies = additionalModule.getAttachment(Attachments.CLASS_PATH_ENTRIES);
final AttachmentList<String> dependencies = additionalModule.getAttachment(ManifestClassPathProcessor.CLASS_PATH_MODULES);
if (dependencies == null || dependencies.isEmpty()) {
continue;
}
// additional modules export any class-path entries
// this means that a module that references the additional module
// gets access to the transitive closure of its call-path entries
for (ModuleIdentifier entry : dependencies) {
additionalModule.addLocalDependency(ModuleDependency.Builder.of(moduleLoader, entry.toString()).setExport(true).setImportServices(true).build());
for (String entry : dependencies) {
additionalModule.addLocalDependency(ModuleDependency.Builder.of(moduleLoader, entry).setExport(true).setImportServices(true).build());
}
// add a dependency on the top ear itself for good measure
additionalModule.addLocalDependency(ModuleDependency.Builder.of(moduleLoader, deploymentUnit.getAttachment(Attachments.MODULE_IDENTIFIER).toString()).setImportServices(true).build());
Expand Down
Loading