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

TargetPlatformFactoryImpl.gatherP2InfUnits should use artifact version #3722

Merged

Conversation

merks
Copy link
Contributor

@merks merks commented Mar 30, 2024

Currently the implementation hard codes the version to 1.0.0 when parsing advice from a p2.inf. This can result in an IAE if the version is used in a range such as [1.0.0,$version$) where because [1.0.0,1.0.0) is not a valid range.

@merks
Copy link
Contributor Author

merks commented Mar 30, 2024

The expected failure is present:

[INFO] -------------< tycho-its-project.p2Inf.virtualUnit:parent >-------------
[INFO] Building parent 2.0.0-SNAPSHOT                                     [1/2]
[INFO]   from pom.xml
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- clean:3.2.0:clean (default-cli) @ parent ---
[INFO] 
[INFO] -----------< tycho-its-project.p2Inf.virtualUnit:pvu.bundle >-----------
[INFO] Building pvu.bundle 2.0.0-SNAPSHOT                                 [2/2]
[INFO]   from bundle/pom.xml
[INFO] ---------------------------[ eclipse-plugin ]---------------------------
[ERROR] [f562fc16-0a91-46b0-ab61-556e46ea8f4a][extension>org.eclipse.tycho:tycho-maven-plugin:5.0.0-SNAPSHOT] An error occured while parsing advice file: basePath=/home/jenkins/agent/workspace/tycho-github_PR-3722/tycho-its/target/projects/VirtualUnitTest/testVirtualUnitRequirementDoesNotFailBuild/p2Inf.virtualUnit/bundle, adviceFilePath=META-INF/p2.inf.
java.lang.IllegalArgumentException: Range minimum "1.0.0" is not less then range maximum "1.0.0" (inclusion is required at both ends if the versions are equal)
    at org.eclipse.equinox.p2.metadata.VersionRange.validateRange (VersionRange.java:522)
    at org.eclipse.equinox.p2.metadata.VersionRange.<init> (VersionRange.java:258)
    at org.eclipse.equinox.p2.metadata.VersionRange.create (VersionRange.java:285)
    at org.eclipse.equinox.p2.publisher.AdviceFileParser.parseUpdateDescriptor (AdviceFileParser.java:220)
    at org.eclipse.equinox.p2.publisher.AdviceFileParser.parse (AdviceFileParser.java:112)
    at org.eclipse.equinox.p2.publisher.AdviceFileAdvice.<init> (AdviceFileAdvice.java:81)
    at org.eclipse.tycho.p2resolver.TargetPlatformFactoryImpl.gatherP2InfUnits (TargetPlatformFactoryImpl.java:310)
    at org.eclipse.tycho.p2resolver.TargetPlatformFactoryImpl.createTargetPlatform (TargetPlatformFactoryImpl.java:271)
    at org.eclipse.tycho.p2resolver.TargetPlatformFactoryImpl.createTargetPlatform (TargetPlatformFactoryImpl.java:185)
    at org.eclipse.tycho.p2resolver.TargetPlatformFactoryImpl.createTargetPlatform (TargetPlatformFactoryImpl.java:123)
    at org.eclipse.tycho.p2resolver.DefaultTargetPlatformFactory.createTargetPlatform (DefaultTargetPlatformFactory.java:75)
    at org.eclipse.tycho.p2resolver.P2DependencyResolver.lambda$getPreliminaryTargetPlatform$3 (P2DependencyResolver.java:242)
    at org.eclipse.tycho.core.osgitools.DefaultReactorProject$LazyValue.get (DefaultReactorProject.java:307)
    at org.eclipse.tycho.core.osgitools.DefaultReactorProject.computeContextValue (DefaultReactorProject.java:200)
    at org.eclipse.tycho.p2resolver.P2DependencyResolver.getPreliminaryTargetPlatform (P2DependencyResolver.java:209)
    at org.eclipse.tycho.core.osgitools.AbstractTychoProject.lambda$getDependencyArtifacts$0 (AbstractTychoProject.java:88)
    at org.eclipse.tycho.core.osgitools.DefaultReactorProject$LazyValue.get (DefaultReactorProject.java:307)
    at org.eclipse.tycho.core.osgitools.DefaultReactorProject.computeContextValue (DefaultReactorProject.java:200)
    at org.eclipse.tycho.core.osgitools.AbstractTychoProject.getDependencyArtifacts (AbstractTychoProject.java:82)
    at org.eclipse.tycho.core.resolver.DefaultTychoResolver.resolveProject (DefaultTychoResolver.java:98)
    at org.eclipse.tycho.core.maven.TychoProjectExecutionListener.beforeProjectLifecycleExecution (TychoProjectExecutionListener.java:111)
    at org.apache.maven.lifecycle.internal.CompoundProjectExecutionListener.beforeProjectLifecycleExecution (CompoundProjectExecutionListener.java:42)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:103)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:73)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:53)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:118)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:261)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:173)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:101)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:906)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:283)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:206)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:568)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:283)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:226)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:407)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:348)
[WARNING] No solution found because the problem is unsatisfiable.:
   Unable to satisfy dependency from pvu.bundle 2.0.0.qualifier to org.eclipse.equinox.p2.iu; configure.pvu.bundle 2.0.0.qualifier.
   No solution found because the problem is unsatisfiable.
[INFO] {osgi.os=linux, osgi.ws=gtk, org.eclipse.update.install.features=true, osgi.arch=x86_64, org.eclipse.update.install.sources=true}
[ERROR] Cannot resolve project dependencies:
[ERROR]   Software being installed: pvu.bundle 2.0.0.qualifier
[ERROR]   Missing requirement: pvu.bundle 2.0.0.qualifier requires 'org.eclipse.equinox.p2.iu; configure.pvu.bundle 2.0.0.qualifier' but it could not be found
[ERROR] 
[ERROR] See https://wiki.eclipse.org/Tycho/Dependency_Resolution_Troubleshooting for help.
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for parent 2.0.0-SNAPSHOT:
[INFO] 
[INFO] parent ............................................. SUCCESS [  0.056 s]
[INFO] pvu.bundle ......................................... FAILURE [  2.789 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE

Copy link

github-actions bot commented Mar 30, 2024

Test Results

  594 files    594 suites   3h 34m 35s ⏱️
  414 tests   407 ✅  7 💤 0 ❌
1 242 runs  1 220 ✅ 22 💤 0 ❌

Results for commit 7425d30.

♻️ This comment has been updated with latest results.

@merks merks force-pushed the pr-tp-factory-use-artifact-version branch 2 times, most recently from 1c41dda to f14cee8 Compare March 31, 2024 07:17
@laeubi laeubi added the backport-to-tycho-4.0.x Can be added to a PR to trigger an automatic backport of the change label Mar 31, 2024
}
try {
return Version.parseVersion(version);
} catch (IllegalAccessError ex) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IllegalAccessError --> IllegalArgumentException?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. 😬

@@ -325,6 +334,31 @@ private void gatherP2InfUnits(ReactorProject reactorProject, Set<IInstallableUni
}
}

private static Version getVersion(ReactorProject reactorProject) {
String version = reactorProject.getVersion();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried projectManager.getArtifactKey(...) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With which artifact?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It supports (maven) Artifact, Maven Projects or Reactor Projects as a parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ll look when I get home later. Is projectManager already available? (I’m on my iPhone now. )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seemed to work okay for the particular tests directly affected, but apparently there isn't always a project manager:

java.lang.AssertionError: unexpected exception type thrown; expected:<org.eclipse.tycho.core.resolver.target.DuplicateReactorIUsException> but was:<java.lang.NullPointerException>
	at org.junit.Assert.assertThrows(Assert.java:1020)
	at org.junit.Assert.assertThrows(Assert.java:981)
	at org.eclipse.tycho.p2resolver.P2ResolverTest.testDuplicateInstallableUnit(P2ResolverTest.java:113)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
	at org.junit.rules.Verifier$1.evaluate(Verifier.java:35)
	at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:316)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:240)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:214)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:155)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
	at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
Caused by: java.lang.NullPointerException: Cannot invoke "org.eclipse.tycho.core.TychoProjectManager.getArtifactKey(org.eclipse.tycho.ReactorProject)" because "this.projectManager" is null
	at org.eclipse.tycho.p2resolver.TargetPlatformFactoryImpl.getVersion(TargetPlatformFactoryImpl.java:333)
	at org.eclipse.tycho.p2resolver.TargetPlatformFactoryImpl.gatherP2InfUnits(TargetPlatformFactoryImpl.java:315)
	at org.eclipse.tycho.p2resolver.TargetPlatformFactoryImpl.createTargetPlatform(TargetPlatformFactoryImpl.java:273)
	at org.eclipse.tycho.p2resolver.TargetPlatformFactoryImpl.createTargetPlatform(TargetPlatformFactoryImpl.java:214)
	at org.eclipse.tycho.p2resolver.P2ResolverTest.getTargetPlatform(P2ResolverTest.java:491)
	at org.eclipse.tycho.p2resolver.P2ResolverTest.getTargetPlatform(P2ResolverTest.java:486)
	at org.eclipse.tycho.p2resolver.P2ResolverTest.getTargetPlatform(P2ResolverTest.java:478)
	at org.eclipse.tycho.p2resolver.P2ResolverTest.lambda$testDuplicateInstallableUnit$0(P2ResolverTest.java:114)
	at org.junit.Assert.assertThrows(Assert.java:1001)
	... 34 more

That should have been obvious because of this code:

    private List<MavenArtifactKey> getMissingJunitBundles(ReactorProject project, Set<IInstallableUnit> externalUIs) {
        List<MavenArtifactKey> missing = new ArrayList<>();
        if (projectManager != null) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little doubtful now whether this

    private Version getVersion(ReactorProject reactorProject) {
        if (projectManager == null) {
            return DEFAULT_P2_ADVICE_VERSION;
        }
        try {
            return projectManager.getArtifactKey(reactorProject).map(key -> Version.parseVersion(key.getVersion()))
                    .orElseGet(() -> DEFAULT_P2_ADVICE_VERSION);
        } catch (IllegalArgumentException ex) {
            return DEFAULT_P2_ADVICE_VERSION;
        }
    }

is better than this:

    private static final Pattern REACTOR_PROJECT_VERSION_PATTERN = Pattern
            .compile("((?:[0-9]+)(?:\\.(?:[0-9]+)(?:\\.(?:[0-9]+))?)?)?([.-][A-Za-z0-9_-]+)?");

    private static Version getVersion(ReactorProject reactorProject) {
        String version = reactorProject.getVersion();
        if (version == null) {
            return DEFAULT_P2_ADVICE_VERSION;
        }
        Matcher matcher = REACTOR_PROJECT_VERSION_PATTERN.matcher(version);
        if (!matcher.matches()) {
            return DEFAULT_P2_ADVICE_VERSION;
        }
        String qualifier = matcher.group(2);
        if (qualifier != null && qualifier.startsWith("-")) {
            if (TychoConstants.SUFFIX_SNAPSHOT.equals(qualifier)) {
                version = version.substring(0, version.length() - TychoConstants.SUFFIX_SNAPSHOT.length())
                        + TychoConstants.SUFFIX_QUALIFIER;
            } else {
                version = matcher.group(1) + '.' + qualifier.substring(1);
            }
        }
        try {
            return Version.parseVersion(version);
        } catch (IllegalAccessError ex) {
            return DEFAULT_P2_ADVICE_VERSION;
        }
    }

@merks merks force-pushed the pr-tp-factory-use-artifact-version branch from f14cee8 to 884534a Compare March 31, 2024 13:22
Currently the implementation hard codes the version to 1.0.0 when
parsing advice from a p2.inf.  This can result in an IAE if the version
is used in a range such as [1.0.0,$version$) where because [1.0.0,1.0.0)
is not a valid range. Instead use the reactor project's actual version.
@merks merks force-pushed the pr-tp-factory-use-artifact-version branch from 884534a to 7425d30 Compare March 31, 2024 13:41
@laeubi
Copy link
Member

laeubi commented Mar 31, 2024

It seemed to work okay for the particular tests directly affected, but apparently there isn't always a project manager

There are some unit test sadly that do not have a complete setup but in any real world usecase there is always a project manager.

@merks
Copy link
Contributor Author

merks commented Mar 31, 2024

There are some unit test sadly that do not have a complete setup but in any real world usecase there is always a project manager.

Ah, I see. So the guard is good for the test, and the other logic is a simpler expression that reuses existing infrastructure. So that's all goodness. Let's hope all the tests pass now.

@eclipse-tycho-bot
Copy link

💚 All backports created successfully

Status Branch Result
tycho-4.0.x

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation and see the Github Action logs for details

@merks merks deleted the pr-tp-factory-use-artifact-version branch April 2, 2024 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport-to-tycho-4.0.x Can be added to a PR to trigger an automatic backport of the change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants