This is an automated email from the ASF dual-hosted git repository. michaelo pushed a commit to branch MNG-7034_3.8.x in repository https://gitbox.apache.org/repos/asf/maven.git
commit 8931800cb10ad1b4b5a811b3fdad022f0cbe13ee Author: Guillaume Nodet <[email protected]> AuthorDate: Wed Nov 25 20:12:04 2020 +0100 [MNG-7034] StackOverflowError thrown if a cycle exists in BOM imports This closes #399 --- .../maven/model/building/DefaultModelBuilder.java | 11 +- .../model/building/DefaultModelBuilderTest.java | 146 +++++++++++++++++++++ 2 files changed, 155 insertions(+), 2 deletions(-) diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java index f981944..70c9ed5 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java @@ -249,6 +249,13 @@ public class DefaultModelBuilder public ModelBuildingResult build( ModelBuildingRequest request ) throws ModelBuildingException { + return build( request, new LinkedHashSet<String>() ); + } + + @SuppressWarnings( "checkstyle:methodlength" ) + protected ModelBuildingResult build( ModelBuildingRequest request, Collection<String> importIds ) + throws ModelBuildingException + { // phase 1 DefaultModelBuildingResult result = new DefaultModelBuildingResult(); @@ -427,7 +434,7 @@ public class DefaultModelBuilder if ( !request.isTwoPhaseBuilding() ) { - build( request, result ); + build( request, result, importIds ); } return result; @@ -1296,7 +1303,7 @@ public class DefaultModelBuilder final ModelBuildingResult importResult; try { - importResult = build( importRequest ); + importResult = build( importRequest, importIds ); } catch ( ModelBuildingException e ) { diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderTest.java new file mode 100644 index 0000000..b4b0a5b --- /dev/null +++ b/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderTest.java @@ -0,0 +1,146 @@ +package org.apache.maven.model.building; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Parent; +import org.apache.maven.model.Repository; +import org.apache.maven.model.resolution.InvalidRepositoryException; +import org.apache.maven.model.resolution.ModelResolver; +import org.apache.maven.model.resolution.UnresolvableModelException; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; + +/** + * @author Guillaume Nodet + */ +public class DefaultModelBuilderTest +{ + + private static final String BASE1_ID = "thegroup:base1:pom"; + + private static final String BASE1 = "<project>\n" + + " <modelVersion>4.0.0</modelVersion>\n" + + " <groupId>thegroup</groupId>\n" + + " <artifactId>base1</artifactId>\n" + + " <version>1</version>\n" + + " <packaging>pom</packaging>\n" + + " <dependencyManagement>\n" + + " <dependencies>\n" + + " <dependency>\n" + + " <groupId>thegroup</groupId>\n" + + " <artifactId>base2</artifactId>\n" + + " <version>1</version>\n" + + " <type>pom</type>\n" + + " <scope>import</scope>\n" + + " </dependency>\n" + + " </dependencies>\n" + + " </dependencyManagement>\n" + + "</project>\n"; + + private static final String BASE2_ID = "thegroup:base2:pom"; + + private static final String BASE2 = "<project>\n" + + " <modelVersion>4.0.0</modelVersion>\n" + + " <groupId>thegroup</groupId>\n" + + " <artifactId>base2</artifactId>\n" + + " <version>1</version>\n" + + " <packaging>pom</packaging>\n" + + " <dependencyManagement>\n" + + " <dependencies>\n" + + " <dependency>\n" + + " <groupId>thegroup</groupId>\n" + + " <artifactId>base1</artifactId>\n" + + " <version>1</version>\n" + + " <type>pom</type>\n" + + " <scope>import</scope>\n" + + " </dependency>\n" + + " </dependencies>\n" + + " </dependencyManagement>\n" + + "</project>\n"; + + @Test( expected = ModelBuildingException.class ) + public void testCycleInImports() + throws Exception + { + ModelBuilder builder = new DefaultModelBuilderFactory().newInstance(); + assertNotNull( builder ); + + DefaultModelBuildingRequest request = new DefaultModelBuildingRequest(); + request.setModelSource( new StringModelSource( BASE1 ) ); + request.setModelResolver( new CycleInImportsResolver() ); + + builder.build( request ); + } + + static class CycleInImportsResolver extends BaseModelResolver + { + @Override + public ModelSource resolveModel(Dependency dependency) throws UnresolvableModelException + { + switch ( dependency.getManagementKey() ) + { + case BASE1_ID: return new StringModelSource( BASE1 ); + case BASE2_ID: return new StringModelSource( BASE2 ); + } + return null; + } + } + + static class BaseModelResolver implements ModelResolver + { + @Override + public ModelSource resolveModel( String groupId, String artifactId, String version ) + throws UnresolvableModelException + { + return null; + } + + @Override + public ModelSource resolveModel( Parent parent ) throws UnresolvableModelException + { + return null; + } + + @Override + public ModelSource resolveModel( Dependency dependency ) throws UnresolvableModelException + { + return null; + } + + @Override + public void addRepository( Repository repository ) throws InvalidRepositoryException + { + } + + @Override + public void addRepository(Repository repository, boolean replace) throws InvalidRepositoryException + { + } + + @Override + public ModelResolver newCopy() + { + return this; + } + } + +}
