Skip to content
Draft
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 @@ -777,6 +777,14 @@ implicit fallback (only if they match the default, e.g., inherited)
sourceContext.handleResourceConfiguration(ProjectScope.MAIN);
sourceContext.handleResourceConfiguration(ProjectScope.TEST);
}

// When resources are defined via <sources> (4.1.0 model), sync them to
// the model's Build so project.getBuild().getResources() is consistent.
// For legacy <resources>, the model already has the correct resources.
if (sourceContext.hasSources(Language.RESOURCES, ProjectScope.MAIN)
|| sourceContext.hasSources(Language.RESOURCES, ProjectScope.TEST)) {
project.syncBuildResources();
}
}

project.setActiveProfiles(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -838,19 +838,31 @@ private Resource toConnectedResource(SourceRoot sourceRoot, ProjectScope scope)

private void addResource(ProjectScope scope, Resource resource) {
addSourceRoot(new DefaultSourceRoot(getBaseDirectory(), scope, resource.getDelegate()));
// Also update the model's Build to maintain compatibility with code that
// accesses resources via project.getBuild().getResources()
if (scope == ProjectScope.MAIN) {
getModelBuild().addResource(resource);
} else {
getModelBuild().addTestResource(resource);
}
}

/**
* @deprecated {@link Resource} is replaced by {@link SourceRoot}.
* Syncs {@code Build.resources/testResources} from the {@code sources} set
* for Maven 3 plugin compatibility (e.g. when resources come from {@code <sources>}).
*/
void syncBuildResources() {
getModelBuild().setResources(new java.util.ArrayList<>(getResources()));
getModelBuild().setTestResources(new java.util.ArrayList<>(getTestResources()));
}

/** @deprecated {@link Resource} is replaced by {@link SourceRoot}. */
@Deprecated(since = "4.0.0")
public void addResource(Resource resource) {
addResource(ProjectScope.MAIN, resource);
}

/**
* @deprecated {@link Resource} is replaced by {@link SourceRoot}.
*/
/** @deprecated {@link Resource} is replaced by {@link SourceRoot}. */
@Deprecated(since = "4.0.0")
public void addTestResource(Resource testResource) {
addResource(ProjectScope.TEST, testResource);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,4 +281,62 @@ void testTargetPathEdgeCases() {
placeholderResult.getTargetPath(),
"Property placeholder in targetPath should be preserved");
}

/**
* Verifies that resources added via {@code project.addResource()} or
* {@code project.getResources().add()} are visible through both
* {@code project.getResources()} and {@code project.getBuild().getResources()}.
* This is important for Maven 3 compatibility, since plugins may access
* resources through either path.
*
* @see <a href="https://github.com/apache/maven-source-plugin/pull/281">maven-source-plugin#281</a>
*/
@Test
void testAddResourceVisibleViaBuildGetResources() {
// Initial state: one resource in sources, none added dynamically
assertEquals(1, project.getResources().size());
int initialBuildResources = project.getBuild().getResources().size();

// Add a resource dynamically (simulating what maven-remote-resources-plugin does)
Resource dynamicResource = new Resource();
dynamicResource.setDirectory("target/maven-shared-archive-resources");
project.addResource(dynamicResource);

// Verify visible via project.getResources()
List<Resource> projectResources = project.getResources();
assertEquals(2, projectResources.size(), "Dynamic resource should be visible via project.getResources()");

// Verify ALSO visible via project.getBuild().getResources()
List<Resource> buildResources = project.getBuild().getResources();
assertEquals(
initialBuildResources + 1,
buildResources.size(),
"Dynamic resource should also be visible via project.getBuild().getResources()");

boolean found =
buildResources.stream().anyMatch(r -> r.getDirectory().contains("maven-shared-archive-resources"));
assertTrue(found, "getBuild().getResources() should contain the dynamically added resource");
}

/**
* Same as above but using {@code project.getResources().add()} path.
*/
@Test
void testAddResourceViaListVisibleViaBuildGetResources() {
int initialBuildResources = project.getBuild().getResources().size();

Resource dynamicResource = new Resource();
dynamicResource.setDirectory("target/maven-shared-archive-resources");
project.getResources().add(dynamicResource);

List<Resource> buildResources = project.getBuild().getResources();
assertEquals(
initialBuildResources + 1,
buildResources.size(),
"Resource added via getResources().add() should be visible via getBuild().getResources()");

boolean found =
buildResources.stream().anyMatch(r -> r.getDirectory().contains("maven-shared-archive-resources"));
assertTrue(found, "getBuild().getResources() should contain the resource added via getResources().add()");
}
}