diff --git a/tycho-compiler-plugin/src/main/java/org/eclipse/tycho/compiler/AbstractOsgiCompilerMojo.java b/tycho-compiler-plugin/src/main/java/org/eclipse/tycho/compiler/AbstractOsgiCompilerMojo.java index 191cf84373..897c31004f 100644 --- a/tycho-compiler-plugin/src/main/java/org/eclipse/tycho/compiler/AbstractOsgiCompilerMojo.java +++ b/tycho-compiler-plugin/src/main/java/org/eclipse/tycho/compiler/AbstractOsgiCompilerMojo.java @@ -69,7 +69,6 @@ import org.eclipse.tycho.classpath.JavaCompilerConfiguration; import org.eclipse.tycho.classpath.SourcepathEntry; import org.eclipse.tycho.core.BundleProject; -import org.eclipse.tycho.core.TychoConstants; import org.eclipse.tycho.core.TychoProject; import org.eclipse.tycho.core.dotClasspath.JREClasspathEntry; import org.eclipse.tycho.core.dotClasspath.M2ClasspathVariable; @@ -662,10 +661,9 @@ private void configureBootclasspathAccessRules(CompilerConfiguration compilerCon } } - @SuppressWarnings("unchecked") private List getStrictBootClasspathAccessRules() throws MojoExecutionException { - return (List) DefaultReactorProject.adapt(project) - .getContextValue(TychoConstants.CTX_ECLIPSE_PLUGIN_STRICT_BOOTCLASSPATH_ACCESSRULES); + return ((OsgiBundleProject) getBundleProject()).getBundleClassPath(DefaultReactorProject.adapt(project)) + .getStrictBootClasspathAccessRules(); } private void configureJavaHome(CompilerConfiguration compilerConfiguration) throws MojoExecutionException { diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/TychoConstants.java b/tycho-core/src/main/java/org/eclipse/tycho/core/TychoConstants.java index f470b9e6df..d4182282f7 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/TychoConstants.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/TychoConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2014 Sonatype Inc. and others. + * Copyright (c) 2008, 2021 Sonatype Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -24,15 +24,8 @@ public interface TychoConstants { */ static final String CTX_TEST_DEPENDENCY_ARTIFACTS = CTX_BASENAME + "/testDependencyArtifacts"; static final String CTX_ECLIPSE_PLUGIN_PROJECT = CTX_BASENAME + "/eclipsePluginProject"; - static final String CTX_ECLIPSE_PLUGIN_CLASSPATH = CTX_BASENAME + "/eclipsePluginClasspath"; - /** - * Stores test-specific classpath (usually derived from .classpath) - */ static final String CTX_ECLIPSE_PLUGIN_TEST_CLASSPATH = CTX_BASENAME + "/eclipsePluginTestClasspath"; - static final String CTX_ECLIPSE_PLUGIN_STRICT_BOOTCLASSPATH_ACCESSRULES = CTX_BASENAME - + "/eclipsePluginStrictBootclasspathAccessRules"; - static final String CTX_ECLIPSE_PLUGIN_BOOTCLASSPATH_EXTRA_ACCESSRULES = CTX_BASENAME - + "/eclipsePluginBootclasspathExtraAccessRules"; + static final String CTX_MERGED_PROPERTIES = CTX_BASENAME + "/mergedProperties"; static final String CTX_TARGET_PLATFORM_CONFIGURATION = CTX_BASENAME + "/targetPlatformConfiguration"; static final String CTX_EXECUTION_ENVIRONMENT_CONFIGURATION = CTX_BASENAME + "/executionEnvironmentConfiguration"; diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/AbstractTychoProject.java b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/AbstractTychoProject.java index d3196d5180..6b7d5b5add 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/AbstractTychoProject.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/AbstractTychoProject.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2012 Sonatype Inc. and others. + * Copyright (c) 2008, 2021 Sonatype Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Sonatype Inc. - initial API and implementation + * Christoph Läubrich - Issue #460 - Delay classpath resolution to the compile phase *******************************************************************************/ package org.eclipse.tycho.core.osgitools; @@ -73,10 +74,6 @@ public void setupProject(MavenSession session, MavenProject project) { public void checkForMissingDependencies(ReactorProject project) { } - public void resolveClassPath(MavenSession session, MavenProject project) { - // do nothing by default - } - protected TargetEnvironment[] getEnvironments(ReactorProject project, TargetEnvironment environment) { if (environment != null) { return new TargetEnvironment[] { environment }; diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/BundleClassPath.java b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/BundleClassPath.java new file mode 100644 index 0000000000..e698819bf4 --- /dev/null +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/BundleClassPath.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2021 Christoph Läubrich and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.tycho.core.osgitools; + +import java.util.Collections; +import java.util.List; + +import org.eclipse.tycho.classpath.ClasspathEntry; +import org.eclipse.tycho.classpath.ClasspathEntry.AccessRule; + +public class BundleClassPath { + + private List classpath; + private List strictBootClasspathAccessRules; + private List bootClasspathExtraAccessRules; + + BundleClassPath(List classpath, List strictBootClasspathAccessRules, + List bootClasspathExtraAccessRules) { + this.classpath = Collections.unmodifiableList(classpath); + this.strictBootClasspathAccessRules = Collections.unmodifiableList(strictBootClasspathAccessRules); + this.bootClasspathExtraAccessRules = Collections.unmodifiableList(bootClasspathExtraAccessRules); + } + + public List getClasspathEntries() { + return classpath; + } + + public List getStrictBootClasspathAccessRules() { + return strictBootClasspathAccessRules; + } + + public List getExtraBootClasspathAccessRules() { + return bootClasspathExtraAccessRules; + } + +} diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/OsgiBundleProject.java b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/OsgiBundleProject.java index 2f2a6586e7..b1b89bf3b0 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/OsgiBundleProject.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/OsgiBundleProject.java @@ -9,6 +9,7 @@ * Sonatype Inc. - initial API and implementation * Christoph Läubrich - [Bug 572416] Tycho does not understand "additional.bundles" directive in build.properties * [Bug 572416] Compile all source folders contained in .classpath + * [Issue #460] Delay classpath resolution to the compile phase *******************************************************************************/ package org.eclipse.tycho.core.osgitools; @@ -23,6 +24,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Properties; import java.util.Set; import java.util.regex.Matcher; @@ -89,7 +91,11 @@ @Component(role = TychoProject.class, hint = PackagingType.TYPE_ECLIPSE_PLUGIN) public class OsgiBundleProject extends AbstractTychoProject implements BundleProject { - private static final String CTX_ARTIFACT_KEY = TychoConstants.CTX_BASENAME + "/osgiBundle/artifactKey"; + private static final String CTX_OSGI_BUNDLE_BASENAME = TychoConstants.CTX_BASENAME + "/osgiBundle"; + private static final String CTX_ARTIFACT_KEY = CTX_OSGI_BUNDLE_BASENAME + "/artifactKey"; + private static final String CTX_MAVEN_SESSION = CTX_OSGI_BUNDLE_BASENAME + "/mavenSession"; + private static final String CTX_MAVEN_PROJECT = CTX_OSGI_BUNDLE_BASENAME + "/mavenProject"; + private static final String CTX_CLASSPATH = CTX_OSGI_BUNDLE_BASENAME + "/classPath"; @Requirement private BundleReader bundleReader; @@ -171,7 +177,20 @@ public ArtifactKey getArtifactKey(ReactorProject project) { @Override public void setupProject(MavenSession session, MavenProject project) { ArtifactKey key = readArtifactKey(project.getBasedir()); - DefaultReactorProject.adapt(project).setContextValue(CTX_ARTIFACT_KEY, key); + ReactorProject reactorProject = DefaultReactorProject.adapt(project); + reactorProject.setContextValue(CTX_ARTIFACT_KEY, key); + reactorProject.setContextValue(CTX_MAVEN_SESSION, session); + reactorProject.setContextValue(CTX_MAVEN_PROJECT, project); + } + + private MavenSession getMavenSession(ReactorProject reactorProject) { + return Objects.requireNonNull((MavenSession) reactorProject.getContextValue(CTX_MAVEN_SESSION), + "Project not setup correctly"); + } + + private MavenProject getMavenProject(ReactorProject reactorProject) { + return Objects.requireNonNull((MavenProject) reactorProject.getContextValue(CTX_MAVEN_PROJECT), + "Project not setup correctly"); } public ArtifactKey readArtifactKey(File location) { @@ -188,8 +207,8 @@ private OsgiManifest getManifest(ReactorProject project) { return bundleReader.loadManifest(project.getBasedir()); } - @Override - public void resolveClassPath(MavenSession session, MavenProject project) { + private BundleClassPath resolveClassPath(MavenSession session, MavenProject project) { + logger.info("Resolving class path of " + project.getName() + "..."); ReactorProject reactorProject = DefaultReactorProject.adapt(project); DependencyArtifacts artifacts = getDependencyArtifacts(reactorProject); @@ -247,13 +266,10 @@ public void resolveClassPath(MavenSession session, MavenProject project) { List projectClasspath = getThisProjectClasspath(artifact, reactorProject); classpath.add(new DefaultClasspathEntry(reactorProject, artifact.getKey(), projectClasspath, null)); - reactorProject.setContextValue(TychoConstants.CTX_ECLIPSE_PLUGIN_CLASSPATH, classpath); - reactorProject.setContextValue(TychoConstants.CTX_ECLIPSE_PLUGIN_STRICT_BOOTCLASSPATH_ACCESSRULES, - strictBootClasspathAccessRules); - reactorProject.setContextValue(TychoConstants.CTX_ECLIPSE_PLUGIN_BOOTCLASSPATH_EXTRA_ACCESSRULES, - dependencyComputer.computeBootClasspathExtraAccessRules(state)); + List bootClasspathExtraAccessRules = dependencyComputer.computeBootClasspathExtraAccessRules(state); addPDESourceRoots(project); + return new BundleClassPath(classpath, strictBootClasspathAccessRules, bootClasspathExtraAccessRules); } private Collection computeExtraTestClasspath(ReactorProject reactorProject) { @@ -365,24 +381,22 @@ private void populateProperties(Properties mavenProjectProperties, EclipsePlugin @Override public List getClasspath(ReactorProject project) { - @SuppressWarnings("unchecked") - List classpath = (List) project - .getContextValue(TychoConstants.CTX_ECLIPSE_PLUGIN_CLASSPATH); - if (classpath == null) { - throw new IllegalStateException(); - } - return classpath; + return getBundleClassPath(project).getClasspathEntries(); } @Override public List getBootClasspathExtraAccessRules(ReactorProject project) { - @SuppressWarnings("unchecked") - List rules = (List) project - .getContextValue(TychoConstants.CTX_ECLIPSE_PLUGIN_BOOTCLASSPATH_EXTRA_ACCESSRULES); - if (rules == null) { - throw new IllegalStateException(); + return getBundleClassPath(project).getExtraBootClasspathAccessRules(); + } + + public synchronized BundleClassPath getBundleClassPath(ReactorProject project) { + Object contextValue = project.getContextValue(CTX_CLASSPATH); + if (contextValue instanceof BundleClassPath) { + return (BundleClassPath) contextValue; } - return rules; + BundleClassPath cp = resolveClassPath(getMavenSession(project), getMavenProject(project)); + project.setContextValue(CTX_CLASSPATH, cp); + return cp; } /** @@ -485,7 +499,8 @@ private void addExtraClasspathEntries(List classpath, ReactorPro if (entry instanceof LibraryClasspathEntry) { LibraryClasspathEntry libraryClasspathEntry = (LibraryClasspathEntry) entry; ArtifactKey projectKey = getArtifactKey(project); - classpath.add(new DefaultClasspathEntry(project, projectKey, Collections.singletonList(libraryClasspathEntry.getLibraryPath()), null)); + classpath.add(new DefaultClasspathEntry(project, projectKey, + Collections.singletonList(libraryClasspathEntry.getLibraryPath()), null)); } } } diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/resolver/DefaultTychoResolver.java b/tycho-core/src/main/java/org/eclipse/tycho/core/resolver/DefaultTychoResolver.java index 58d30da4f5..1d76d61e0b 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/resolver/DefaultTychoResolver.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/resolver/DefaultTychoResolver.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2020 Sonatype Inc. and others. + * Copyright (c) 2008, 2021 Sonatype Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * Sonatype Inc. - initial API and implementation * Christoph Läubrich - Bug 532575 + * Christoph Läubrich - Issue #460 - Delay classpath resolution to the compile phase *******************************************************************************/ package org.eclipse.tycho.core.resolver; @@ -169,9 +170,6 @@ public List getExtraRequirements() { Objects.requireNonNullElse(testDependencyArtifacts, new DefaultDependencyArtifacts())); } - logger.info("Resolving class path of " + project); - dr.resolveClassPath(session, project); - resolver.injectDependenciesIntoMavenModel(project, dr, dependencyArtifacts, testDependencyArtifacts, logger); if (logger.isDebugEnabled() && DebugUtils.isDebugEnabled(session, project)) {