You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by ja...@apache.org on 2018/02/09 03:50:06 UTC
ant-ivy git commit: IVY-1545: Added tracking for a cycle in
parent-POM ancestry,
throw a CircularDependencyException if found. Added tests for cycles in parent
ancestry and references-self as parent.
Repository: ant-ivy
Updated Branches:
refs/heads/master 55e6b039a -> 537e13241
IVY-1545: Added tracking for a cycle in parent-POM ancestry, throw a CircularDependencyException if found.
Added tests for cycles in parent ancestry and references-self as parent.
This closes #66 pull request at github/apache/ant-ivy repo
Project: http://git-wip-us.apache.org/repos/asf/ant-ivy/repo
Commit: http://git-wip-us.apache.org/repos/asf/ant-ivy/commit/537e1324
Tree: http://git-wip-us.apache.org/repos/asf/ant-ivy/tree/537e1324
Diff: http://git-wip-us.apache.org/repos/asf/ant-ivy/diff/537e1324
Branch: refs/heads/master
Commit: 537e13241a7ffd99e5a3676e574e3cd9ea9aae03
Parents: 55e6b03
Author: Brett Randall <ja...@gmail.com>
Authored: Fri Mar 25 20:55:15 2016 +1100
Committer: Jaikiran Pai <ja...@apache.org>
Committed: Fri Feb 9 09:17:56 2018 +0530
----------------------------------------------------------------------
asciidoc/release-notes.adoc | 1 +
.../circular/CircularDependencyException.java | 12 +++++-
.../parser/m2/PomModuleDescriptorParser.java | 40 +++++++++++++++---
.../apache/ivy/core/resolve/ResolveTest.java | 43 ++++++++++++++++++++
.../org/apache/dm/parent4/1.0/parent4-1.0.pom | 36 ++++++++++++++++
.../org/apache/dm/parent5/1.0/parent5-1.0.pom | 36 ++++++++++++++++
.../org/apache/dm/test6/1.0/test6-1.0.jar | 1 +
.../org/apache/dm/test6/1.0/test6-1.0.pom | 37 +++++++++++++++++
.../org/apache/dm/test7/1.0/test7-1.0.jar | 1 +
.../org/apache/dm/test7/1.0/test7-1.0.pom | 37 +++++++++++++++++
10 files changed, 237 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/537e1324/asciidoc/release-notes.adoc
----------------------------------------------------------------------
diff --git a/asciidoc/release-notes.adoc b/asciidoc/release-notes.adoc
index 38ca44b..986b153 100644
--- a/asciidoc/release-notes.adoc
+++ b/asciidoc/release-notes.adoc
@@ -74,6 +74,7 @@ For details about the following changes, check our JIRA install at link:https://
- FIX: ApacheURLLister skips versions with URL encoded characters [jira:IVY-1442[]] [jira:IVY-1573[]]
- FIX: Configuration lists are sensitive to whitespace; multiple split/merge methods [jira:IVY-309[]] [jira:IVY-1282[]]
- FIX: Warnings about illegal reflection access due to lack of methods to retrieve default authenticator in Java 5 to 8 [jira:IVY-1569[]]
+- FIX: Cycle in parent POM ancestry yields StackOverflowError in PomModuleDescriptorParser [jira:IVY-1545] (Thanks to Brett Randall)
- IMPROVEMENT: Throw an IllegalStateException when retrieving the resolutionCacheRoot on the DefaultResolutionCacheManager if the basedir (or IvySettings) is not set (jira:IVY-1482[])
- IMPROVEMENT: Optimization: limit the revision numbers scanned if revision prefix is specified (Thanks to Ernestas Vaiciukevičius)
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/537e1324/src/java/org/apache/ivy/plugins/circular/CircularDependencyException.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/circular/CircularDependencyException.java b/src/java/org/apache/ivy/plugins/circular/CircularDependencyException.java
index 438c572..788b994 100644
--- a/src/java/org/apache/ivy/plugins/circular/CircularDependencyException.java
+++ b/src/java/org/apache/ivy/plugins/circular/CircularDependencyException.java
@@ -17,15 +17,21 @@
*/
package org.apache.ivy.plugins.circular;
+import java.util.Collection;
+
import org.apache.ivy.core.module.id.ModuleRevisionId;
/**
* Unchecked exception thrown when a circular dependency exists between projects.
*/
-@SuppressWarnings("serial")
public class CircularDependencyException extends RuntimeException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 670272039106237360L;
+
private ModuleRevisionId[] mrids;
/**
@@ -37,6 +43,10 @@ public class CircularDependencyException extends RuntimeException {
this.mrids = mrids;
}
+ public CircularDependencyException(final Collection<ModuleRevisionId> mrids) {
+ this(mrids.toArray(new ModuleRevisionId[mrids.size()]));
+ }
+
public ModuleRevisionId[] getPath() {
return this.mrids;
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/537e1324/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java
index 01b3509..b1c0b7f 100644
--- a/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java
+++ b/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java
@@ -23,8 +23,11 @@ import java.io.InputStream;
import java.net.URL;
import java.text.ParseException;
import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.Map;
+import org.apache.ivy.core.IvyContext;
import org.apache.ivy.core.cache.ArtifactOrigin;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.Configuration;
@@ -38,6 +41,7 @@ import org.apache.ivy.core.resolve.ResolveData;
import org.apache.ivy.core.resolve.ResolveEngine;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
+import org.apache.ivy.plugins.circular.CircularDependencyException;
import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
import org.apache.ivy.plugins.parser.ParserSettings;
import org.apache.ivy.plugins.parser.m2.PomModuleDescriptorBuilder.PomDependencyDescriptor;
@@ -52,7 +56,6 @@ import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.apache.ivy.util.Message;
import org.xml.sax.SAXException;
-import static org.apache.ivy.core.IvyContext.getContext;
import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PUBLIC;
import static org.apache.ivy.plugins.namespace.NameSpaceHelper.toSystem;
import static org.apache.ivy.plugins.parser.m2.PomModuleDescriptorBuilder.MAVEN2_CONFIGURATIONS;
@@ -63,9 +66,9 @@ import static org.apache.ivy.plugins.parser.m2.PomModuleDescriptorBuilder.getPlu
/**
* A parser for Maven 2 POM.
* <p>
- * The configurations used in the generated module descriptor mimics the behavior defined by
- * Maven 2 scopes, as documented
- * <a href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html">here</a>.
+ * The configurations used in the generated module descriptor mimics the behavior defined by Maven 2
+ * scopes, as documented <a href=
+ * "http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html">here</a>.
* The PomModuleDescriptorParser use a PomDomReader to read the pom, and the
* PomModuleDescriptorBuilder to write the ivy module descriptor using the info read by the
* PomDomReader.
@@ -75,6 +78,8 @@ public final class PomModuleDescriptorParser implements ModuleDescriptorParser {
private static final PomModuleDescriptorParser INSTANCE = new PomModuleDescriptorParser();
+ private static final String PARENT_MAP_KEY = PomModuleDescriptorParser.class.getName() + ".parentMap";
+
public static PomModuleDescriptorParser getInstance() {
return INSTANCE;
}
@@ -123,12 +128,25 @@ public final class PomModuleDescriptorParser implements ModuleDescriptorParser {
ivySettings);
try {
+ final IvyContext ivyContext = IvyContext.pushNewCopyContext();
+ @SuppressWarnings("unchecked")
+ HashSet<ModuleRevisionId> parents = (HashSet<ModuleRevisionId>) ivyContext
+ .get(PARENT_MAP_KEY);
+ if (parents == null) {
+ parents = new LinkedHashSet<ModuleRevisionId>();
+ ivyContext.set(PARENT_MAP_KEY, parents);
+ }
+
PomReader domReader = new PomReader(descriptorURL, res);
domReader.setProperty("parent.version", domReader.getParentVersion());
domReader.setProperty("parent.groupId", domReader.getParentGroupId());
domReader.setProperty("project.parent.version", domReader.getParentVersion());
domReader.setProperty("project.parent.groupId", domReader.getParentGroupId());
+ Message.debug("parent.groupId: " + domReader.getParentGroupId());
+ Message.debug("parent.artifactId: " + domReader.getParentArtifactId());
+ Message.debug("parent.version: " + domReader.getParentVersion());
+
for (Map.Entry<String, String> prop : domReader.getPomProperties().entrySet()) {
domReader.setProperty(prop.getKey(), prop.getValue());
mdBuilder.addProperty(prop.getKey(), prop.getValue());
@@ -141,6 +159,14 @@ public final class PomModuleDescriptorParser implements ModuleDescriptorParser {
ModuleRevisionId parentModRevID = ModuleRevisionId.newInstance(
domReader.getParentGroupId(), domReader.getParentArtifactId(),
domReader.getParentVersion());
+
+ // check for cycles
+ if (parents.contains(parentModRevID)) {
+ throw new CircularDependencyException(parents);
+ } else {
+ parents.add(parentModRevID);
+ }
+
ResolvedModuleRevision parentModule = parseOtherPom(ivySettings, parentModRevID);
if (parentModule == null) {
throw new IOException("Impossible to load parent for " + res.getName()
@@ -282,6 +308,8 @@ public final class PomModuleDescriptorParser implements ModuleDescriptorParser {
}
} catch (SAXException e) {
throw newParserException(e);
+ } finally {
+ IvyContext.popContext();
}
return mdBuilder.getModuleDescriptor();
@@ -383,9 +411,9 @@ public final class PomModuleDescriptorParser implements ModuleDescriptorParser {
private ResolvedModuleRevision parseOtherPom(ParserSettings ivySettings,
ModuleRevisionId parentModRevID) throws ParseException {
DependencyDescriptor dd = new DefaultDependencyDescriptor(parentModRevID, true);
- ResolveData data = getContext().getResolveData();
+ ResolveData data = IvyContext.getContext().getResolveData();
if (data == null) {
- ResolveEngine engine = getContext().getIvy().getResolveEngine();
+ ResolveEngine engine = IvyContext.getContext().getIvy().getResolveEngine();
ResolveOptions options = new ResolveOptions();
options.setDownload(false);
data = new ResolveData(engine, options);
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/537e1324/test/java/org/apache/ivy/core/resolve/ResolveTest.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/core/resolve/ResolveTest.java b/test/java/org/apache/ivy/core/resolve/ResolveTest.java
index a41f91f..c3fe21a 100644
--- a/test/java/org/apache/ivy/core/resolve/ResolveTest.java
+++ b/test/java/org/apache/ivy/core/resolve/ResolveTest.java
@@ -79,6 +79,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
/**
*
@@ -4921,6 +4922,48 @@ public class ResolveTest {
"jar").exists());
}
+ @Test
+ public void testErrorResolveMaven2ParentPomWithCycle() throws Exception {
+ // IVY-1545
+ // test6 has parent parent4, parent4 parent is parent5, parent5 parent is parent4, a cycle.
+ Ivy ivy = new Ivy();
+ ivy.configure(new File("test/repositories/parentPom/ivysettings.xml"));
+ ivy.getSettings().setDefaultResolver("parentChain");
+
+ try {
+ ivy.resolve(
+ new File("test/repositories/parentPom/org/apache/dm/test6/1.0/test6-1.0.pom"),
+ getResolveOptions(new String[] {"*"}));
+
+ // don't expect to get here, should suffer StackOverflowError if cycle is not detected
+ fail("Expected CircularDependencyException from parent cycle detection");
+ } catch (CircularDependencyException e) {
+ // ok
+ assertEquals("org.apache.dm#parent4;1.0->org.apache.dm#parent5;1.0", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testErrorResolveMaven2SelfAsParent() throws Exception {
+ // IVY-1545
+ // test7 has parent == self
+ Ivy ivy = new Ivy();
+ ivy.configure(new File("test/repositories/parentPom/ivysettings.xml"));
+ ivy.getSettings().setDefaultResolver("parentChain");
+
+ try {
+ ivy.resolve(
+ new File("test/repositories/parentPom/org/apache/dm/test7/1.0/test7-1.0.pom"),
+ getResolveOptions(new String[] {"*"}));
+
+ // don't expect to get here, should suffer StackOverflowError if cycle is not detected
+ fail("Expected CircularDependencyException from parent cycle detection");
+ } catch (CircularDependencyException e) {
+ // ok
+ assertEquals("org.apache.dm#test7;1.0", e.getMessage());
+ }
+ }
+
/**
* Test case for IVY-1186.
*
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/537e1324/test/repositories/parentPom/org/apache/dm/parent4/1.0/parent4-1.0.pom
----------------------------------------------------------------------
diff --git a/test/repositories/parentPom/org/apache/dm/parent4/1.0/parent4-1.0.pom b/test/repositories/parentPom/org/apache/dm/parent4/1.0/parent4-1.0.pom
new file mode 100644
index 0000000..82a69f5
--- /dev/null
+++ b/test/repositories/parentPom/org/apache/dm/parent4/1.0/parent4-1.0.pom
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<project>
+ <parent>
+ <artifactId>parent5</artifactId>
+ <groupId>org.apache.dm</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.dm</groupId>
+ <artifactId>parent4</artifactId>
+ <name>Test Module for Ivy M2 parsing - detects circular parent references</name>
+ <version>1.0</version>
+ <url>http://ivy.jayasoft.org/</url>
+ <organization>
+ <name>Jayasoft</name>
+ <url>http://www.jayasoft.org/</url>
+ </organization>
+</project>
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/537e1324/test/repositories/parentPom/org/apache/dm/parent5/1.0/parent5-1.0.pom
----------------------------------------------------------------------
diff --git a/test/repositories/parentPom/org/apache/dm/parent5/1.0/parent5-1.0.pom b/test/repositories/parentPom/org/apache/dm/parent5/1.0/parent5-1.0.pom
new file mode 100644
index 0000000..596a8f1
--- /dev/null
+++ b/test/repositories/parentPom/org/apache/dm/parent5/1.0/parent5-1.0.pom
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<project>
+ <parent>
+ <artifactId>parent4</artifactId>
+ <groupId>org.apache.dm</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.dm</groupId>
+ <artifactId>parent5</artifactId>
+ <name>Test Module for Ivy M2 parsing - detects circular parent references</name>
+ <version>1.0</version>
+ <url>http://ivy.jayasoft.org/</url>
+ <organization>
+ <name>Jayasoft</name>
+ <url>http://www.jayasoft.org/</url>
+ </organization>
+</project>
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/537e1324/test/repositories/parentPom/org/apache/dm/test6/1.0/test6-1.0.jar
----------------------------------------------------------------------
diff --git a/test/repositories/parentPom/org/apache/dm/test6/1.0/test6-1.0.jar b/test/repositories/parentPom/org/apache/dm/test6/1.0/test6-1.0.jar
new file mode 100644
index 0000000..56f3b36
--- /dev/null
+++ b/test/repositories/parentPom/org/apache/dm/test6/1.0/test6-1.0.jar
@@ -0,0 +1 @@
+
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/537e1324/test/repositories/parentPom/org/apache/dm/test6/1.0/test6-1.0.pom
----------------------------------------------------------------------
diff --git a/test/repositories/parentPom/org/apache/dm/test6/1.0/test6-1.0.pom b/test/repositories/parentPom/org/apache/dm/test6/1.0/test6-1.0.pom
new file mode 100644
index 0000000..35e1a3c
--- /dev/null
+++ b/test/repositories/parentPom/org/apache/dm/test6/1.0/test6-1.0.pom
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<project>
+ <!-- has parent cycle parent4 -> parent5 -> parent4 ... -->
+ <parent>
+ <artifactId>parent4</artifactId>
+ <groupId>org.apache.dm</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.dm</groupId>
+ <artifactId>test6</artifactId>
+ <name>Test safe-failure of parent with dependency cycle</name>
+ <version>1.0</version>
+ <url>http://ivy.jayasoft.org/</url>
+ <organization>
+ <name>Jayasoft</name>
+ <url>http://www.jayasoft.org/</url>
+ </organization>
+</project>
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/537e1324/test/repositories/parentPom/org/apache/dm/test7/1.0/test7-1.0.jar
----------------------------------------------------------------------
diff --git a/test/repositories/parentPom/org/apache/dm/test7/1.0/test7-1.0.jar b/test/repositories/parentPom/org/apache/dm/test7/1.0/test7-1.0.jar
new file mode 100644
index 0000000..56f3b36
--- /dev/null
+++ b/test/repositories/parentPom/org/apache/dm/test7/1.0/test7-1.0.jar
@@ -0,0 +1 @@
+
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/537e1324/test/repositories/parentPom/org/apache/dm/test7/1.0/test7-1.0.pom
----------------------------------------------------------------------
diff --git a/test/repositories/parentPom/org/apache/dm/test7/1.0/test7-1.0.pom b/test/repositories/parentPom/org/apache/dm/test7/1.0/test7-1.0.pom
new file mode 100644
index 0000000..be74ee2
--- /dev/null
+++ b/test/repositories/parentPom/org/apache/dm/test7/1.0/test7-1.0.pom
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<project>
+ <!-- illegal, references itself as parent -->
+ <parent>
+ <artifactId>test7</artifactId>
+ <groupId>org.apache.dm</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.dm</groupId>
+ <artifactId>test7</artifactId>
+ <name>Test safe-failure of references self as parent</name>
+ <version>1.0</version>
+ <url>http://ivy.jayasoft.org/</url>
+ <organization>
+ <name>Jayasoft</name>
+ <url>http://www.jayasoft.org/</url>
+ </organization>
+</project>