m-m-m / code

Library to parse, analyze, transform and generate code
Apache License 2.0
2 stars 3 forks source link

Infinity loop in MavenDependencyCollector.collectWithReactor #26

Closed hohwille closed 4 years ago

hohwille commented 4 years ago
Exception in thread "main" java.lang.StackOverflowError
    at org.codehaus.plexus.interpolation.reflection.ReflectionValueExtractor.evaluate(ReflectionValueExtractor.java:90)
    at org.codehaus.plexus.interpolation.ObjectBasedValueSource.getValue(ObjectBasedValueSource.java:64)
    at org.codehaus.plexus.interpolation.PrefixedValueSourceWrapper.getValue(PrefixedValueSourceWrapper.java:129)
    at org.codehaus.plexus.interpolation.AbstractDelegatingValueSource.getValue(AbstractDelegatingValueSource.java:44)
    at org.codehaus.plexus.interpolation.StringSearchInterpolator.interpolate(StringSearchInterpolator.java:198)
    at org.codehaus.plexus.interpolation.StringSearchInterpolator.interpolate(StringSearchInterpolator.java:217)
    at org.codehaus.plexus.interpolation.StringSearchInterpolator.interpolate(StringSearchInterpolator.java:122)
    at org.apache.maven.model.interpolation.AbstractStringBasedModelInterpolator.interpolateInternal(AbstractStringBasedModelInterpolator.java:247)
    at org.apache.maven.model.interpolation.StringSearchModelInterpolator$InterpolateObjectAction.interpolate(StringSearchModelInterpolator.java:141)
    at org.apache.maven.model.interpolation.StringSearchModelInterpolator$InterpolateObjectAction.access$300(StringSearchModelInterpolator.java:95)
    at org.apache.maven.model.interpolation.StringSearchModelInterpolator$InterpolateObjectAction$StringField.doInterpolate(StringSearchModelInterpolator.java:349)
    at org.apache.maven.model.interpolation.StringSearchModelInterpolator$InterpolateObjectAction$CacheField.interpolate(StringSearchModelInterpolator.java:301)
    at org.apache.maven.model.interpolation.StringSearchModelInterpolator$InterpolateObjectAction$CacheItem.interpolate(StringSearchModelInterpolator.java:274)
    at org.apache.maven.model.interpolation.StringSearchModelInterpolator$InterpolateObjectAction.traverseObjectWithParents(StringSearchModelInterpolator.java:158)
    at org.apache.maven.model.interpolation.StringSearchModelInterpolator$InterpolateObjectAction.run(StringSearchModelInterpolator.java:132)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.apache.maven.model.interpolation.StringSearchModelInterpolator.interpolateObject(StringSearchModelInterpolator.java:78)
    at org.apache.maven.model.interpolation.StringSearchModelInterpolator.interpolateModel(StringSearchModelInterpolator.java:61)
    at org.apache.maven.model.building.DefaultModelBuilder.interpolateModel(DefaultModelBuilder.java:771)
    at org.apache.maven.model.building.DefaultModelBuilder.build(DefaultModelBuilder.java:387)
    at org.apache.maven.model.building.DefaultModelBuilder.importDependencyManagement(DefaultModelBuilder.java:1279)
    at org.apache.maven.model.building.DefaultModelBuilder.build(DefaultModelBuilder.java:457)
    at org.apache.maven.model.building.DefaultModelBuilder.build(DefaultModelBuilder.java:423)
    at org.apache.maven.model.building.DefaultModelBuilder.build(DefaultModelBuilder.java:413)
    at org.apache.maven.model.building.DefaultModelBuilder.importDependencyManagement(DefaultModelBuilder.java:1279)
    at org.apache.maven.model.building.DefaultModelBuilder.build(DefaultModelBuilder.java:457)
    at org.apache.maven.model.building.DefaultModelBuilder.build(DefaultModelBuilder.java:423)
    at org.apache.maven.model.building.DefaultModelBuilder.build(DefaultModelBuilder.java:413)
    at net.sf.mmm.code.java.maven.impl.MavenBridgeImpl.readEffectiveModel(MavenBridgeImpl.java:184)
    at net.sf.mmm.code.impl.java.source.maven.MavenDependencyCollector.parseModel(MavenDependencyCollector.java:148)
    at net.sf.mmm.code.impl.java.source.maven.MavenDependencyCollector.collectWithReactor(MavenDependencyCollector.java:173)
    at net.sf.mmm.code.impl.java.source.maven.MavenDependencyCollector.collectWithReactor(MavenDependencyCollector.java:174)
    at net.sf.mmm.code.impl.java.source.maven.MavenDependencyCollector.collectWithReactor(MavenDependencyCollector.java:174)
hohwille commented 4 years ago

https://github.com/m-m-m/code/blob/632393e544504754b3d391a9a36e0ddeccdcbc48/java/impl/src/main/java/net/sf/mmm/code/impl/java/source/maven/MavenDependencyCollector.java#L174

hohwille commented 4 years ago

What I do not get easily is that in the code clearly in every iteration from the model the parent is taken: https://github.com/m-m-m/code/blob/632393e544504754b3d391a9a36e0ddeccdcbc48/java/impl/src/main/java/net/sf/mmm/code/impl/java/source/maven/MavenDependencyCollector.java#L166

Then for that parent model the POM is resolved: https://github.com/m-m-m/code/blob/632393e544504754b3d391a9a36e0ddeccdcbc48/java/impl/src/main/java/net/sf/mmm/code/impl/java/source/maven/MavenDependencyCollector.java#L172

And the maven model for that parent (!) pom is build: https://github.com/m-m-m/code/blob/632393e544504754b3d391a9a36e0ddeccdcbc48/java/impl/src/main/java/net/sf/mmm/code/impl/java/source/maven/MavenDependencyCollector.java#L173

As we recurse with that parentModel how could this create an infinity look? IMHO only in a case where a POM points to itself in the parent declaration. This should never be possible in a POM from maven central and is really odd and unlikely though still possible. But in my case I believe the error has to be another reason that I can not figure out easily. Any ideas what I might be missing?

hohwille commented 4 years ago

Maybe the effective model does not apply the defaults from super-pom as expected so in this line: https://github.com/m-m-m/code/blob/632393e544504754b3d391a9a36e0ddeccdcbc48/java/impl/src/main/java/net/sf/mmm/code/impl/java/source/maven/MavenDependencyCollector.java#L172

It could be that parent.getRelativePath() then does not return ../pom.xml but the empty string if <relativePath> is omitted. In that case we would stay in modelBasedir and by default resolve pom.xml what is the current POM again.

However, I already tuned this to avoid visiting the same POM twice here: https://github.com/m-m-m/code/blob/632393e544504754b3d391a9a36e0ddeccdcbc48/java/impl/src/main/java/net/sf/mmm/code/impl/java/source/maven/MavenDependencyCollector.java#L169

This is porperly filled here: https://github.com/m-m-m/code/blob/632393e544504754b3d391a9a36e0ddeccdcbc48/java/impl/src/main/java/net/sf/mmm/code/impl/java/source/maven/MavenDependencyCollector.java#L162

So even if the first assumtion would apply it still does not explain the infinity look. IMHO I can only figure this out via debugging.

hohwille commented 4 years ago

I was able to debug and trace down the problem: The project was using this parent declaration in their root pom:

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

Therefore still in the effective POM the relativePath was empty. This lead to the effect, I predicted that the parent POM accidentally was resolved as the POM of the current project itself.

For the caching that did not help here, the problem is that GAV is org.springframework.boot:spring-boot-starter-parent:2.1.6.RELEASE but the POM that is then resolved and loaded is still the projects POM that then we end up in an infinity loop.

hohwille commented 4 years ago

Fixed. Will be released with 1.0.0-beta5.