diff --git a/README.md b/README.md index 32c443a7e..bdf60133c 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,7 @@ ShrinkWrap Resolvers allows you to override any programmatic configuration via S - `maven.repo.local`: Path to local repository with cached artifacts. Overrides value defined in any of the settings.xml files. - `maven.legacyLocalRepo`: Flag whether to ignore origin tracking for artifacts present in local repository. +- `org.jboss.shrinkwrap.resolver.maven.skipCompilation`: Flag to skip compilation of resolved artifacts (true/false) - default is false. ## Embedded Maven diff --git a/maven/api-maven-archive/src/main/java/org/jboss/shrinkwrap/resolver/api/maven/archive/importer/PomlessMavenImporter.java b/maven/api-maven-archive/src/main/java/org/jboss/shrinkwrap/resolver/api/maven/archive/importer/PomlessMavenImporter.java index ffd972820..2228bf160 100644 --- a/maven/api-maven-archive/src/main/java/org/jboss/shrinkwrap/resolver/api/maven/archive/importer/PomlessMavenImporter.java +++ b/maven/api-maven-archive/src/main/java/org/jboss/shrinkwrap/resolver/api/maven/archive/importer/PomlessMavenImporter.java @@ -135,4 +135,17 @@ PomEquippedMavenImporter loadPomFromClassLoaderResource(String pathToPomResource * @return Modified {@link PomlessMavenImporter} instance */ PomlessMavenImporter offline(); + + /** + * Optional operation. Skip dependency compilation during import Default is false + * @param skip boolean flag + * @return this configured {@link MavenImporter} + */ + ConfiguredMavenImporter skipCompilation(boolean skip); + + /** + * Optional operation. Skip dependency compilation during import + * @return this configured {@link MavenImporter} + */ + ConfiguredMavenImporter skipCompilation(); } diff --git a/maven/api-maven/src/main/java/org/jboss/shrinkwrap/resolver/api/maven/MavenWorkingSession.java b/maven/api-maven/src/main/java/org/jboss/shrinkwrap/resolver/api/maven/MavenWorkingSession.java index 4542506ba..228ff95f8 100644 --- a/maven/api-maven/src/main/java/org/jboss/shrinkwrap/resolver/api/maven/MavenWorkingSession.java +++ b/maven/api-maven/src/main/java/org/jboss/shrinkwrap/resolver/api/maven/MavenWorkingSession.java @@ -139,4 +139,14 @@ Collection resolveDependencies(MavenResolutionStrategy st * @throws IllegalArgumentException if argument is null */ void addRemoteRepo(MavenRemoteRepository repository); + + /** + * @return true if dependency compilation is skipped + */ + boolean skipCompilation(); + + /** + * Optional operation. Skip dependency compilation during import + */ + void skipCompilation(boolean skip); } diff --git a/maven/impl-maven-archive/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/archive/importer/MavenImporterImpl.java b/maven/impl-maven-archive/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/archive/importer/MavenImporterImpl.java index bfada7cbe..07f511374 100644 --- a/maven/impl-maven-archive/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/archive/importer/MavenImporterImpl.java +++ b/maven/impl-maven-archive/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/archive/importer/MavenImporterImpl.java @@ -183,4 +183,14 @@ public PomlessMavenImporter offline() { return this.offline(true); } + @Override + public ConfiguredMavenImporter skipCompilation(boolean skip) { + session.skipCompilation(skip); + return this; + } + + @Override + public ConfiguredMavenImporter skipCompilation() { + return this.skipCompilation(true); + } } diff --git a/maven/impl-maven-archive/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/archive/packaging/AbstractCompilingProcessor.java b/maven/impl-maven-archive/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/archive/packaging/AbstractCompilingProcessor.java index 923d800dc..f87895171 100644 --- a/maven/impl-maven-archive/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/archive/packaging/AbstractCompilingProcessor.java +++ b/maven/impl-maven-archive/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/archive/packaging/AbstractCompilingProcessor.java @@ -52,21 +52,30 @@ public abstract class AbstractCompilingProcessor configure(MavenWorkingSession session) { this.session = session; + if (Boolean.getBoolean("org.jboss.shrinkwrap.resolver.maven.skipCompilation") || session.skipCompilation()) { + log.fine("Compilation was skipped due to system property org.jboss.shrinkwrap.resolver.maven.importer.skipCompilation being set to true"); + } else { + compiler = new JavacCompiler(); + } return this; } protected AbstractCompilingProcessor compile(File inputDirectory, File outputDirectory, ScopeType... scopes) { - Validate.notNullAndNoNullValues(scopes, "Cannot compile sources, there were no scopes defined"); Validate.notNull(inputDirectory, "Directory with sources to be compiled must not be null"); Validate.notNull(outputDirectory, "Target directory for compiled sources must not be null"); - JavacCompiler compiler = new JavacCompiler(); + if (compiler == null) { + log.warning("No compiler found, skipping compilation"); + return this; + } + CompilerConfiguration configuration = getCompilerConfiguration(); if (log.isLoggable(Level.FINE)) { diff --git a/maven/impl-maven-embedded/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/embedded/FileExtractor.java b/maven/impl-maven-embedded/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/embedded/FileExtractor.java index 3a136b5cf..84e89dd81 100644 --- a/maven/impl-maven-embedded/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/embedded/FileExtractor.java +++ b/maven/impl-maven-embedded/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/embedded/FileExtractor.java @@ -85,8 +85,9 @@ private void extractFileInDestinationDir() { } catch (IOException e) { System.err.println("Failed to unzip file: " + e.getMessage()); } - markerFileHandler.deleteMarkerFile(); - System.out.printf("Resolver: Successfully extracted maven binaries from %s%n", fileToExtract); + if (markerFileHandler.deleteMarkerFile()) { + System.out.printf("Resolver: Successfully extracted maven binaries from %s%n", fileToExtract); + } } private static InputStream getCompressorInputStream(String fileExtension, FileInputStream fileInputStream) throws IOException { diff --git a/maven/impl-maven-embedded/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/embedded/MarkerFileHandler.java b/maven/impl-maven-embedded/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/embedded/MarkerFileHandler.java index 72abf128c..cb062e368 100644 --- a/maven/impl-maven-embedded/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/embedded/MarkerFileHandler.java +++ b/maven/impl-maven-embedded/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/embedded/MarkerFileHandler.java @@ -23,10 +23,12 @@ void createMarkerFile() { } } - void deleteMarkerFile() { + boolean deleteMarkerFile() { if (markerFile.exists() && !markerFile.delete()) { log.warning("failed to delete marker file: " + markerFile); + return false; } + return true; } boolean waitTillMarkerFileIsGone(long timeoutInMilliseconds, String processName) { diff --git a/maven/impl-maven-embedded/src/test/java/org/jboss/shrinkwrap/resolver/impl/maven/embedded/pom/equipped/PomEquippedEmbeddedMavenRunningAsDaemonTestCase.java b/maven/impl-maven-embedded/src/test/java/org/jboss/shrinkwrap/resolver/impl/maven/embedded/pom/equipped/PomEquippedEmbeddedMavenRunningAsDaemonTestCase.java index 26a01594f..de41c684d 100644 --- a/maven/impl-maven-embedded/src/test/java/org/jboss/shrinkwrap/resolver/impl/maven/embedded/pom/equipped/PomEquippedEmbeddedMavenRunningAsDaemonTestCase.java +++ b/maven/impl-maven-embedded/src/test/java/org/jboss/shrinkwrap/resolver/impl/maven/embedded/pom/equipped/PomEquippedEmbeddedMavenRunningAsDaemonTestCase.java @@ -33,7 +33,7 @@ public void testDaemonShouldWaitForBuildSuccess() throws TimeoutException { .withWaitUntilOutputLineMatches(".*BUILD SUCCESS.*") .build(); - Awaitility.await("Wait till thread is not be alive").atMost(20, TimeUnit.SECONDS) + Awaitility.await("Wait till thread is not be alive").atMost(45, TimeUnit.SECONDS) .until(() -> !daemonBuild.isAlive()); Assertions.assertThat(daemonBuild.getBuiltProject()).isNotNull(); @@ -58,7 +58,7 @@ public void testDaemonWithoutWaitShouldNotReachTheEndOfTheBuild() { Assertions.assertThat(daemonBuild.isAlive()).isTrue(); Assertions.assertThat(daemonBuild.getBuiltProject()).isNull(); - Awaitility.await("Wait till thread is not be alive").atMost(20, TimeUnit.SECONDS) + Awaitility.await("Wait till thread is not be alive").atMost(45, TimeUnit.SECONDS) .until(() -> !daemonBuild.isAlive()); Assertions.assertThat(daemonBuild.isAlive()).isFalse(); diff --git a/maven/impl-maven/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/ConfigurableMavenWorkingSessionImpl.java b/maven/impl-maven/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/ConfigurableMavenWorkingSessionImpl.java index b059b0d18..c49993858 100644 --- a/maven/impl-maven/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/ConfigurableMavenWorkingSessionImpl.java +++ b/maven/impl-maven/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/ConfigurableMavenWorkingSessionImpl.java @@ -53,6 +53,7 @@ public abstract class ConfigurableMavenWorkingSessionImpl implements MavenWorkin private boolean useLegacyLocalRepository = false; private final MavenRepositorySystem system; private boolean disableClassPathWorkspaceReader = false; + private boolean skipCompilation = false; public ConfigurableMavenWorkingSessionImpl() { this.system = new MavenRepositorySystem(); @@ -98,6 +99,16 @@ public void useLegacyLocalRepository(boolean useLegacyLocalRepository) { this.useLegacyLocalRepository = useLegacyLocalRepository; } + @Override + public boolean skipCompilation() { + return this.skipCompilation; + } + + @Override + public void skipCompilation(boolean skip) { + this.skipCompilation = skip; + } + /** * Returns an instance of the {@link DefaultRepositorySystemSession} that is generated if it hasn't been yet. * diff --git a/maven/impl-maven/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/MavenWorkingSessionImpl.java b/maven/impl-maven/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/MavenWorkingSessionImpl.java index 1723ec26d..e4ae972d9 100644 --- a/maven/impl-maven/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/MavenWorkingSessionImpl.java +++ b/maven/impl-maven/src/main/java/org/jboss/shrinkwrap/resolver/impl/maven/MavenWorkingSessionImpl.java @@ -21,16 +21,21 @@ import eu.maveniverse.maven.mima.context.Runtime; import eu.maveniverse.maven.mima.context.Runtimes; import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.Properties; import java.util.Set; +import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collectors; import org.apache.maven.model.Model; import org.apache.maven.model.Profile; @@ -42,12 +47,16 @@ import org.apache.maven.model.building.ModelBuildingResult; import org.apache.maven.model.building.ModelProblem; import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.collection.CollectRequest; import org.eclipse.aether.collection.DependencyCollectionException; import org.eclipse.aether.collection.DependencySelector; +import org.eclipse.aether.graph.DefaultDependencyNode; +import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.repository.RemoteRepository.Builder; import org.eclipse.aether.repository.RepositoryPolicy; +import org.eclipse.aether.resolution.ArtifactRequest; import org.eclipse.aether.resolution.ArtifactResolutionException; import org.eclipse.aether.resolution.ArtifactResult; import org.eclipse.aether.resolution.DependencyResolutionException; @@ -188,6 +197,76 @@ public MavenWorkingSession loadPomFromFile(File pomFile, Properties userProperti return this; } + private Collection resolveProjectLocal(final List depsForResolution, + Set additionalDependencies) { + Collection projectLocalDependencies = new ArrayList<>(depsForResolution.size()); + for (MavenDependency dependency : depsForResolution) { + Path resolved = resolveProjectLocal(dependency.getGroupId(), dependency.getArtifactId(), + dependency.getVersion(), Optional.ofNullable(dependency.getClassifier()), + Optional.ofNullable(dependency.getPackaging().getExtension()), additionalDependencies); + if (resolved != null && resolved.toFile().exists()) { + Artifact artifact = new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(), + dependency.getClassifier(), dependency.getPackaging().getExtension(), dependency.getVersion(), + null, resolved.toFile()); + ArtifactResult result = new ArtifactResult(new ArtifactRequest() + .setDependencyNode(new DefaultDependencyNode( + new Dependency(artifact, dependency.getScope().name(), dependency.isOptional())))); + result.setArtifact(artifact); + projectLocalDependencies.add(result); + } + } + return projectLocalDependencies; + } + + private Path resolveProjectLocal(String groupId, String artifactId, String version, + Optional classifier, Optional extension, + Set additionalDependencies) { + Path findProjectLocalRepository = findProjectLocalRepository(); + if (findProjectLocalRepository == null) { + return null; + } + + Predicate isNotEmpty = s -> !s.isEmpty(); + Path directory = findProjectLocalRepository.resolve(groupId).resolve(artifactId).resolve(version); + String versionedArtifact = artifactId + "-" + version; + File consumerPom = directory.resolve(versionedArtifact + "-consumer.pom").toFile(); + if (consumerPom.exists()) { + additionalDependencies.addAll(loadPomFromFile(consumerPom).getParsedPomFile().getDependencies()); + } + + return findProjectLocalRepository.resolve(groupId).resolve(artifactId).resolve(version) + .resolve(versionedArtifact + + classifier.filter(isNotEmpty).map(c -> "-" + c).orElse("") + + "." + extension.filter(isNotEmpty).orElse("jar")); + } + + private List filterFromLocal(final List depsForResolution, + final Collection projectLocalDependencies) { + return depsForResolution.stream() + .filter(dependency -> projectLocalDependencies.stream() + .noneMatch(result -> MavenConverter.asArtifact(dependency, + getSession().getArtifactTypeRegistry()) + .setProperties(Collections.EMPTY_MAP) + .equals(result.getArtifact().setFile(null)))) + .collect(Collectors.toList()); + } + + /** + * @return absolute path to the project-local repository or null if not found + */ + private Path findProjectLocalRepository() { + Path targetPath = Paths.get("target/project-local-repo"); + Path currentPath = Paths.get("").toAbsolutePath(); + while (currentPath != null) { + Path path = currentPath.resolve(targetPath); + if (path.toFile().exists()) { + return path; + } + currentPath = currentPath.getParent(); + } + return null; + } + @Override public Collection resolveDependencies(final MavenResolutionStrategy strategy) throws ResolutionException { @@ -198,7 +277,12 @@ public Collection resolveDependencies(final MavenResoluti final List repos = this.getRemoteRepositories(); - final CollectRequest request = new CollectRequest(MavenConverter.asDependencies(depsForResolution, + Set allDependencies = new LinkedHashSet<>(depsForResolution); + Collection projectLocalDependencies = resolveProjectLocal(depsForResolution, allDependencies); + List unresolvedLocally = filterFromLocal( + allDependencies.stream().collect(Collectors.toList()), projectLocalDependencies); + + final CollectRequest request = new CollectRequest(MavenConverter.asDependencies(unresolvedLocally, getSession().getArtifactTypeRegistry()), MavenConverter.asDependencies(depManagement, getSession().getArtifactTypeRegistry()), repos); @@ -231,7 +315,11 @@ public Collection resolveDependencies(final MavenResoluti throw wrapException(e); } - final Collection resolvedArtifacts = new ArrayList<>(results.size()); + final Collection resolvedArtifacts = new ArrayList<>(results.size() + projectLocalDependencies.size()); + + for (final ArtifactResult result : projectLocalDependencies) { + resolvedArtifacts.add(MavenResolvedArtifactImpl.fromArtifactResult(result)); + } for (final ArtifactResult result : results) { resolvedArtifacts.add(MavenResolvedArtifactImpl.fromArtifactResult(result));