Skip to content

Commit

Permalink
Fix eclipse-tycho#460 Delay classpath resolution to the compile phase (
Browse files Browse the repository at this point in the history
…eclipse-tycho#461)

- Delay the classpath computation
- Add a ValidateClassPathMojo if earlier validation/computation is desired
  • Loading branch information
laeubi committed Dec 31, 2021
1 parent 1fe29d7 commit 4980ba6
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 45 deletions.
Expand Up @@ -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;
Expand Down Expand Up @@ -662,10 +661,9 @@ private void configureBootclasspathAccessRules(CompilerConfiguration compilerCon
}
}

@SuppressWarnings("unchecked")
private List<AccessRule> getStrictBootClasspathAccessRules() throws MojoExecutionException {
return (List<AccessRule>) 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 {
Expand Down
@@ -0,0 +1,51 @@
/*******************************************************************************
* 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.compiler;

import java.util.Map;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.eclipse.tycho.core.TychoProject;
import org.eclipse.tycho.core.osgitools.DefaultReactorProject;
import org.eclipse.tycho.core.osgitools.OsgiBundleProject;

/**
* This mojo could be added to a build if validation of the classpath is desired before the
* compile-phase.
*/
@Mojo(name = "validate-classpath", defaultPhase = LifecyclePhase.VALIDATE, requiresDependencyResolution = ResolutionScope.COMPILE, threadSafe = true)
public class ValidateClassPathMojo extends AbstractMojo {

@Parameter(property = "project", readonly = true)
private MavenProject project;

@Component(role = TychoProject.class)
private Map<String, TychoProject> projectTypes;

@Override
public void execute() throws MojoExecutionException, MojoFailureException {

TychoProject projectType = projectTypes.get(project.getPackaging());
if (projectType instanceof OsgiBundleProject) {
OsgiBundleProject bundleProject = (OsgiBundleProject) projectType;
bundleProject.getClasspath(DefaultReactorProject.adapt(project));
}
}

}
@@ -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
Expand All @@ -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";
Expand Down
@@ -1,12 +1,13 @@
/*******************************************************************************
* 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
* http://www.eclipse.org/legal/epl-v10.html
*
* 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;

Expand Down Expand Up @@ -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 };
Expand Down
@@ -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<ClasspathEntry> classpath;
private List<AccessRule> strictBootClasspathAccessRules;
private List<AccessRule> bootClasspathExtraAccessRules;

BundleClassPath(List<ClasspathEntry> classpath, List<AccessRule> strictBootClasspathAccessRules,
List<AccessRule> bootClasspathExtraAccessRules) {
this.classpath = Collections.unmodifiableList(classpath);
this.strictBootClasspathAccessRules = Collections.unmodifiableList(strictBootClasspathAccessRules);
this.bootClasspathExtraAccessRules = Collections.unmodifiableList(bootClasspathExtraAccessRules);
}

public List<ClasspathEntry> getClasspathEntries() {
return classpath;
}

public List<AccessRule> getStrictBootClasspathAccessRules() {
return strictBootClasspathAccessRules;
}

public List<AccessRule> getExtraBootClasspathAccessRules() {
return bootClasspathExtraAccessRules;
}

}
Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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);

Expand Down Expand Up @@ -247,13 +266,10 @@ public void resolveClassPath(MavenSession session, MavenProject project) {
List<File> 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<AccessRule> bootClasspathExtraAccessRules = dependencyComputer.computeBootClasspathExtraAccessRules(state);

addPDESourceRoots(project);
return new BundleClassPath(classpath, strictBootClasspathAccessRules, bootClasspathExtraAccessRules);
}

private Collection<ClasspathEntry> computeExtraTestClasspath(ReactorProject reactorProject) {
Expand Down Expand Up @@ -365,24 +381,22 @@ private void populateProperties(Properties mavenProjectProperties, EclipsePlugin

@Override
public List<ClasspathEntry> getClasspath(ReactorProject project) {
@SuppressWarnings("unchecked")
List<ClasspathEntry> classpath = (List<ClasspathEntry>) project
.getContextValue(TychoConstants.CTX_ECLIPSE_PLUGIN_CLASSPATH);
if (classpath == null) {
throw new IllegalStateException();
}
return classpath;
return getBundleClassPath(project).getClasspathEntries();
}

@Override
public List<ClasspathEntry.AccessRule> getBootClasspathExtraAccessRules(ReactorProject project) {
@SuppressWarnings("unchecked")
List<ClasspathEntry.AccessRule> rules = (List<AccessRule>) 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;
}

/**
Expand Down Expand Up @@ -485,7 +499,8 @@ private void addExtraClasspathEntries(List<ClasspathEntry> 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));
}
}
}
Expand Down
@@ -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
Expand All @@ -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;

Expand Down Expand Up @@ -169,9 +170,6 @@ public List<ArtifactKey> 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)) {
Expand Down

0 comments on commit 4980ba6

Please sign in to comment.