From 8d4d3459b01203d2ce35d7847874a88941960443 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Wed, 5 Jan 2022 12:21:20 +0200 Subject: [PATCH] Revert "Support for project modules that produce multiple JARs (with classifiers)" --- .../deployment/ApplicationArchiveImpl.java | 5 - .../io/quarkus/deployment/CodeGenerator.java | 6 +- .../quarkus/deployment/QuarkusAugmentor.java | 9 +- .../builditem/ArchiveRootBuildItem.java | 3 +- .../NativeImageResourcePatternsBuildItem.java | 2 +- .../deployment/dev/CompilationProvider.java | 5 +- .../deployment/dev/DevModeContext.java | 47 ++- .../quarkus/deployment/dev/DevModeMain.java | 23 +- .../deployment/dev/IDEDevModeMain.java | 60 ++-- .../dev/JavaCompilationProvider.java | 10 +- .../deployment/dev/QuarkusCompiler.java | 12 +- .../dev/QuarkusDevModeLauncher.java | 8 +- .../dev/RuntimeUpdatesProcessor.java | 24 +- .../deployment/dev/testing/TestSupport.java | 7 +- .../index/ApplicationArchiveBuildStep.java | 197 ++++++------- .../deployment/index/IndexingUtil.java | 77 ----- .../deployment/mutability/DevModeTask.java | 13 +- .../steps/ApplicationIndexBuildStep.java | 2 +- .../io/quarkus/deployment}/util/GlobUtil.java | 2 +- .../deployment}/util/GlobUtilTest.java | 3 +- .../DirectoryClassPathElementTestCase.java | 6 +- .../MemoryClassPathElementTestCase.java | 4 +- .../io/quarkus/gradle/tasks/QuarkusDev.java | 16 +- .../gradle/tasks/QuarkusGenerateCode.java | 4 +- .../gradle/tasks/QuarkusGradleUtils.java | 15 + .../GradleApplicationModelBuilder.java | 103 ++++--- .../main/java/io/quarkus/maven/DevMojo.java | 115 +++----- .../io/quarkus/maven/GenerateCodeMojo.java | 7 +- .../maven/QuarkusBootstrapProvider.java | 14 +- .../maven/QuarkusMavenWorkspaceBuilder.java | 25 +- .../quarkus/awt/deployment/AwtProcessor.java | 4 +- .../deployment/KotlinCompilationProvider.java | 4 +- .../deployment/ScalaCompilationProvider.java | 4 +- .../deployment/SmallRyeOpenApiProcessor.java | 27 +- .../deployment/HttpRootPathBuildItem.java | 3 +- .../http/deployment/VertxHttpProcessor.java | 56 ++-- .../devmode/console/DevConsoleProcessor.java | 143 +++++---- .../test/WebJarLocatorRootPathTest.java | 13 +- .../bootstrap/app-model/pom.xml | 4 - .../bootstrap/model/AppArtifactKey.java | 20 +- .../bootstrap/model/AppDependency.java | 2 +- .../bootstrap/util/BootstrapUtils.java | 2 +- .../io/quarkus/bootstrap/util/PathsUtils.java | 16 + .../bootstrap/workspace/ArtifactSources.java | 56 ---- .../workspace/DefaultArtifactSources.java | 53 ---- ...eDir.java => DefaultProcessedSources.java} | 49 +-- .../workspace/DefaultWorkspaceModule.java | 64 ++-- .../bootstrap/workspace/ProcessedSources.java | 14 + .../bootstrap/workspace/SourceDir.java | 25 -- .../bootstrap/workspace/WorkspaceModule.java | 30 +- .../maven/dependency/ArtifactDependency.java | 4 - .../quarkus/maven/dependency/Dependency.java | 4 +- .../io/quarkus/maven/dependency/GACT.java | 17 +- .../ResolvedArtifactDependency.java | 7 - .../maven/dependency/ResolvedDependency.java | 32 -- .../io/quarkus/paths/ArchivePathTree.java | 156 ---------- .../io/quarkus/paths/CachingPathTree.java | 191 ------------ .../io/quarkus/paths/DirectoryPathTree.java | 95 ------ .../java/io/quarkus/paths/EmptyPathTree.java | 50 ---- .../java/io/quarkus/paths/FilePathTree.java | 106 ------- .../io/quarkus/paths/MultiRootPathTree.java | 97 ------ .../java/io/quarkus/paths/OpenPathTree.java | 8 - .../java/io/quarkus/paths/PathCollection.java | 11 - .../java/io/quarkus/paths/PathFilter.java | 108 ------- .../main/java/io/quarkus/paths/PathList.java | 25 +- .../main/java/io/quarkus/paths/PathTree.java | 71 ----- .../io/quarkus/paths/PathTreeBuilder.java | 71 ----- .../java/io/quarkus/paths/PathTreeVisit.java | 122 -------- .../quarkus/paths/PathTreeWithManifest.java | 193 ------------ .../main/java/io/quarkus/paths/PathUtils.java | 26 -- .../main/java/io/quarkus/paths/PathVisit.java | 24 -- .../java/io/quarkus/paths/PathVisitor.java | 6 - independent-projects/bootstrap/core/pom.xml | 4 + .../bootstrap/BootstrapAppModelFactory.java | 10 +- .../io/quarkus/bootstrap/IDELauncherImpl.java | 30 +- .../bootstrap/app/AdditionalDependency.java | 6 + .../bootstrap/app/CuratedApplication.java | 102 +++---- .../bootstrap/app/QuarkusBootstrap.java | 35 +-- .../AbstractClassPathElement.java | 31 +- .../classloading/ClassPathElement.java | 53 +--- .../DirectoryClassPathElement.java | 19 +- .../FilteredClassPathElement.java | 18 -- .../classloading/JarClassPathElement.java | 23 +- .../classloading/MemoryClassPathElement.java | 17 +- .../PathTreeClassPathElement.java | 279 ------------------ .../classloading/QuarkusClassLoader.java | 14 +- .../bootstrap/devmode/DependenciesFilter.java | 34 +-- .../ClassLoadingInterruptTestCase.java | 2 +- .../ClassLoadingResourceUrlTestCase.java | 9 +- .../classloader/MultiReleaseJarTestCase.java | 4 +- .../resolver/BootstrapAppModelResolver.java | 87 ++++-- .../DeploymentInjectingDependencyVisitor.java | 57 +++- .../maven/workspace/LocalProject.java | 162 +++------- .../maven/workspace/LocalWorkspace.java | 55 ++-- .../test/LocalWorkspaceDiscoveryTest.java | 16 +- .../builder/QuarkusModelBuilderTest.java | 42 +-- .../java/io/quarkus/maven/it/DevMojoIT.java | 66 ----- .../java/io/quarkus/maven/it/PackageIT.java | 12 - .../projects/multijar-module/beans/pom.xml | 80 ----- .../src/main/java/org/acme/AcmeBean.java | 12 - .../src/main/java/org/acme/AcmeService.java | 8 - .../java/org/acme/AcmeServiceProducer.java | 15 - .../beans/src/main/java/org/acme/Named.java | 5 - .../beans/src/main/java/org/acme/Other.java | 12 - .../beans/src/main/java/org/acme/Printer.java | 16 - .../beans/src/main/java/org/acme/Service.java | 6 - .../src/main/resources/META-INF/beans.xml | 0 .../java/org/acme/testlib/TestMessage.java | 17 -- .../org/acme/testlib/mock/MockService.java | 10 - .../testlib/mock/MockServiceProducer.java | 15 - .../src/test/resources/META-INF/beans.xml | 0 .../src/test/resources/application.properties | 2 - .../projects/multijar-module/pom.xml | 78 ----- .../projects/multijar-module/runner/pom.xml | 139 --------- .../src/main/java/org/acme/HelloResource.java | 35 --- .../src/main/resources/application.properties | 4 - .../src/test/java/org/acme/ResourceTest.java | 38 --- .../jacoco/deployment/JacocoProcessor.java | 24 +- .../io/quarkus/test/QuarkusDevModeTest.java | 17 +- .../java/io/quarkus/test/QuarkusUnitTest.java | 2 +- .../AbstractJvmQuarkusTestExtension.java | 29 +- .../test/junit/IntegrationTestUtil.java | 30 +- 122 files changed, 981 insertions(+), 3637 deletions(-) rename {independent-projects/bootstrap/app-model/src/main/java/io/quarkus => core/deployment/src/main/java/io/quarkus/deployment}/util/GlobUtil.java (99%) rename {independent-projects/bootstrap/app-model/src/test/java/io/quarkus => core/deployment/src/test/java/io/quarkus/deployment}/util/GlobUtilTest.java (99%) create mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/util/PathsUtils.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/ArtifactSources.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultArtifactSources.java rename independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/{DefaultSourceDir.java => DefaultProcessedSources.java} (52%) create mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/ProcessedSources.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/SourceDir.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/ArchivePathTree.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/CachingPathTree.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/DirectoryPathTree.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/EmptyPathTree.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/FilePathTree.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/MultiRootPathTree.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/OpenPathTree.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathFilter.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTree.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTreeBuilder.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTreeVisit.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTreeWithManifest.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathUtils.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathVisit.java delete mode 100644 independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathVisitor.java delete mode 100644 independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/PathTreeClassPathElement.java delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/pom.xml delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/AcmeBean.java delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/AcmeService.java delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/AcmeServiceProducer.java delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Named.java delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Other.java delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Printer.java delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Service.java delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/resources/META-INF/beans.xml delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/java/org/acme/testlib/TestMessage.java delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/java/org/acme/testlib/mock/MockService.java delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/java/org/acme/testlib/mock/MockServiceProducer.java delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/resources/META-INF/beans.xml delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/resources/application.properties delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/pom.xml delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/runner/pom.xml delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/runner/src/main/java/org/acme/HelloResource.java delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/runner/src/main/resources/application.properties delete mode 100644 integration-tests/maven/src/test/resources/projects/multijar-module/runner/src/test/java/org/acme/ResourceTest.java diff --git a/core/deployment/src/main/java/io/quarkus/deployment/ApplicationArchiveImpl.java b/core/deployment/src/main/java/io/quarkus/deployment/ApplicationArchiveImpl.java index 3ede12215b0d8..5ec62ab2fc928 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/ApplicationArchiveImpl.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/ApplicationArchiveImpl.java @@ -65,11 +65,6 @@ public PathCollection getResolvedPaths() { } @Override - @Deprecated - /** - * @deprecated in favor of {@link #getKey()} - * @return archive key - */ public AppArtifactKey getArtifactKey() { return artifactKey == null ? null : new AppArtifactKey(artifactKey.getGroupId(), artifactKey.getArtifactId(), artifactKey.getClassifier(), diff --git a/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java b/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java index 5be736243a852..39a650eebf009 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java @@ -10,9 +10,9 @@ import java.util.function.Consumer; import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.prebuild.CodeGenException; import io.quarkus.deployment.codegen.CodeGenData; -import io.quarkus.paths.PathCollection; import io.quarkus.runtime.LaunchMode; import io.quarkus.runtime.configuration.ConfigUtils; import io.smallrye.config.PropertiesConfigSource; @@ -25,7 +25,7 @@ public class CodeGenerator { // used by Gradle and Maven public static void initAndRun(ClassLoader classLoader, - PathCollection sourceParentDirs, Path generatedSourcesDir, Path buildDir, + PathsCollection sourceParentDirs, Path generatedSourcesDir, Path buildDir, Consumer sourceRegistrar, ApplicationModel appModel, Properties properties, String launchMode) throws CodeGenException { List generators = init(classLoader, sourceParentDirs, generatedSourcesDir, buildDir, sourceRegistrar); @@ -36,7 +36,7 @@ public static void initAndRun(ClassLoader classLoader, } public static List init(ClassLoader deploymentClassLoader, - PathCollection sourceParentDirs, + PathsCollection sourceParentDirs, Path generatedSourcesDir, Path buildDir, Consumer sourceRegistrar) throws CodeGenException { diff --git a/core/deployment/src/main/java/io/quarkus/deployment/QuarkusAugmentor.java b/core/deployment/src/main/java/io/quarkus/deployment/QuarkusAugmentor.java index 832d8b3187eaa..5ae5264e33b2b 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/QuarkusAugmentor.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/QuarkusAugmentor.java @@ -18,6 +18,7 @@ import io.quarkus.bootstrap.classloading.QuarkusClassLoader; import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.builder.BuildChain; import io.quarkus.builder.BuildChainBuilder; import io.quarkus.builder.BuildExecutionBuilder; @@ -45,7 +46,7 @@ public class QuarkusAugmentor { private final ClassLoader classLoader; private final ClassLoader deploymentClassLoader; - private final PathCollection root; + private final PathsCollection root; private final Set> finalResults; private final List> buildChainCustomizers; private final LaunchMode launchMode; @@ -192,7 +193,7 @@ public static final class Builder { List additionalApplicationArchives = new ArrayList<>(); Collection excludedFromIndexing = Collections.emptySet(); ClassLoader classLoader; - PathCollection root; + PathsCollection root; Path targetDir; Set> finalResults = new HashSet<>(); private final List> buildChainCustomizers = new ArrayList<>(); @@ -273,7 +274,7 @@ public Builder setClassLoader(ClassLoader classLoader) { return this; } - public PathCollection getRoot() { + public PathsCollection getRoot() { return root; } @@ -282,7 +283,7 @@ public Builder addFinal(Class clazz) { return this; } - public Builder setRoot(PathCollection root) { + public Builder setRoot(PathsCollection root) { this.root = root; return this; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/ArchiveRootBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/ArchiveRootBuildItem.java index e773ef7393854..62b3826fc4d4b 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/ArchiveRootBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/ArchiveRootBuildItem.java @@ -13,7 +13,6 @@ import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.builder.item.SimpleBuildItem; import io.quarkus.fs.util.ZipUtils; -import io.quarkus.paths.PathCollection; public final class ArchiveRootBuildItem extends SimpleBuildItem { @@ -30,7 +29,7 @@ public Builder addArchiveRoot(Path root) { return this; } - public Builder addArchiveRoots(PathCollection paths) { + public Builder addArchiveRoots(PathsCollection paths) { paths.forEach(archiveRoots::add); return this; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/NativeImageResourcePatternsBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/NativeImageResourcePatternsBuildItem.java index d5dbc44c36d01..2b062767950af 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/NativeImageResourcePatternsBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/NativeImageResourcePatternsBuildItem.java @@ -8,7 +8,7 @@ import io.quarkus.builder.item.MultiBuildItem; import io.quarkus.deployment.pkg.NativeConfig; -import io.quarkus.util.GlobUtil; +import io.quarkus.deployment.util.GlobUtil; /** * A build item that indicates that a set of resource paths defined by regular expression patterns or globs should be diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/CompilationProvider.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/CompilationProvider.java index 334936d3b04b5..fb41ff763b174 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/CompilationProvider.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/CompilationProvider.java @@ -11,7 +11,7 @@ import java.util.List; import java.util.Set; -import io.quarkus.paths.PathCollection; +import io.quarkus.bootstrap.model.PathsCollection; public interface CompilationProvider extends Closeable { @@ -23,7 +23,7 @@ default Set handledSourcePaths() { void compile(Set files, Context context); - Path getSourcePath(Path classFilePath, PathCollection sourcePaths, String classesPath); + Path getSourcePath(Path classFilePath, PathsCollection sourcePaths, String classesPath); @Override default void close() throws IOException { @@ -58,6 +58,7 @@ public Context( String targetJvmVersion, List compilePluginArtifacts, List compilerPluginOptions) { + this.name = name; this.classpath = classpath; this.projectDirectory = projectDirectory; diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java index 823696138eb0f..b8b04379e8099 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeContext.java @@ -15,9 +15,9 @@ import java.util.Set; import io.quarkus.bootstrap.app.QuarkusBootstrap; +import io.quarkus.bootstrap.model.AppArtifactKey; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.maven.dependency.ArtifactKey; -import io.quarkus.paths.PathCollection; -import io.quarkus.paths.PathList; /** * Object that is used to pass context data from the plugin doing the invocation @@ -27,7 +27,7 @@ */ public class DevModeContext implements Serializable { - public static final CompilationUnit EMPTY_COMPILATION_UNIT = new CompilationUnit(PathList.of(), null, null, null); + public static final CompilationUnit EMPTY_COMPILATION_UNIT = new CompilationUnit(PathsCollection.of(), null, null, null); public static final String ENABLE_PREVIEW_FLAG = "--enable-preview"; @@ -59,7 +59,7 @@ public class DevModeContext implements Serializable { private String alternateEntryPoint; private QuarkusBootstrap.Mode mode = QuarkusBootstrap.Mode.DEV; private String baseName; - private final Set localArtifacts = new HashSet<>(); + private final Set localArtifacts = new HashSet<>(); public boolean isLocalProjectDiscovery() { return localProjectDiscovery; @@ -232,7 +232,7 @@ public void setBaseName(String baseName) { this.baseName = baseName; } - public Set getLocalArtifacts() { + public Set getLocalArtifacts() { return localArtifacts; } @@ -245,17 +245,16 @@ public static class ModuleInfo implements Serializable { private final CompilationUnit test; private final String preBuildOutputDir; - private final PathCollection sourceParents; + private final PathsCollection sourceParents; private final String targetDir; ModuleInfo(Builder builder) { this.appArtifactKey = builder.appArtifactKey; - this.name = builder.name == null ? builder.appArtifactKey.toGacString() : builder.name; + this.name = builder.name; this.projectDirectory = builder.projectDirectory; this.main = new CompilationUnit(builder.sourcePaths, builder.classesPath, builder.resourcePaths, builder.resourcesOutputPath); - if (builder.testClassesPath != null) { this.test = new CompilationUnit(builder.testSourcePaths, builder.testClassesPath, builder.testResourcePaths, builder.testResourcesOutputPath); @@ -275,7 +274,7 @@ public String getProjectDirectory() { return projectDirectory; } - public PathCollection getSourceParents() { + public PathsCollection getSourceParents() { return sourceParents; } @@ -313,18 +312,18 @@ public static class Builder { private ArtifactKey appArtifactKey; private String name; private String projectDirectory; - private PathCollection sourcePaths = PathList.of(); + private PathsCollection sourcePaths = PathsCollection.of(); private String classesPath; - private PathCollection resourcePaths = PathList.of(); + private PathsCollection resourcePaths = PathsCollection.of(); private String resourcesOutputPath; private String preBuildOutputDir; - private PathCollection sourceParents = PathList.of(); + private PathsCollection sourceParents = PathsCollection.of(); private String targetDir; - private PathCollection testSourcePaths = PathList.of(); + private PathsCollection testSourcePaths = PathsCollection.of(); private String testClassesPath; - private PathCollection testResourcePaths = PathList.of(); + private PathsCollection testResourcePaths = PathsCollection.of(); private String testResourcesOutputPath; public Builder setArtifactKey(ArtifactKey appArtifactKey) { @@ -342,7 +341,7 @@ public Builder setProjectDirectory(String projectDirectory) { return this; } - public Builder setSourcePaths(PathCollection sourcePaths) { + public Builder setSourcePaths(PathsCollection sourcePaths) { this.sourcePaths = sourcePaths; return this; } @@ -352,7 +351,7 @@ public Builder setClassesPath(String classesPath) { return this; } - public Builder setResourcePaths(PathCollection resourcePaths) { + public Builder setResourcePaths(PathsCollection resourcePaths) { this.resourcePaths = resourcePaths; return this; } @@ -367,7 +366,7 @@ public Builder setPreBuildOutputDir(String preBuildOutputDir) { return this; } - public Builder setSourceParents(PathCollection sourceParents) { + public Builder setSourceParents(PathsCollection sourceParents) { this.sourceParents = sourceParents; return this; } @@ -377,7 +376,7 @@ public Builder setTargetDir(String targetDir) { return this; } - public Builder setTestSourcePaths(PathCollection testSourcePaths) { + public Builder setTestSourcePaths(PathsCollection testSourcePaths) { this.testSourcePaths = testSourcePaths; return this; } @@ -387,7 +386,7 @@ public Builder setTestClassesPath(String testClassesPath) { return this; } - public Builder setTestResourcePaths(PathCollection testResourcePaths) { + public Builder setTestResourcePaths(PathsCollection testResourcePaths) { this.testResourcePaths = testResourcePaths; return this; } @@ -404,12 +403,12 @@ public ModuleInfo build() { } public static class CompilationUnit implements Serializable { - private PathCollection sourcePaths; + private PathsCollection sourcePaths; private final String classesPath; - private final PathCollection resourcePaths; + private final PathsCollection resourcePaths; private final String resourcesOutputPath; - public CompilationUnit(PathCollection sourcePaths, String classesPath, PathCollection resourcePaths, + public CompilationUnit(PathsCollection sourcePaths, String classesPath, PathsCollection resourcePaths, String resourcesOutputPath) { this.sourcePaths = sourcePaths; this.classesPath = classesPath; @@ -417,7 +416,7 @@ public CompilationUnit(PathCollection sourcePaths, String classesPath, PathColle this.resourcesOutputPath = resourcesOutputPath; } - public PathCollection getSourcePaths() { + public PathsCollection getSourcePaths() { return sourcePaths; } @@ -425,7 +424,7 @@ public String getClassesPath() { return classesPath; } - public PathCollection getResourcePaths() { + public PathsCollection getResourcePaths() { return resourcePaths; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeMain.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeMain.java index 1052ec948e798..a84e17c04f6b5 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeMain.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/DevModeMain.java @@ -22,13 +22,14 @@ import org.apache.commons.lang3.SystemUtils; import org.jboss.logging.Logger; +import io.quarkus.bootstrap.app.AdditionalDependency; import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; +import io.quarkus.bootstrap.model.AppArtifactKey; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.deployment.util.ProcessUtil; import io.quarkus.dev.appstate.ApplicationStateNotification; import io.quarkus.dev.spi.DevModeType; -import io.quarkus.maven.dependency.ArtifactKey; -import io.quarkus.paths.PathList; /** * The main entry point for the dev mojo execution @@ -86,8 +87,8 @@ public void start() throws Exception { } } } - final PathList.Builder appRoots = PathList.builder(); - Path p = Path.of(context.getApplicationRoot().getMain().getClassesPath()); + final PathsCollection.Builder appRoots = PathsCollection.builder(); + Path p = Paths.get(context.getApplicationRoot().getMain().getClassesPath()); if (Files.exists(p)) { appRoots.add(p); } @@ -115,10 +116,22 @@ public void start() throws Exception { } else { bootstrapBuilder.setProjectRoot(new File(".").toPath()); } - for (ArtifactKey i : context.getLocalArtifacts()) { + for (AppArtifactKey i : context.getLocalArtifacts()) { bootstrapBuilder.addLocalArtifact(i); } + for (DevModeContext.ModuleInfo i : context.getAdditionalModules()) { + if (i.getMain().getClassesPath() != null) { + Path classesPath = Paths.get(i.getMain().getClassesPath()); + bootstrapBuilder.addAdditionalApplicationArchive(new AdditionalDependency(classesPath, true, false)); + } + if (i.getMain().getResourcesOutputPath() != null + && !i.getMain().getResourcesOutputPath().equals(i.getMain().getClassesPath())) { + Path resourceOutputPath = Paths.get(i.getMain().getResourcesOutputPath()); + bootstrapBuilder.addAdditionalApplicationArchive(new AdditionalDependency(resourceOutputPath, true, false)); + } + } + linkDotEnvFile(); Properties buildSystemProperties = new Properties(); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/IDEDevModeMain.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/IDEDevModeMain.java index ab57f576f4dd5..f5ad2cc7224de 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/IDEDevModeMain.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/IDEDevModeMain.java @@ -14,16 +14,18 @@ import io.quarkus.bootstrap.BootstrapGradleException; import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.devmode.DependenciesFilter; +import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.resolver.AppModelResolverException; import io.quarkus.bootstrap.util.BootstrapUtils; import io.quarkus.bootstrap.utils.BuildToolHelper; -import io.quarkus.bootstrap.workspace.ArtifactSources; -import io.quarkus.bootstrap.workspace.SourceDir; +import io.quarkus.bootstrap.workspace.ProcessedSources; +import io.quarkus.bootstrap.workspace.WorkspaceModule; import io.quarkus.deployment.dev.DevModeContext.ModuleInfo; import io.quarkus.dev.spi.DevModeType; -import io.quarkus.maven.dependency.ResolvedDependency; -import io.quarkus.paths.PathList; +import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; public class IDEDevModeMain implements BiConsumer>, Closeable { @@ -48,14 +50,14 @@ public void accept(CuratedApplication curatedApplication, Map st } if (appModel != null) { - for (ResolvedDependency project : DependenciesFilter.getReloadableModules(appModel)) { + for (WorkspaceModule project : DependenciesFilter.getReloadableModules(appModel)) { final ModuleInfo module = toModule(project); - if (project.getKey().equals(appModel.getAppArtifact().getKey()) - && project.getVersion().equals(appModel.getAppArtifact().getVersion())) { + if (project == appModel.getApplicationModule()) { devModeContext.setApplicationRoot(module); } else { devModeContext.getAdditionalModules().add(module); - devModeContext.getLocalArtifacts().add(project.getKey()); + devModeContext.getLocalArtifacts() + .add(new AppArtifactKey(project.getId().getGroupId(), project.getId().getArtifactId())); } } } @@ -83,48 +85,40 @@ private void terminateIfRunning() { } } - private DevModeContext.ModuleInfo toModule(ResolvedDependency module) throws BootstrapGradleException { + private DevModeContext.ModuleInfo toModule(WorkspaceModule module) throws BootstrapGradleException { String classesDir = null; final Set sourceParents = new LinkedHashSet<>(); - final PathList.Builder srcPaths = PathList.builder(); - final ArtifactSources sources = module.getSources(); - for (SourceDir src : sources.getSourceDirs()) { - for (Path p : src.getSourceTree().getRoots()) { - sourceParents.add(p.getParent()); - if (!srcPaths.contains(p)) { - srcPaths.add(p); - } - } + final PathsCollection.Builder srcPaths = PathsCollection.builder(); + for (ProcessedSources src : module.getMainSources()) { + sourceParents.add(src.getSourceDir().getParentFile().toPath()); + srcPaths.add(src.getSourceDir().toPath()); if (classesDir == null) { - classesDir = src.getOutputDir().toString(); + classesDir = src.getDestinationDir().toString(); } } String resourceDirectory = null; - final PathList.Builder resourcesPaths = PathList.builder(); - for (SourceDir src : sources.getResourceDirs()) { - for (Path p : src.getSourceTree().getRoots()) { - if (!resourcesPaths.contains(p)) { - resourcesPaths.add(p); - } - } + final PathsCollection.Builder resourcesPaths = PathsCollection.builder(); + for (ProcessedSources src : module.getMainResources()) { + resourcesPaths.add(src.getSourceDir().toPath()); if (resourceDirectory == null) { // Peek the first one as we assume that it is the primary - resourceDirectory = src.getOutputDir().toString(); + resourceDirectory = src.getDestinationDir().toString(); } } + final ArtifactKey key = new GACT(module.getId().getGroupId(), module.getId().getArtifactId()); return new DevModeContext.ModuleInfo.Builder() - .setArtifactKey(module.getKey()) - .setProjectDirectory(module.getWorkspaceModule().getModuleDir().getPath()) + .setArtifactKey(key) + .setName(module.getId().getArtifactId()) + .setProjectDirectory(module.getModuleDir().getPath()) .setSourcePaths(srcPaths.build()) .setClassesPath(classesDir) .setResourcePaths(resourcesPaths.build()) .setResourcesOutputPath(resourceDirectory) - .setSourceParents(PathList.from(sourceParents)) - .setPreBuildOutputDir(module.getWorkspaceModule().getBuildDir().toPath().resolve("generated-sources") - .toAbsolutePath().toString()) - .setTargetDir(module.getWorkspaceModule().getBuildDir().toString()).build(); + .setSourceParents(PathsCollection.from(sourceParents)) + .setPreBuildOutputDir(module.getBuildDir().toPath().resolve("generated-sources").toAbsolutePath().toString()) + .setTargetDir(module.getBuildDir().toString()).build(); } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/JavaCompilationProvider.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/JavaCompilationProvider.java index 6957c6df0fbc0..e2faf52ad8a0c 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/JavaCompilationProvider.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/JavaCompilationProvider.java @@ -23,8 +23,8 @@ import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.gizmo.Gizmo; -import io.quarkus.paths.PathCollection; public class JavaCompilationProvider implements CompilationProvider { @@ -95,7 +95,7 @@ public void compile(Set filesToCompile, Context context) { } @Override - public Path getSourcePath(Path classFilePath, PathCollection sourcePaths, String classesPath) { + public Path getSourcePath(Path classFilePath, PathsCollection sourcePaths, String classesPath) { Path sourceFilePath = null; final RuntimeUpdatesClassVisitor visitor = new RuntimeUpdatesClassVisitor(sourcePaths, classesPath); try (final InputStream inputStream = Files.newInputStream(classFilePath)) { @@ -140,11 +140,11 @@ private static boolean ignoreWarningForNamespace(String message) { } static class RuntimeUpdatesClassVisitor extends ClassVisitor { - private final PathCollection sourcePaths; + private final PathsCollection sourcePaths; private final String classesPath; private String sourceFile; - public RuntimeUpdatesClassVisitor(PathCollection sourcePaths, String classesPath) { + public RuntimeUpdatesClassVisitor(PathsCollection sourcePaths, String classesPath) { super(Gizmo.ASM_API_VERSION); this.sourcePaths = sourcePaths; this.classesPath = classesPath; @@ -162,7 +162,7 @@ public Path getSourceFileForClass(final Path classFilePath) { sourceRelativeDir.append(classesDir.relativize(classFilePath.getParent())); sourceRelativeDir.append(File.separator); sourceRelativeDir.append(sourceFile); - final Path sourceFilePath = sourcesDir.resolve(Path.of(sourceRelativeDir.toString())); + final Path sourceFilePath = sourcesDir.resolve(Paths.get(sourceRelativeDir.toString())); if (Files.exists(sourceFilePath)) { return sourceFilePath; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/QuarkusCompiler.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/QuarkusCompiler.java index 51472ee12c0fe..2ab1114dd20b9 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/QuarkusCompiler.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/QuarkusCompiler.java @@ -23,8 +23,8 @@ import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.maven.dependency.ResolvedDependency; -import io.quarkus.paths.PathCollection; /** * Class that handles compilation of source files @@ -62,7 +62,7 @@ public QuarkusCompiler(CuratedApplication application, } Set paths = new HashSet<>(); for (ResolvedDependency i : application.getApplicationModel().getRuntimeDependencies()) { - for (Path p : i.getContentTree().getRoots()) { + for (Path p : i.getResolvedPaths()) { paths.add(p); } } @@ -157,11 +157,7 @@ public void setupSourceCompilationContext(DevModeContext context, Set clas return; } compilationUnit.getSourcePaths().forEach(sourcePath -> { - final String srcPathStr = sourcePath.toString(); - if (this.compilationContexts.containsKey(srcPathStr)) { - return; - } - this.compilationContexts.put(srcPathStr, + this.compilationContexts.put(sourcePath.toString(), new CompilationProvider.Context( i.getName(), classPathElements, @@ -195,7 +191,7 @@ public void compile(String sourceDir, Map> extensionToChangedF } } - public Path findSourcePath(Path classFilePath, PathCollection sourcePaths, String classesPath) { + public Path findSourcePath(Path classFilePath, PathsCollection sourcePaths, String classesPath) { for (CompilationProvider compilationProvider : compilationProviders) { Path sourcePath = compilationProvider.getSourcePath(classFilePath, sourcePaths, classesPath); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/QuarkusDevModeLauncher.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/QuarkusDevModeLauncher.java index 23cd0fc0a1590..685035cd46559 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/QuarkusDevModeLauncher.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/QuarkusDevModeLauncher.java @@ -30,8 +30,8 @@ import org.apache.maven.shared.utils.cli.CommandLineUtils; import io.quarkus.bootstrap.app.QuarkusBootstrap; +import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.deployment.dev.DevModeContext.ModuleInfo; -import io.quarkus.maven.dependency.ArtifactKey; import io.quarkus.runtime.util.JavaVersionUtil; import io.quarkus.utilities.JavaBinFinder; @@ -225,12 +225,12 @@ public B entryPointCustomizer(Consumer consumer) { } @SuppressWarnings("unchecked") - public B localArtifact(ArtifactKey localArtifact) { + public B localArtifact(AppArtifactKey localArtifact) { localArtifacts.add(localArtifact); return (B) this; } - public boolean isLocal(ArtifactKey artifact) { + public boolean isLocal(AppArtifactKey artifact) { return localArtifacts.contains(artifact); } @@ -297,7 +297,7 @@ public R build() throws Exception { private String baseName; private Consumer entryPointCustomizer; private String applicationArgs; - private Set localArtifacts = new HashSet<>(); + private Set localArtifacts = new HashSet<>(); private ModuleInfo main; private List dependencies = new ArrayList<>(0); private List classpath = new ArrayList<>(0); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java index aad0018167243..fe6faebe7ab43 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java @@ -3,6 +3,7 @@ import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toList; import java.io.ByteArrayInputStream; import java.io.Closeable; @@ -53,9 +54,9 @@ import org.jboss.jandex.Indexer; import org.jboss.logging.Logger; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.runner.Timing; import io.quarkus.changeagent.ClassChangeAgent; -import io.quarkus.deployment.dev.DevModeContext.ModuleInfo; import io.quarkus.deployment.dev.filewatch.FileChangeCallback; import io.quarkus.deployment.dev.filewatch.FileChangeEvent; import io.quarkus.deployment.dev.filewatch.WatchServiceFileSystemWatcher; @@ -68,8 +69,6 @@ import io.quarkus.dev.spi.HotReplacementContext; import io.quarkus.dev.spi.HotReplacementSetup; import io.quarkus.dev.testing.TestScanningLock; -import io.quarkus.paths.PathCollection; -import io.quarkus.paths.PathList; public class RuntimeUpdatesProcessor implements HotReplacementContext, Closeable { public static final boolean IS_LINUX = System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("linux"); @@ -190,13 +189,8 @@ public Path getClassesDir() { @Override public List getSourcesDir() { - final List paths = new ArrayList<>(); - for (ModuleInfo m : context.getAllModules()) { - for (Path p : m.getMain().getSourcePaths()) { - paths.add(p); - } - } - return paths; + return context.getAllModules().stream().flatMap(m -> m.getMain().getSourcePaths().toList().stream()) + .collect(toList()); } private void startTestScanningTimer() { @@ -847,12 +841,12 @@ Set checkForFileChange(Function moduleResources = correspondingResources.computeIfAbsent(compilationUnit, m -> Collections.newSetFromMap(new ConcurrentHashMap<>())); boolean doCopy = true; - PathCollection rootPaths = compilationUnit.getResourcePaths(); + PathsCollection rootPaths = compilationUnit.getResourcePaths(); String outputPath = compilationUnit.getResourcesOutputPath(); if (rootPaths.isEmpty()) { String rootPath = compilationUnit.getClassesPath(); if (rootPath != null) { - rootPaths = PathList.of(Paths.get(rootPath)); + rootPaths = PathsCollection.of(Paths.get(rootPath)); } outputPath = rootPath; doCopy = false; @@ -860,7 +854,7 @@ Set checkForFileChange(Function roots = rootPaths.stream() + final List roots = rootPaths.toList().stream() .filter(Files::exists) .filter(Files::isReadable) .collect(Collectors.toList()); @@ -1083,13 +1077,13 @@ private RuntimeUpdatesProcessor setWatchedFilePathsInternal(Map for (DevModeContext.ModuleInfo module : context.getAllModules()) { List compilationUnits = cuf.apply(module); for (DevModeContext.CompilationUnit unit : compilationUnits) { - PathCollection rootPaths = unit.getResourcePaths(); + PathsCollection rootPaths = unit.getResourcePaths(); if (rootPaths.isEmpty()) { String rootPath = unit.getClassesPath(); if (rootPath == null) { continue; } - rootPaths = PathList.of(Path.of(rootPath)); + rootPaths = PathsCollection.of(Paths.get(rootPath)); } for (Path root : rootPaths) { for (String path : watchedFilePaths.keySet()) { diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestSupport.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestSupport.java index 1d5ab9ee81424..34a38cf9ad02e 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestSupport.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestSupport.java @@ -27,6 +27,7 @@ import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; import io.quarkus.bootstrap.classloading.QuarkusClassLoader; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.deployment.dev.ClassScanResult; import io.quarkus.deployment.dev.CompilationProvider; import io.quarkus.deployment.dev.DevModeContext; @@ -34,7 +35,6 @@ import io.quarkus.deployment.dev.RuntimeUpdatesProcessor; import io.quarkus.dev.spi.DevModeType; import io.quarkus.dev.testing.TestWatchedFiles; -import io.quarkus.paths.PathList; import io.quarkus.runtime.configuration.HyphenateEnumConverter; public class TestSupport implements TestController { @@ -169,7 +169,7 @@ public void init() { } }); if (mainModule) { - curatedApplication.getQuarkusBootstrap().getApplicationRoot().forEach(paths::add); + paths.addAll(curatedApplication.getQuarkusBootstrap().getApplicationRoot().toList()); } else { paths.add(Paths.get(module.getMain().getClassesPath())); } @@ -189,8 +189,7 @@ public void init() { .setAuxiliaryApplication(true) .setHostApplicationIsTestOnly(devModeType == DevModeType.TEST_ONLY) .setProjectRoot(Paths.get(module.getProjectDirectory())) - .setApplicationRoot(PathList.from(paths)) - .clearLocalArtifacts() // we want to re-discover the local dependencies with test scope + .setApplicationRoot(PathsCollection.from(paths)) .build() .bootstrap(); if (mainModule) { diff --git a/core/deployment/src/main/java/io/quarkus/deployment/index/ApplicationArchiveBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/index/ApplicationArchiveBuildStep.java index 6a434ed9099ee..9c34d2b6c0f3d 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/index/ApplicationArchiveBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/index/ApplicationArchiveBuildStep.java @@ -1,20 +1,22 @@ package io.quarkus.deployment.index; +import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.UncheckedIOException; +import java.net.URI; +import java.net.URL; import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; +import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; +import java.util.stream.Stream; import org.jboss.jandex.CompositeIndex; import org.jboss.jandex.Index; @@ -22,8 +24,6 @@ import org.jboss.jandex.Indexer; import org.jboss.logging.Logger; -import io.quarkus.bootstrap.classloading.ClassPathElement; -import io.quarkus.bootstrap.classloading.QuarkusClassLoader; import io.quarkus.deployment.ApplicationArchive; import io.quarkus.deployment.ApplicationArchiveImpl; import io.quarkus.deployment.annotations.BuildProducer; @@ -39,15 +39,13 @@ import io.quarkus.deployment.configuration.ClassLoadingConfig; import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; import io.quarkus.fs.util.ZipUtils; +import io.quarkus.maven.dependency.ArtifactCoords; import io.quarkus.maven.dependency.ArtifactKey; import io.quarkus.maven.dependency.GACT; import io.quarkus.maven.dependency.GACTV; import io.quarkus.maven.dependency.ResolvedDependency; -import io.quarkus.paths.DirectoryPathTree; +import io.quarkus.paths.PathCollection; import io.quarkus.paths.PathList; -import io.quarkus.paths.PathTree; -import io.quarkus.paths.PathVisit; -import io.quarkus.paths.PathVisitor; import io.quarkus.runtime.annotations.ConfigDocMapKey; import io.quarkus.runtime.annotations.ConfigDocSection; import io.quarkus.runtime.annotations.ConfigItem; @@ -92,6 +90,11 @@ ApplicationArchivesBuildItem build( CurateOutcomeBuildItem curateOutcomeBuildItem, ClassLoadingConfig classLoadingConfig) throws IOException { + Set markerFiles = new HashSet<>(); + for (AdditionalApplicationArchiveMarkerBuildItem i : appMarkers) { + markerFiles.add(i.getFile()); + } + IndexCache indexCache = liveReloadContext.getContextObject(IndexCache.class); if (indexCache == null) { indexCache = new IndexCache(); @@ -104,7 +107,7 @@ ApplicationArchivesBuildItem build( } List applicationArchives = scanForOtherIndexes(buildCloseables, - appMarkers, root, additionalApplicationArchiveBuildItem, indexDependencyBuildItems, indexCache, + markerFiles, root, additionalApplicationArchiveBuildItem, indexDependencyBuildItems, indexCache, curateOutcomeBuildItem, removedResources); return new ApplicationArchivesBuildItem( new ApplicationArchiveImpl(appindex.getIndex(), PathList.from(root.getRootDirs()), @@ -113,7 +116,7 @@ ApplicationArchivesBuildItem build( } private List scanForOtherIndexes(QuarkusBuildCloseablesBuildItem buildCloseables, - List appMarkers, + Set applicationArchiveFiles, ArchiveRootBuildItem root, List additionalApplicationArchives, List indexDependencyBuildItem, IndexCache indexCache, CurateOutcomeBuildItem curateOutcomeBuildItem, Map> removedResources) @@ -123,11 +126,7 @@ private List scanForOtherIndexes(QuarkusBuildCloseablesBuild Set indexedPaths = new HashSet<>(); //get paths that are included via marker files - final Set markers = new HashSet<>(appMarkers.size() + 1); - for (AdditionalApplicationArchiveMarkerBuildItem i : appMarkers) { - final String marker = i.getFile(); - markers.add(marker.endsWith("/") ? marker.substring(0, marker.length() - 1) : marker); - } + Set markers = new HashSet<>(applicationArchiveFiles); markers.add(IndexingUtil.JANDEX_INDEX); addMarkerFilePaths(markers, root, curateOutcomeBuildItem, indexedPaths, appArchives, buildCloseables, indexCache, removedResources); @@ -173,7 +172,7 @@ private void addIndexDependencyPaths(List indexDepende throw new RuntimeException( "Could not resolve artifact " + key + " among the runtime dependencies of the application"); } - for (Path path : artifact.getContentTree().getRoots()) { + for (Path path : artifact.getResolvedPaths()) { if (!root.isExcludedFromIndexing(path) && !root.getPaths().contains(path) && indexedDeps.add(path)) { appArchives.add(createApplicationArchive(buildCloseables, indexCache, path, key, removedResources)); @@ -188,119 +187,107 @@ private void addIndexDependencyPaths(List indexDepende private static ApplicationArchive createApplicationArchive(QuarkusBuildCloseablesBuildItem buildCloseables, IndexCache indexCache, Path dep, ArtifactKey artifactKey, Map> removedResources) throws IOException { - LOGGER.debugf("Indexing dependency: %s", dep); - final Set removed = removedResources.get(artifactKey); Path rootDir = dep; - final IndexView index; - if (Files.isDirectory(dep)) { - index = indexPathTree(new DirectoryPathTree(dep), removed); - } else { + boolean isDirectory = Files.isDirectory(dep); + if (!isDirectory) { final FileSystem fs = buildCloseables.add(ZipUtils.newFileSystem(dep)); rootDir = fs.getRootDirectories().iterator().next(); - index = handleJarPath(dep, indexCache, removed); } + final IndexView index = indexPath(indexCache, dep, removedResources.get(artifactKey), isDirectory); return new ApplicationArchiveImpl(index, rootDir, dep, artifactKey); } + private static IndexView indexPath(IndexCache indexCache, Path dep, Set removed, boolean isWorkspaceModule) + throws IOException { + LOGGER.debugf("Indexing dependency: %s", dep); + return isWorkspaceModule ? handleFilePath(dep, removed) : handleJarPath(dep, indexCache, removed); + } + private static void addMarkerFilePaths(Set applicationArchiveMarkers, ArchiveRootBuildItem root, CurateOutcomeBuildItem curateOutcomeBuildItem, Set indexedPaths, List appArchives, QuarkusBuildCloseablesBuildItem buildCloseables, IndexCache indexCache, Map> removed) throws IOException { - final QuarkusClassLoader cl = ((QuarkusClassLoader) Thread.currentThread().getContextClassLoader()); - final Set indexedElements = new HashSet<>(); + + Set markedUris = new HashSet<>(); for (String marker : applicationArchiveMarkers) { - final List elements = cl.getElementsWithResource(marker, false); - if (elements.isEmpty()) { + Enumeration resources = Thread.currentThread().getContextClassLoader().getResources(marker); + + while (resources.hasMoreElements()) { + URL resource = resources.nextElement(); + String s = resource.toString(); + if ("jar".equals(resource.getProtocol())) { + // Path is in the format jar:file:/path/to/jarfile.jar!/META-INF/jandex.idx. Only the path to jar + // is needed, for comparisons and opening fs. Remove the protocol an path inside jar here. + // Results in file:/path/to/jarfile.jar + s = s.substring(4, s.lastIndexOf("!")); + } else if ("file".equals(resource.getProtocol())) { + s = s.substring(0, s.length() - marker.length()); + } + markedUris.add(URI.create(s)); + } + } + + List applicationArchives = new ArrayList<>(); + for (ResolvedDependency dep : curateOutcomeBuildItem.getApplicationModel().getRuntimeDependencies()) { + if (!ArtifactCoords.TYPE_JAR.equals(dep.getType())) { continue; } - for (ClassPathElement cpe : elements) { - if (!cpe.isRuntime()) { + + final PathCollection artifactPaths = dep.getResolvedPaths(); + for (Path p : artifactPaths) { + if (root.isExcludedFromIndexing(p)) { continue; } - final ArtifactKey dependencyKey = cpe.getDependencyKey(); - if (dependencyKey == null || !indexedElements.add(dependencyKey)) { - continue; + + if (markedUris.contains(p.toUri())) { + applicationArchives.add(dep); + break; } - cpe.withOpenTree(tree -> { - indexedPaths.addAll(tree.getOriginalTree().getRoots()); - - final Path rootPath = tree.getOriginalTree().getRoots().size() == 1 - ? tree.getOriginalTree().getRoots().iterator().next() - : null; - if (rootPath != null && !Files.isDirectory(rootPath)) { - if (root.isExcludedFromIndexing(rootPath)) { - return null; - } - Index index = indexCache.cache.get(rootPath); - if (index == null) { - try { - index = IndexingUtil.indexTree(tree, - dependencyKey == null ? Collections.emptySet() : removed.get(dependencyKey)); - } catch (IOException ioe) { - throw new UncheckedIOException(ioe); - } - indexCache.cache.put(rootPath, index); - } - appArchives.add(new ApplicationArchiveImpl(index, PathList.of(tree.getRoots().iterator().next()), - PathList.of(rootPath), - dependencyKey)); - return null; - } + } + } - final ApplicationArchive archive = tree.processPath(marker, visit -> { - if (visit == null || root.isExcludedFromIndexing(visit.getRoot())) { - return null; - } - - final PathList.Builder rootDirs = PathList.builder(); - final Collection artifactPaths = tree.getRoots(); - final List indexes = new ArrayList<>(artifactPaths.size()); - for (Path p : artifactPaths) { - if (Files.isDirectory(p)) { - rootDirs.add(p); - } else { - rootDirs.add(visit.getPath().getRoot()); - } - } - try { - indexes.add(indexPathTree(tree, removed.get(dependencyKey))); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - return new ApplicationArchiveImpl( - indexes.size() == 1 ? indexes.get(0) : CompositeIndex.create(indexes), - rootDirs.build(), PathList.from(artifactPaths), dependencyKey); - }); - if (archive != null) { - appArchives.add(archive); - } - return null; - }); + for (ResolvedDependency dep : applicationArchives) { + final PathList.Builder rootDirs = PathList.builder(); + final PathCollection artifactPaths = dep.getResolvedPaths(); + final List indexes = new ArrayList<>(artifactPaths.size()); + for (Path p : artifactPaths) { + boolean isDirectory = Files.isDirectory(p); + if (isDirectory) { + rootDirs.add(p); + } else { + FileSystem fs = ZipUtils.newFileSystem(p); + buildCloseables.add(fs); + fs.getRootDirectories().forEach(rootDirs::add); + } + indexes.add(indexPath(indexCache, p, removed.get(dep.getKey()), isDirectory)); + indexedPaths.add(p); } + appArchives + .add(new ApplicationArchiveImpl(indexes.size() == 1 ? indexes.get(0) : CompositeIndex.create(indexes), + rootDirs.build(), artifactPaths, dep.getKey())); } } - private static Index indexPathTree(PathTree tree, Set removed) throws IOException { + private static Index handleFilePath(Path path, Set removed) throws IOException { Indexer indexer = new Indexer(); - tree.walk(new PathVisitor() { - @Override - public void visitPath(PathVisit visit) { - final Path path = visit.getPath(); - final Path fileName = path.getFileName(); - if (fileName == null - || !fileName.toString().endsWith(".class") - || Files.isDirectory(path) - || removed != null && removed.contains(visit.getRelativePath("/"))) { - return; + try (Stream stream = Files.walk(path)) { + stream.forEach(path1 -> { + if (removed != null) { + String relative = path.relativize(path1).toString().replace("\\", "/"); + if (removed.contains(relative)) { + return; + } } - try (InputStream in = Files.newInputStream(path)) { - indexer.index(in); - } catch (IOException e) { - throw new RuntimeException(e); + if (path1.toString().endsWith(".class")) { + try (FileInputStream in = new FileInputStream(path1.toFile())) { + indexer.index(in); + } catch (IOException e) { + throw new RuntimeException(e); + } } - } - }); + }); + } return indexer.complete(); } @@ -322,6 +309,8 @@ public Index apply(Path path) { * to re-index them each time. We cache them here to reduce the hot reload time. */ private static final class IndexCache { + final Map cache = new HashMap<>(); + } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/index/IndexingUtil.java b/core/deployment/src/main/java/io/quarkus/deployment/index/IndexingUtil.java index 06f81cabb748c..84c056ff863ea 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/index/IndexingUtil.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/index/IndexingUtil.java @@ -7,13 +7,10 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.UncheckedIOException; -import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; import java.util.Enumeration; import java.util.Set; -import java.util.function.Function; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipEntry; @@ -28,9 +25,6 @@ import org.jboss.logging.Logger; import io.quarkus.deployment.util.IoUtil; -import io.quarkus.paths.OpenPathTree; -import io.quarkus.paths.PathVisit; -import io.quarkus.paths.PathVisitor; import io.smallrye.common.io.jar.JarFiles; public class IndexingUtil { @@ -56,19 +50,6 @@ public static Index indexJar(Path path, Set removed) throws IOException return indexJar(path.toFile(), removed); } - public static Index indexTree(OpenPathTree tree, Set removed) throws IOException { - if (removed == null) { - final Index i = tree.processPath(JANDEX_INDEX, MetaInfJandexReader.getInstance()); - if (i != null) { - return i; - } - } - final Indexer indexer = new Indexer(); - final PathTreeIndexer treeIndexer = new PathTreeIndexer(indexer, removed); - tree.walk(treeIndexer); - return indexer.complete(); - } - public static Index indexJar(File file, Set removed) throws IOException { try (JarFile jarFile = new JarFile(file)) { ZipEntry existing = jarFile.getEntry(JANDEX_INDEX); @@ -200,62 +181,4 @@ public static void indexClass(String className, Indexer indexer, } } - private static class PathTreeIndexer implements PathVisitor { - - final Indexer indexer; - final Set removed; - - PathTreeIndexer(Indexer indexer, Set removed) { - this.indexer = indexer; - this.removed = removed; - } - - @Override - public void visitPath(PathVisit visit) { - final Path fileName = visit.getPath().getFileName(); - if (fileName == null || - !fileName.toString().endsWith(".class") || - Files.isDirectory(visit.getPath()) || - removed != null && removed.contains(visit.getRelativePath("/"))) { - return; - } - try (InputStream inputStream = Files.newInputStream(visit.getPath())) { - indexer.index(inputStream); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - } - - private static class MetaInfJandexReader implements Function { - private static MetaInfJandexReader instance; - - private static MetaInfJandexReader getInstance() { - return instance == null ? instance = new MetaInfJandexReader() : instance; - } - - @Override - public Index apply(PathVisit visit) { - if (visit == null) { - return null; - } - try (InputStream in = Files.newInputStream(visit.getPath())) { - IndexReader reader = new IndexReader(in); - if (reader.getIndexVersion() < REQUIRED_INDEX_VERSION) { - log.warnf( - "Re-indexing %s - at least Jandex 2.1 must be used to index an application dependency", - visit.getPath()); - return null; - } - try { - return reader.read(); - } catch (UnsupportedVersion e) { - throw new UnsupportedVersion( - "Can't read Jandex index from " + visit.getPath() + ": " + e.getMessage()); - } - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/mutability/DevModeTask.java b/core/deployment/src/main/java/io/quarkus/deployment/mutability/DevModeTask.java index 385f1ad4c1c09..3c97e1aedd7f6 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/mutability/DevModeTask.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/mutability/DevModeTask.java @@ -31,6 +31,7 @@ import io.quarkus.deployment.pkg.steps.JarResultBuildStep; import io.quarkus.dev.spi.DevModeType; import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; import io.quarkus.maven.dependency.ResolvedArtifactDependency; import io.quarkus.maven.dependency.ResolvedDependency; import io.quarkus.paths.PathList; @@ -80,8 +81,8 @@ private static DevModeContext createDevModeContext(Path appRoot, ApplicationMode public void run(ResolvedDependency dep, Path moduleClasses, boolean appArtifact) { ((ResolvedArtifactDependency) dep).setResolvedPaths(PathList.of(moduleClasses)); - DevModeContext.ModuleInfo module = new DevModeContext.ModuleInfo.Builder() - .setArtifactKey(dep.getKey()) + DevModeContext.ModuleInfo module = new DevModeContext.ModuleInfo.Builder().setArtifactKey(dep.getKey()) + .setName(dep.getArtifactId()) .setClassesPath(moduleClasses.toAbsolutePath().toString()) .setResourcesOutputPath(moduleClasses.toAbsolutePath().toString()) .build(); @@ -96,15 +97,16 @@ public void run(ResolvedDependency dep, Path moduleClasses, boolean appArtifact) context.setAbortOnFailedStart(false); context.setLocalProjectDiscovery(false); return context; + } public static void extractDevModeClasses(Path appRoot, ApplicationModel appModel, PostExtractAction postExtractAction) throws IOException { Path extracted = appRoot.resolve("dev"); Files.createDirectories(extracted); - final Map rtDependencies = new HashMap<>(); + Map rtDependencies = new HashMap<>(); for (ResolvedDependency i : appModel.getRuntimeDependencies()) { - rtDependencies.put(i.getKey(), i); + rtDependencies.put(new GACT(i.getGroupId(), i.getArtifactId()), i); } //setup the classes that can be hot reloaded @@ -115,7 +117,8 @@ public static void extractDevModeClasses(Path appRoot, ApplicationModel appModel ResolvedDependency dep = rtDependencies.get(i); Path moduleClasses = null; if (dep == null) { - appArtifact = appModel.getAppArtifact().getKey().equals(i); + appArtifact = i.getGroupId().equals(appModel.getAppArtifact().getGroupId()) + && i.getArtifactId().equals(appModel.getAppArtifact().getArtifactId()); //check if this is the application itself if (appArtifact) { dep = appModel.getAppArtifact(); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/ApplicationIndexBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/ApplicationIndexBuildStep.java index b400a25f0a2c0..3d7f9dc91faad 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/ApplicationIndexBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/ApplicationIndexBuildStep.java @@ -32,7 +32,7 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (file.getFileName().toString().endsWith(".class")) { + if (file.toString().endsWith(".class")) { log.debugf("Indexing %s", file); try (InputStream stream = Files.newInputStream(file)) { indexer.index(stream); diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/util/GlobUtil.java b/core/deployment/src/main/java/io/quarkus/deployment/util/GlobUtil.java similarity index 99% rename from independent-projects/bootstrap/app-model/src/main/java/io/quarkus/util/GlobUtil.java rename to core/deployment/src/main/java/io/quarkus/deployment/util/GlobUtil.java index 84ce28d1a1ae7..7b7ccbb1d272d 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/util/GlobUtil.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/util/GlobUtil.java @@ -1,4 +1,4 @@ -package io.quarkus.util; +package io.quarkus.deployment.util; import java.util.regex.Pattern; diff --git a/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/util/GlobUtilTest.java b/core/deployment/src/test/java/io/quarkus/deployment/util/GlobUtilTest.java similarity index 99% rename from independent-projects/bootstrap/app-model/src/test/java/io/quarkus/util/GlobUtilTest.java rename to core/deployment/src/test/java/io/quarkus/deployment/util/GlobUtilTest.java index d3df4885a7c7b..6d60735286e3e 100644 --- a/independent-projects/bootstrap/app-model/src/test/java/io/quarkus/util/GlobUtilTest.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/util/GlobUtilTest.java @@ -1,10 +1,11 @@ -package io.quarkus.util; +package io.quarkus.deployment.util; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/core/deployment/src/test/java/io/quarkus/runner/classloading/DirectoryClassPathElementTestCase.java b/core/deployment/src/test/java/io/quarkus/runner/classloading/DirectoryClassPathElementTestCase.java index 01cebd094c6a6..ed372c921f315 100644 --- a/core/deployment/src/test/java/io/quarkus/runner/classloading/DirectoryClassPathElementTestCase.java +++ b/core/deployment/src/test/java/io/quarkus/runner/classloading/DirectoryClassPathElementTestCase.java @@ -37,7 +37,7 @@ public static void after() throws Exception { @Test public void testGetAllResources() { - DirectoryClassPathElement f = new DirectoryClassPathElement(root, true); + DirectoryClassPathElement f = new DirectoryClassPathElement(root); Set res = f.getProvidedResources(); Assertions.assertEquals(4, res.size()); Assertions.assertEquals(new HashSet<>(Arrays.asList("a.txt", "b.txt", "foo", "foo/sub.txt")), res); @@ -45,7 +45,7 @@ public void testGetAllResources() { @Test public void testGetResource() { - DirectoryClassPathElement f = new DirectoryClassPathElement(root, true); + DirectoryClassPathElement f = new DirectoryClassPathElement(root); ClassPathResource res = f.getResource("foo/sub.txt"); Assertions.assertNotNull(res); Assertions.assertEquals("subdir file", new String(res.getData(), StandardCharsets.UTF_8)); @@ -59,7 +59,7 @@ public void testInvalidPath() { } else { invalidPath = "hello\u0000world"; } - final DirectoryClassPathElement classPathElement = new DirectoryClassPathElement(root, true); + final DirectoryClassPathElement classPathElement = new DirectoryClassPathElement(root); final ClassPathResource resource = classPathElement.getResource(invalidPath); Assertions.assertNull(resource, "DirectoryClassPathElement wasn't expected to return a resource for an invalid path"); } diff --git a/core/deployment/src/test/java/io/quarkus/runner/classloading/MemoryClassPathElementTestCase.java b/core/deployment/src/test/java/io/quarkus/runner/classloading/MemoryClassPathElementTestCase.java index b48c68526b064..282e297a10e4f 100644 --- a/core/deployment/src/test/java/io/quarkus/runner/classloading/MemoryClassPathElementTestCase.java +++ b/core/deployment/src/test/java/io/quarkus/runner/classloading/MemoryClassPathElementTestCase.java @@ -34,7 +34,7 @@ public static void after() throws Exception { @Test public void testGetAllResources() { - MemoryClassPathElement f = new MemoryClassPathElement(data, true); + MemoryClassPathElement f = new MemoryClassPathElement(data); Set res = f.getProvidedResources(); Assertions.assertEquals(3, res.size()); Assertions.assertEquals(new HashSet<>(Arrays.asList("a.txt", "b.txt", "foo/sub.txt")), res); @@ -42,7 +42,7 @@ public void testGetAllResources() { @Test public void testGetResource() { - MemoryClassPathElement f = new MemoryClassPathElement(data, true); + MemoryClassPathElement f = new MemoryClassPathElement(data); ClassPathResource res = f.getResource("foo/sub.txt"); Assertions.assertNotNull(res); Assertions.assertEquals("subdir file", new String(res.getData(), StandardCharsets.UTF_8)); diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java index cb7c22a029fb7..88ebef62663c2 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusDev.java @@ -40,11 +40,11 @@ import io.quarkus.bootstrap.BootstrapConstants; import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.deployment.dev.DevModeContext; import io.quarkus.deployment.dev.QuarkusDevModeLauncher; import io.quarkus.gradle.tooling.ToolingUtils; import io.quarkus.maven.dependency.GACT; -import io.quarkus.paths.PathList; import io.quarkus.runtime.LaunchMode; public class QuarkusDev extends QuarkusTask { @@ -342,7 +342,7 @@ private void addSelfWithLocalDeps(Project project, GradleDevModeLauncher.Builder } private void addLocalProject(Project project, GradleDevModeLauncher.Builder builder, Set addeDeps, boolean root) { - final GACT key = new GACT(project.getGroup().toString(), project.getName(), "", "jar"); + final GACT key = new GACT(project.getGroup().toString(), project.getName()); if (addeDeps.contains(key)) { return; } @@ -399,14 +399,14 @@ private void addLocalProject(Project project, GradleDevModeLauncher.Builder buil } DevModeContext.ModuleInfo.Builder moduleBuilder = new DevModeContext.ModuleInfo.Builder() - .setArtifactKey(key) + .setArtifactKey(new GACT(key.getGroupId(), key.getArtifactId())) .setName(project.getName()) .setProjectDirectory(project.getProjectDir().getAbsolutePath()) - .setSourcePaths(PathList.from(sourcePaths)) + .setSourcePaths(PathsCollection.from(sourcePaths)) .setClassesPath(classesDir) - .setResourcePaths(PathList.from(resourcesSrcDirs)) + .setResourcePaths(PathsCollection.from(resourcesSrcDirs)) .setResourcesOutputPath(resourcesOutputPath) - .setSourceParents(PathList.from(sourceParentPaths)) + .setSourceParents(PathsCollection.from(sourceParentPaths)) .setPreBuildOutputDir(project.getBuildDir().toPath().resolve("generated-sources").toAbsolutePath().toString()) .setTargetDir(project.getBuildDir().toString()); @@ -445,9 +445,9 @@ private void addLocalProject(Project project, GradleDevModeLauncher.Builder buil // currently resources dir should exist testResourcesOutputPath = testClassesDir; } - moduleBuilder.setTestSourcePaths(PathList.from(testSourcePaths)) + moduleBuilder.setTestSourcePaths(PathsCollection.from(testSourcePaths)) .setTestClassesPath(testClassesDir) - .setTestResourcePaths(PathList.from(testResourcesSrcDirs)) + .setTestResourcePaths(PathsCollection.from(testResourcesSrcDirs)) .setTestResourcesOutputPath(testResourcesOutputPath); } } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java index 3057fc80e8317..cbe570046ec45 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java @@ -28,8 +28,8 @@ import io.quarkus.bootstrap.app.QuarkusBootstrap; import io.quarkus.bootstrap.classloading.QuarkusClassLoader; import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.deployment.CodeGenerator; -import io.quarkus.paths.PathList; import io.quarkus.runtime.LaunchMode; public class QuarkusGenerateCode extends QuarkusTask { @@ -131,7 +131,7 @@ public void prepareQuarkus() { } initAndRun.get().invoke(null, deploymentClassLoader, - PathList.from(sourcesDirectories), + PathsCollection.from(sourcesDirectories), paths.get(0), buildDir, sourceRegistrar, diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGradleUtils.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGradleUtils.java index 65af2220ef3cc..43f39890e148f 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGradleUtils.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGradleUtils.java @@ -13,6 +13,7 @@ import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.tasks.SourceSet; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.util.IoUtils; public class QuarkusGradleUtils { @@ -27,6 +28,20 @@ public static SourceSet getSourceSet(Project project, String sourceSetName) { return javaConvention.getSourceSets().getByName(sourceSetName); } + public static PathsCollection getOutputPaths(Project project) { + final SourceSet mainSourceSet = getSourceSet(project, SourceSet.MAIN_SOURCE_SET_NAME); + final PathsCollection.Builder builder = PathsCollection.builder(); + mainSourceSet.getOutput().getClassesDirs().filter(f -> f.exists()).forEach(f -> builder.add(f.toPath())); + final File resourcesDir = mainSourceSet.getOutput().getResourcesDir(); + if (resourcesDir != null && resourcesDir.exists()) { + final Path p = resourcesDir.toPath(); + if (!builder.contains(p)) { + builder.add(p); + } + } + return builder.build(); + } + public static String getClassesDir(SourceSet sourceSet, File tmpDir, boolean test) { return getClassesDir(sourceSet, tmpDir, true, test); } diff --git a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java index 061467d495a29..1b9377c625695 100644 --- a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java +++ b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java @@ -44,10 +44,9 @@ import io.quarkus.bootstrap.model.gradle.ModelParameter; import io.quarkus.bootstrap.model.gradle.impl.ModelParameterImpl; import io.quarkus.bootstrap.resolver.AppModelResolverException; -import io.quarkus.bootstrap.workspace.DefaultArtifactSources; -import io.quarkus.bootstrap.workspace.DefaultSourceDir; +import io.quarkus.bootstrap.workspace.DefaultProcessedSources; import io.quarkus.bootstrap.workspace.DefaultWorkspaceModule; -import io.quarkus.bootstrap.workspace.SourceDir; +import io.quarkus.bootstrap.workspace.ProcessedSources; import io.quarkus.fs.util.ZipUtils; import io.quarkus.maven.dependency.ArtifactCoords; import io.quarkus.maven.dependency.ArtifactKey; @@ -149,7 +148,7 @@ public Object buildAll(String modelName, ModelParameter parameter, Project proje final ResolvedDependency appArtifact = getProjectArtifact(project, mode); final ApplicationModelBuilder modelBuilder = new ApplicationModelBuilder() .setAppArtifact(appArtifact) - .addReloadableWorkspaceModule(appArtifact.getKey()) + .addReloadableWorkspaceModule(new GACT(appArtifact.getGroupId(), appArtifact.getArtifactId())) .setPlatformImports(platformImports); final Map appDependencies = new LinkedHashMap<>(); @@ -178,33 +177,33 @@ public static ResolvedDependency getProjectArtifact(Project project, LaunchMode final DefaultWorkspaceModule mainModule = new DefaultWorkspaceModule( new GAV(appArtifact.getGroupId(), appArtifact.getArtifactId(), appArtifact.getVersion()), project.getProjectDir(), project.getBuildDir()); - mainModule.setBuildFiles(PathList.of(project.getBuildFile().toPath())); - initProjectModule(project, mainModule, javaConvention.getSourceSets().findByName(SourceSet.MAIN_SOURCE_SET_NAME), - SourceSet.MAIN_SOURCE_SET_NAME, ""); + false); if (mode.equals(LaunchMode.TEST)) { initProjectModule(project, mainModule, javaConvention.getSourceSets().findByName(SourceSet.TEST_SOURCE_SET_NAME), - SourceSet.TEST_SOURCE_SET_NAME, "tests"); + true); } final PathList.Builder paths = PathList.builder(); - collectDestinationDirs(mainModule.getMainSources().getSourceDirs(), paths); - collectDestinationDirs(mainModule.getMainSources().getResourceDirs(), paths); + mainModule.getMainSources().forEach(src -> { + collectDestinationDirs(src, paths); + }); + mainModule.getMainResources().forEach(src -> { + collectDestinationDirs(src, paths); + }); return appArtifact.setWorkspaceModule(mainModule).setResolvedPaths(paths.build()).build(); } - private static void collectDestinationDirs(Collection sources, final PathList.Builder paths) { - for (SourceDir src : sources) { - if (!Files.exists(src.getOutputDir())) { - return; - } - final Path path = src.getOutputDir(); - if (paths.contains(path)) { - return; - } - paths.add(path); + private static void collectDestinationDirs(ProcessedSources src, final PathList.Builder paths) { + if (!src.getDestinationDir().exists()) { + return; } + final Path path = src.getDestinationDir().toPath(); + if (paths.contains(path)) { + return; + } + paths.add(path); } private static void processQuarkusDir(ResolvedDependencyBuilder artifactBuilder, Path quarkusDir, @@ -336,7 +335,7 @@ private void collectDependencies(ResolvedConfiguration configuration, final String parentPath = f.getParent(); final String group = HashUtil.sha1(parentPath == null ? f.getName() : parentPath); String name = f.getName(); - String type = ArtifactCoords.TYPE_JAR; + String type = "jar"; if (!f.isDirectory()) { final int dot = f.getName().lastIndexOf('.'); if (dot > 0) { @@ -432,10 +431,6 @@ private void collectDependencies(org.gradle.api.artifacts.ResolvedDependency res } } - private static String toNonNullClassifier(String resolvedClassifier) { - return resolvedClassifier == null ? "" : resolvedClassifier; - } - private DefaultWorkspaceModule initProjectModuleAndBuildPaths(final Project project, ResolvedArtifact resolvedArtifact, ApplicationModelBuilder appModel, final ResolvedDependencyBuilder appDep, final JavaPluginConvention javaExt, PathList.Builder buildPaths, String sourceName, boolean test) { @@ -447,17 +442,27 @@ private DefaultWorkspaceModule initProjectModuleAndBuildPaths(final Project proj resolvedArtifact.getModuleVersion().getId().getVersion()), project.getProjectDir(), project.getBuildDir()); - projectModule.setBuildFiles(PathList.of(project.getBuildFile().toPath())); - final String classifier = toNonNullClassifier(resolvedArtifact.getClassifier()); - initProjectModule(project, projectModule, javaExt.getSourceSets().findByName(sourceName), sourceName, classifier); + initProjectModule(project, projectModule, javaExt.getSourceSets().findByName(sourceName), test); - collectDestinationDirs(projectModule.getSources(classifier).getSourceDirs(), buildPaths); - collectDestinationDirs(projectModule.getSources(classifier).getResourceDirs(), buildPaths); + if (test) { + projectModule.getTestSources().forEach(src -> { + collectDestinationDirs(src, buildPaths); + }); + projectModule.getTestResources().forEach(src -> { + collectDestinationDirs(src, buildPaths); + }); + } else { + projectModule.getMainSources().forEach(src -> { + collectDestinationDirs(src, buildPaths); + }); + projectModule.getMainResources().forEach(src -> { + collectDestinationDirs(src, buildPaths); + }); + } appModel.addReloadableWorkspaceModule( - new GACT(resolvedArtifact.getModuleVersion().getId().getGroup(), resolvedArtifact.getName(), classifier, - GACTV.TYPE_JAR)); + new GACT(resolvedArtifact.getModuleVersion().getId().getGroup(), resolvedArtifact.getName())); return projectModule; } @@ -478,19 +483,18 @@ private void processQuarkusDependency(ResolvedDependencyBuilder artifactBuilder, }); } - private static void initProjectModule(Project project, DefaultWorkspaceModule module, SourceSet sourceSet, - String sourceName, String classifier) { + private static void initProjectModule(Project project, DefaultWorkspaceModule module, SourceSet sourceSet, boolean test) { if (sourceSet == null) { return; } + module.setBuildFiles(PathList.of(project.getBuildFile().toPath())); + final FileCollection allClassesDirs = sourceSet.getOutput().getClassesDirs(); // some plugins do not add source directories to source sets and they may be missing from sourceSet.getAllJava() // see https://github.com/quarkusio/quarkus/issues/20755 - final List sourceDirs = new ArrayList<>(1); - final List resourceDirs = new ArrayList<>(1); project.getTasks().withType(AbstractCompile.class, t -> { if (!t.getEnabled()) { return; @@ -509,9 +513,13 @@ private static void initProjectModule(Project project, DefaultWorkspaceModule mo if (a.getRelativePath().getSegments().length == 1) { final File srcDir = a.getFile().getParentFile(); if (srcDirs.add(srcDir)) { - DefaultSourceDir sources = new DefaultSourceDir(srcDir, destDir, + DefaultProcessedSources sources = new DefaultProcessedSources(srcDir, destDir, Collections.singletonMap("compiler", t.getName())); - sourceDirs.add(sources); + if (test) { + module.addTestSources(sources); + } else { + module.addMainSources(sources); + } } } }); @@ -537,17 +545,24 @@ private static void initProjectModule(Project project, DefaultWorkspaceModule mo if (a.getRelativePath().getSegments().length == 1) { final File srcDir = a.getFile().getParentFile(); if (srcDirs.add(srcDir)) { - resourceDirs.add(new DefaultSourceDir(srcDir, destDir)); + addResources(module, srcDir, destDir, test); } } }); }); // there could be a task generating resources - if (resourcesOutputDir.exists() && resourceDirs.isEmpty()) { - sourceSet.getResources().getSrcDirs() - .forEach(srcDir -> resourceDirs.add(new DefaultSourceDir(srcDir, resourcesOutputDir))); + if (resourcesOutputDir.exists() && (test ? module.getTestResources().isEmpty() : module.getMainResources().isEmpty())) { + sourceSet.getResources().getSrcDirs().forEach(srcDir -> addResources(module, srcDir, resourcesOutputDir, test)); + } + } + + private static void addResources(DefaultWorkspaceModule module, File srcDir, final File destDir, boolean test) { + final DefaultProcessedSources resrc = new DefaultProcessedSources(srcDir, destDir); + if (test) { + module.addTestResources(resrc); + } else { + module.addMainResources(resrc); } - module.addArtifactSources(new DefaultArtifactSources(classifier, sourceDirs, resourceDirs)); } private void addSubstitutedProject(PathList.Builder paths, File projectFile) { @@ -620,6 +635,8 @@ private static ArtifactCoords toArtifactCoords(ResolvedArtifact a) { } private static ArtifactKey toAppDependenciesKey(String groupId, String artifactId, String classifier) { + // Default classifier is empty string and not null value, lets keep it that way + classifier = classifier == null ? "" : classifier; return new GACT(groupId, artifactId, classifier, ArtifactCoords.TYPE_JAR); } } diff --git a/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java index 08cdac3e7069b..b7f064d47600d 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java @@ -82,23 +82,21 @@ import io.quarkus.bootstrap.BootstrapConstants; import io.quarkus.bootstrap.devmode.DependenciesFilter; +import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.resolver.BootstrapAppModelResolver; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; import io.quarkus.bootstrap.resolver.maven.options.BootstrapMavenOptions; import io.quarkus.bootstrap.util.BootstrapUtils; -import io.quarkus.bootstrap.workspace.ArtifactSources; -import io.quarkus.bootstrap.workspace.SourceDir; +import io.quarkus.bootstrap.workspace.WorkspaceModule; import io.quarkus.deployment.dev.DevModeContext; import io.quarkus.deployment.dev.DevModeMain; import io.quarkus.deployment.dev.QuarkusDevModeLauncher; import io.quarkus.maven.MavenDevModeLauncher.Builder; import io.quarkus.maven.components.MavenVersionEnforcer; -import io.quarkus.maven.dependency.ArtifactKey; import io.quarkus.maven.dependency.GACT; import io.quarkus.maven.dependency.GACTV; -import io.quarkus.maven.dependency.ResolvedDependency; -import io.quarkus.paths.PathList; import io.quarkus.runtime.LaunchMode; /** @@ -336,7 +334,7 @@ public class DevMojo extends AbstractMojo { @Component private ToolchainManager toolchainManager; - private Map pluginMap; + private Map pluginMap; @Component protected QuarkusBootstrapProvider bootstrapProvider; @@ -656,10 +654,10 @@ private Plugin getConfiguredPluginOrNull(String groupId, String artifactId) { pluginMap = new HashMap<>(); // the original plugin keys may include property expressions, so we can't rely on the exact groupId:artifactId keys for (Plugin p : project.getBuildPlugins()) { - pluginMap.put(new GACT(p.getGroupId(), p.getArtifactId()), p); + pluginMap.put(new AppArtifactKey(p.getGroupId(), p.getArtifactId()), p); } } - return pluginMap.get(new GACT(groupId, artifactId)); + return pluginMap.get(new AppArtifactKey(groupId, artifactId)); } private Map readPomFileTimestamps(DevModeRunner runner) throws IOException { @@ -678,7 +676,7 @@ private String getSourceEncoding() { return null; } - private void addProject(MavenDevModeLauncher.Builder builder, ResolvedDependency module, boolean root) throws Exception { + private void addProject(MavenDevModeLauncher.Builder builder, WorkspaceModule module, boolean root) throws Exception { String projectDirectory; Set sourcePaths; @@ -689,28 +687,15 @@ private void addProject(MavenDevModeLauncher.Builder builder, ResolvedDependency Set testResourcePaths; List activeProfiles = Collections.emptyList(); - final MavenProject mavenProject = module.getClassifier().isEmpty() - ? session.getProjectMap() - .get(String.format("%s:%s:%s", module.getGroupId(), module.getArtifactId(), module.getVersion())) - : null; - final ArtifactSources sources = module.getSources(); + final MavenProject mavenProject = session.getProjectMap().get( + String.format("%s:%s:%s", module.getId().getGroupId(), module.getId().getArtifactId(), + module.getId().getVersion())); if (mavenProject == null) { - projectDirectory = module.getWorkspaceModule().getModuleDir().getAbsolutePath(); - sourcePaths = new LinkedHashSet<>(); - for (SourceDir src : sources.getSourceDirs()) { - for (Path p : src.getSourceTree().getRoots()) { - sourcePaths.add(p.toAbsolutePath()); - } - } - testSourcePaths = new LinkedHashSet<>(); - ArtifactSources testSources = module.getWorkspaceModule().getTestSources(); - if (testSources != null) { - for (SourceDir src : testSources.getSourceDirs()) { - for (Path p : src.getSourceTree().getRoots()) { - testSourcePaths.add(p.toAbsolutePath()); - } - } - } + projectDirectory = module.getModuleDir().getAbsolutePath(); + sourcePaths = module.getMainSources().stream().map(src -> src.getSourceDir().toPath().toAbsolutePath()) + .collect(Collectors.toCollection(LinkedHashSet::new)); + testSourcePaths = module.getTestSources().stream().map(src -> src.getSourceDir().toPath().toAbsolutePath()) + .collect(Collectors.toCollection(LinkedHashSet::new)); } else { projectDirectory = mavenProject.getBasedir().getPath(); sourcePaths = mavenProject.getCompileSourceRoots().stream() @@ -725,40 +710,26 @@ private void addProject(MavenDevModeLauncher.Builder builder, ResolvedDependency } final Path sourceParent; - if (sources.getSourceDirs() == null) { - if (sources.getResourceDirs() == null) { + if (module.getMainSources().isEmpty()) { + if (module.getMainResources().isEmpty()) { throw new MojoExecutionException("The project does not appear to contain any sources or resources"); } - sourceParent = sources.getResourceDirs().iterator().next().getDir().toAbsolutePath().getParent(); + sourceParent = module.getMainResources().iterator().next().getSourceDir().toPath().toAbsolutePath().getParent(); } else { - sourceParent = sources.getSourceDirs().iterator().next().getDir().toAbsolutePath().getParent(); + sourceParent = module.getMainSources().iterator().next().getSourceDir().toPath().toAbsolutePath().getParent(); } - Path classesDir = sources.getSourceDirs().iterator().next().getOutputDir().toAbsolutePath(); + Path classesDir = module.getMainSources().iterator().next().getDestinationDir().toPath().toAbsolutePath(); if (Files.isDirectory(classesDir)) { classesPath = classesDir.toString(); } - Path testClassesDir = module.getWorkspaceModule().getTestSources().getSourceDirs().iterator().next().getOutputDir() - .toAbsolutePath(); + Path testClassesDir = module.getTestSources().iterator().next().getDestinationDir().toPath().toAbsolutePath(); testClassesPath = testClassesDir.toString(); - resourcePaths = new LinkedHashSet<>(); - for (SourceDir src : sources.getResourceDirs()) { - for (Path p : src.getSourceTree().getRoots()) { - resourcePaths.add(p.toAbsolutePath()); - } - } - - testResourcePaths = new LinkedHashSet<>(); - ArtifactSources testSources = module.getWorkspaceModule().getTestSources(); - if (testSources != null) { - for (SourceDir src : testSources.getResourceDirs()) { - for (Path p : src.getSourceTree().getRoots()) { - testResourcePaths.add(p.toAbsolutePath()); - } - } - } - + resourcePaths = module.getMainResources().stream().map(src -> src.getSourceDir().toPath().toAbsolutePath()) + .collect(Collectors.toCollection(LinkedHashSet::new)); + testResourcePaths = module.getTestResources().stream().map(src -> src.getSourceDir().toPath().toAbsolutePath()) + .collect(Collectors.toCollection(LinkedHashSet::new)); // Add the resources and test resources from the profiles for (Profile profile : activeProfiles) { final BuildBase build = profile.getBuild(); @@ -779,26 +750,27 @@ private void addProject(MavenDevModeLauncher.Builder builder, ResolvedDependency } if (classesPath == null && (!sourcePaths.isEmpty() || !resourcePaths.isEmpty())) { - throw new MojoExecutionException("Hot reloadable dependency " + module.getWorkspaceModule().getId() + throw new MojoExecutionException("Hot reloadable dependency " + module.getId() + " has not been compiled yet (the classes directory " + classesDir + " does not exist)"); } Path targetDir = Paths.get(project.getBuild().getDirectory()); DevModeContext.ModuleInfo moduleInfo = new DevModeContext.ModuleInfo.Builder() - .setArtifactKey(module.getKey()) + .setArtifactKey(new GACT(module.getId().getGroupId(), module.getId().getArtifactId())) + .setName(module.getId().getArtifactId()) .setProjectDirectory(projectDirectory) - .setSourcePaths(PathList.from(sourcePaths)) + .setSourcePaths(PathsCollection.from(sourcePaths)) .setClassesPath(classesPath) .setResourcesOutputPath(classesPath) - .setResourcePaths(PathList.from(resourcePaths)) - .setSourceParents(PathList.of(sourceParent.toAbsolutePath())) + .setResourcePaths(PathsCollection.from(resourcePaths)) + .setSourceParents(PathsCollection.of(sourceParent.toAbsolutePath())) .setPreBuildOutputDir(targetDir.resolve("generated-sources").toAbsolutePath().toString()) .setTargetDir(targetDir.toAbsolutePath().toString()) - .setTestSourcePaths(PathList.from(testSourcePaths)) + .setTestSourcePaths(PathsCollection.from(testSourcePaths)) .setTestClassesPath(testClassesPath) .setTestResourcesOutputPath(testClassesPath) - .setTestResourcePaths(PathList.from(testResourcePaths)) + .setTestResourcePaths(PathsCollection.from(testResourcePaths)) .build(); if (root) { @@ -967,8 +939,7 @@ private QuarkusDevModeLauncher newLauncher() throws Exception { appModel = new BootstrapAppModelResolver(resolverBuilder.build()) .setDevMode(true) .setCollectReloadableDependencies(!noDeps) - .resolveModel(new GACTV(project.getGroupId(), project.getArtifactId(), null, GACTV.TYPE_JAR, - project.getVersion())); + .resolveModel(new GACTV(project.getGroupId(), project.getArtifactId(), null, "jar", project.getVersion())); } // serialize the app model to avoid re-resolving it in the dev process @@ -976,14 +947,14 @@ private QuarkusDevModeLauncher newLauncher() throws Exception { builder.jvmArgs("-D" + BootstrapConstants.SERIALIZED_APP_MODEL + "=" + appModelLocation); if (noDeps) { - addProject(builder, appModel.getAppArtifact(), true); + addProject(builder, appModel.getApplicationModule(), true); appModel.getApplicationModule().getBuildFiles().forEach(p -> builder.watchedBuildFile(p)); - builder.localArtifact(new GACT(project.getGroupId(), project.getArtifactId(), null, GACTV.TYPE_JAR)); + builder.localArtifact(new AppArtifactKey(project.getGroupId(), project.getArtifactId())); } else { - for (ResolvedDependency project : DependenciesFilter.getReloadableModules(appModel)) { - addProject(builder, project, project == appModel.getAppArtifact()); - project.getWorkspaceModule().getBuildFiles().forEach(p -> builder.watchedBuildFile(p)); - builder.localArtifact(project.getKey()); + for (WorkspaceModule project : DependenciesFilter.getReloadableModules(appModel)) { + addProject(builder, project, project == appModel.getApplicationModule()); + project.getBuildFiles().forEach(p -> builder.watchedBuildFile(p)); + builder.localArtifact(new AppArtifactKey(project.getId().getGroupId(), project.getId().getArtifactId())); } } @@ -992,7 +963,7 @@ private QuarkusDevModeLauncher newLauncher() throws Exception { //in most cases these are not used, however they need to be present for some //parent-first cases such as logging //first we go through and get all the parent first artifacts - Set parentFirstArtifacts = new HashSet<>(); + Set parentFirstArtifacts = new HashSet<>(); for (Artifact appDep : project.getArtifacts()) { if (appDep.getArtifactHandler().getExtension().equals("jar") && appDep.getFile().isFile()) { try (ZipFile file = new ZipFile(appDep.getFile())) { @@ -1005,7 +976,7 @@ private QuarkusDevModeLauncher newLauncher() throws Exception { if (parentFirst != null) { String[] artifacts = parentFirst.split(","); for (String artifact : artifacts) { - parentFirstArtifacts.add(new GACT(artifact.split(":"))); + parentFirstArtifacts.add(new AppArtifactKey(artifact.split(":"))); } } } @@ -1017,7 +988,7 @@ private QuarkusDevModeLauncher newLauncher() throws Exception { for (Artifact appDep : project.getArtifacts()) { // only add the artifact if it's present in the dev mode context // we need this to avoid having jars on the classpath multiple times - ArtifactKey key = new GACT(appDep.getGroupId(), appDep.getArtifactId(), + AppArtifactKey key = new AppArtifactKey(appDep.getGroupId(), appDep.getArtifactId(), appDep.getClassifier(), appDep.getArtifactHandler().getExtension()); if (!builder.isLocal(key) && parentFirstArtifacts.contains(key)) { builder.classpathEntry(appDep.getFile()); diff --git a/devtools/maven/src/main/java/io/quarkus/maven/GenerateCodeMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/GenerateCodeMojo.java index 8a4505c2db35e..2464f0b2f07e2 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/GenerateCodeMojo.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/GenerateCodeMojo.java @@ -16,8 +16,7 @@ import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.classloading.QuarkusClassLoader; import io.quarkus.bootstrap.model.ApplicationModel; -import io.quarkus.paths.PathCollection; -import io.quarkus.paths.PathList; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.runtime.LaunchMode; // in the PROCESS_RESOURCES phase because we want the config to be available @@ -73,12 +72,12 @@ void generateCode(Path sourcesDir, Thread.currentThread().setContextClassLoader(deploymentClassLoader); final Class codeGenerator = deploymentClassLoader.loadClass("io.quarkus.deployment.CodeGenerator"); - final Method initAndRun = codeGenerator.getMethod("initAndRun", ClassLoader.class, PathCollection.class, + final Method initAndRun = codeGenerator.getMethod("initAndRun", ClassLoader.class, PathsCollection.class, Path.class, Path.class, Consumer.class, ApplicationModel.class, Properties.class, String.class); initAndRun.invoke(null, deploymentClassLoader, - PathList.of(sourcesDir), + PathsCollection.of(sourcesDir), generatedSourcesDir(test), buildDir().toPath(), sourceRegistrar, diff --git a/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapProvider.java b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapProvider.java index a8ef9595c6126..558af0bdb9a5c 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapProvider.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusBootstrapProvider.java @@ -172,19 +172,13 @@ protected CuratedApplication doBootstrap(QuarkusBootstrapMojo mojo, LaunchMode m .setDevMode(mode == LaunchMode.DEVELOPMENT) .setTest(mode == LaunchMode.TEST); - final ArtifactCoords artifactCoords = appArtifact(mojo); final List localProjects = mojo.mavenProject().getCollectedProjects(); - final Set localProjectKeys = new HashSet<>(localProjects.size()); - for (MavenProject p : localProjects) { - localProjectKeys.add(new GACT(p.getGroupId(), p.getArtifactId())); - } final Set reloadableModules = new HashSet<>(localProjects.size() + 1); - for (Artifact a : mojo.mavenProject().getArtifacts()) { - if (localProjectKeys.contains(new GACT(a.getGroupId(), a.getArtifactId()))) { - reloadableModules.add(new GACT(a.getGroupId(), a.getArtifactId(), a.getClassifier(), a.getType())); - } + final ArtifactCoords artifactCoords = appArtifact(mojo); + reloadableModules.add(new GACT(artifactCoords.getGroupId(), artifactCoords.getArtifactId())); + for (MavenProject project : localProjects) { + reloadableModules.add(new GACT(project.getGroupId(), project.getArtifactId())); } - reloadableModules.add(artifactCoords.getKey()); final ApplicationModel appModel; try { diff --git a/devtools/maven/src/main/java/io/quarkus/maven/QuarkusMavenWorkspaceBuilder.java b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusMavenWorkspaceBuilder.java index 2592f7af20e0c..64d4917608d87 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/QuarkusMavenWorkspaceBuilder.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusMavenWorkspaceBuilder.java @@ -1,18 +1,14 @@ package io.quarkus.maven; import java.io.File; -import java.util.ArrayList; -import java.util.List; import org.apache.maven.model.Build; import org.apache.maven.model.Resource; import org.apache.maven.project.MavenProject; import io.quarkus.bootstrap.model.ApplicationModelBuilder; -import io.quarkus.bootstrap.workspace.DefaultArtifactSources; -import io.quarkus.bootstrap.workspace.DefaultSourceDir; +import io.quarkus.bootstrap.workspace.DefaultProcessedSources; import io.quarkus.bootstrap.workspace.DefaultWorkspaceModule; -import io.quarkus.bootstrap.workspace.SourceDir; import io.quarkus.bootstrap.workspace.WorkspaceModule; import io.quarkus.bootstrap.workspace.WorkspaceModuleId; import io.quarkus.maven.dependency.GAV; @@ -29,24 +25,21 @@ static WorkspaceModule toProjectModule(MavenProject project) { new File(build.getDirectory())); final File classesDir = new File(build.getOutputDirectory()); - final List sources = new ArrayList<>(project.getCompileSourceRoots().size()); - project.getCompileSourceRoots().forEach(s -> sources.add(new DefaultSourceDir(new File(s), classesDir))); - final List resources = new ArrayList<>(build.getResources().size()); + project.getCompileSourceRoots() + .forEach(s -> module.addMainSources(new DefaultProcessedSources(new File(s), classesDir))); + final File testClassesDir = new File(build.getTestOutputDirectory()); + project.getTestCompileSourceRoots() + .forEach(s -> module.addTestSources(new DefaultProcessedSources(new File(s), testClassesDir))); + for (Resource r : build.getResources()) { - resources.add(new DefaultSourceDir(new File(r.getDirectory()), + module.addMainResources(new DefaultProcessedSources(new File(r.getDirectory()), r.getTargetPath() == null ? classesDir : new File(r.getTargetPath()))); } - module.addArtifactSources(new DefaultArtifactSources(DefaultWorkspaceModule.MAIN, sources, resources)); - final File testClassesDir = new File(build.getTestOutputDirectory()); - final List testSources = new ArrayList<>(project.getCompileSourceRoots().size()); - project.getTestCompileSourceRoots().forEach(s -> testSources.add(new DefaultSourceDir(new File(s), testClassesDir))); - final List testResources = new ArrayList<>(build.getTestResources().size()); for (Resource r : build.getTestResources()) { - testResources.add(new DefaultSourceDir(new File(r.getDirectory()), + module.addTestResources(new DefaultProcessedSources(new File(r.getDirectory()), r.getTargetPath() == null ? testClassesDir : new File(r.getTargetPath()))); } - module.addArtifactSources(new DefaultArtifactSources(DefaultWorkspaceModule.TEST, testSources, testResources)); module.setBuildFiles(PathList.of(project.getFile().toPath())); diff --git a/extensions/awt/deployment/src/main/java/io/quarkus/awt/deployment/AwtProcessor.java b/extensions/awt/deployment/src/main/java/io/quarkus/awt/deployment/AwtProcessor.java index ab5c53a1b851d..aec0f2b0e83b5 100644 --- a/extensions/awt/deployment/src/main/java/io/quarkus/awt/deployment/AwtProcessor.java +++ b/extensions/awt/deployment/src/main/java/io/quarkus/awt/deployment/AwtProcessor.java @@ -5,6 +5,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.FileSystem; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; @@ -20,7 +21,6 @@ import io.quarkus.deployment.builditem.nativeimage.UnsupportedOSBuildItem; import io.quarkus.deployment.pkg.NativeConfig; import io.quarkus.deployment.pkg.steps.NativeBuild; -import io.quarkus.fs.util.ZipUtils; class AwtProcessor { @@ -120,7 +120,7 @@ GeneratedResourceBuildItem yankI18NPropertiesFromHostJDK(BuildProducer filesToCompile, Context context) { } @Override - public Path getSourcePath(Path classFilePath, PathCollection sourcePaths, String classesPath) { + public Path getSourcePath(Path classFilePath, PathsCollection sourcePaths, String classesPath) { // return same class so it is not removed return classFilePath; } diff --git a/extensions/scala/deployment/src/main/java/io/quarkus/scala/deployment/ScalaCompilationProvider.java b/extensions/scala/deployment/src/main/java/io/quarkus/scala/deployment/ScalaCompilationProvider.java index b071478a0a1db..0e4f32e03d3ef 100644 --- a/extensions/scala/deployment/src/main/java/io/quarkus/scala/deployment/ScalaCompilationProvider.java +++ b/extensions/scala/deployment/src/main/java/io/quarkus/scala/deployment/ScalaCompilationProvider.java @@ -6,8 +6,8 @@ import java.util.Set; import java.util.stream.Collectors; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.deployment.dev.CompilationProvider; -import io.quarkus.paths.PathCollection; import scala.collection.JavaConverters; import scala.tools.nsc.Global; import scala.tools.nsc.Settings; @@ -36,7 +36,7 @@ public void compile(Set files, Context context) { } @Override - public Path getSourcePath(Path classFilePath, PathCollection sourcePaths, String classesPath) { + public Path getSourcePath(Path classFilePath, PathsCollection sourcePaths, String classesPath) { return classFilePath; } } diff --git a/extensions/smallrye-openapi/deployment/src/main/java/io/quarkus/smallrye/openapi/deployment/SmallRyeOpenApiProcessor.java b/extensions/smallrye-openapi/deployment/src/main/java/io/quarkus/smallrye/openapi/deployment/SmallRyeOpenApiProcessor.java index 0b428867f6d8e..30371f76c916f 100644 --- a/extensions/smallrye-openapi/deployment/src/main/java/io/quarkus/smallrye/openapi/deployment/SmallRyeOpenApiProcessor.java +++ b/extensions/smallrye-openapi/deployment/src/main/java/io/quarkus/smallrye/openapi/deployment/SmallRyeOpenApiProcessor.java @@ -64,7 +64,6 @@ import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem; import io.quarkus.deployment.logging.LogCleanupFilterBuildItem; import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem; -import io.quarkus.paths.PathUtils; import io.quarkus.resteasy.common.spi.ResteasyDotNames; import io.quarkus.resteasy.server.common.spi.AllowedJaxRsAnnotationPrefixBuildItem; import io.quarkus.resteasy.server.common.spi.ResteasyJaxrsConfigBuildItem; @@ -780,12 +779,12 @@ private List findStaticModels(SmallRyeOpenApiConfig openApiConfig, Path List results = new ArrayList<>(); // First check for the file in both META-INF and WEB-INF/classes/META-INF - addStaticModelIfExist(results, Format.YAML, META_INF_OPENAPI_YAML); - addStaticModelIfExist(results, Format.YAML, WEB_INF_CLASSES_META_INF_OPENAPI_YAML); - addStaticModelIfExist(results, Format.YAML, META_INF_OPENAPI_YML); - addStaticModelIfExist(results, Format.YAML, WEB_INF_CLASSES_META_INF_OPENAPI_YML); - addStaticModelIfExist(results, Format.JSON, META_INF_OPENAPI_JSON); - addStaticModelIfExist(results, Format.JSON, WEB_INF_CLASSES_META_INF_OPENAPI_JSON); + results = addStaticModelIfExist(results, Format.YAML, META_INF_OPENAPI_YAML); + results = addStaticModelIfExist(results, Format.YAML, WEB_INF_CLASSES_META_INF_OPENAPI_YAML); + results = addStaticModelIfExist(results, Format.YAML, META_INF_OPENAPI_YML); + results = addStaticModelIfExist(results, Format.YAML, WEB_INF_CLASSES_META_INF_OPENAPI_YML); + results = addStaticModelIfExist(results, Format.JSON, META_INF_OPENAPI_JSON); + results = addStaticModelIfExist(results, Format.JSON, WEB_INF_CLASSES_META_INF_OPENAPI_JSON); // Add any aditional directories if configured if (openApiConfig.additionalDocsDirectory.isPresent()) { @@ -793,9 +792,9 @@ private List findStaticModels(SmallRyeOpenApiConfig openApiConfig, Path for (Path path : additionalStaticDocuments) { // Scan all yaml and json files try { - List filesInDir = getResourceFiles(PathUtils.asString(path, "/"), target); + List filesInDir = getResourceFiles(path.toString(), target); for (String possibleModelFile : filesInDir) { - addStaticModelIfExist(results, possibleModelFile); + results = addStaticModelIfExist(results, possibleModelFile); } } catch (IOException ioe) { ioe.printStackTrace(); @@ -806,17 +805,18 @@ private List findStaticModels(SmallRyeOpenApiConfig openApiConfig, Path return results; } - private void addStaticModelIfExist(List results, String path) { + private List addStaticModelIfExist(List results, String path) { if (path.endsWith(".json")) { // Scan a specific json file - addStaticModelIfExist(results, Format.JSON, path); + results = addStaticModelIfExist(results, Format.JSON, path); } else if (path.endsWith(".yaml") || path.endsWith(".yml")) { // Scan a specific yaml file - addStaticModelIfExist(results, Format.YAML, path); + results = addStaticModelIfExist(results, Format.YAML, path); } + return results; } - private void addStaticModelIfExist(List results, Format format, String path) { + private List addStaticModelIfExist(List results, Format format, String path) { ClassLoader cl = Thread.currentThread().getContextClassLoader(); try (InputStream inputStream = cl.getResourceAsStream(path)) { if (inputStream != null) { @@ -825,6 +825,7 @@ private void addStaticModelIfExist(List results, Format format, String p } catch (IOException ex) { ex.printStackTrace(); } + return results; } private List getResourceFiles(String pathName, Path target) throws IOException { diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpRootPathBuildItem.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpRootPathBuildItem.java index 714873eaf63be..40afedb5e3c4c 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpRootPathBuildItem.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpRootPathBuildItem.java @@ -102,7 +102,7 @@ public static class Builder extends RouteBuildItem.Builder { private RouteBuildItem.RouteType routeType = RouteBuildItem.RouteType.APPLICATION_ROUTE; private String path; - private Builder(HttpRootPathBuildItem buildItem) { + Builder(HttpRootPathBuildItem buildItem) { this.buildItem = buildItem; } @@ -143,6 +143,7 @@ public Builder routeFunction(String route, Consumer routeFunction) { this.path = route; this.routeType = RouteBuildItem.RouteType.ABSOLUTE_ROUTE; } + super.routeFunction(this.path, routeFunction); return this; } diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/VertxHttpProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/VertxHttpProcessor.java index b3938e83dc70f..767c0b1dfa8f6 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/VertxHttpProcessor.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/VertxHttpProcessor.java @@ -1,7 +1,12 @@ package io.quarkus.vertx.http.deployment; import java.io.IOException; -import java.io.UncheckedIOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.FileSystem; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.CodeSource; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -17,8 +22,6 @@ import io.quarkus.arc.deployment.BeanContainerBuildItem; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; import io.quarkus.arc.processor.BuiltinScope; -import io.quarkus.bootstrap.classloading.ClassPathElement; -import io.quarkus.bootstrap.classloading.QuarkusClassLoader; import io.quarkus.builder.BuildException; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; @@ -36,6 +39,7 @@ import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem; import io.quarkus.deployment.logging.LogCleanupFilterBuildItem; +import io.quarkus.fs.util.ZipUtils; import io.quarkus.kubernetes.spi.KubernetesPortBuildItem; import io.quarkus.netty.runtime.virtual.VirtualServerChannel; import io.quarkus.runtime.LaunchMode; @@ -63,7 +67,6 @@ class VertxHttpProcessor { - private static final String META_INF_SERVICES_EXCHANGE_ATTRIBUTE_BUILDER = "META-INF/services/io.quarkus.vertx.http.runtime.attribute.ExchangeAttributeBuilder"; private static final Logger logger = Logger.getLogger(VertxHttpProcessor.class); @BuildStep @@ -337,33 +340,30 @@ void registerExchangeAttributeBuilders(final BuildProducer elements = QuarkusClassLoader.getElements(META_INF_SERVICES_EXCHANGE_ATTRIBUTE_BUILDER, - false); - if (elements.isEmpty()) { + final CodeSource codeSource = ExchangeAttributeBuilder.class.getProtectionDomain().getCodeSource(); + if (codeSource == null) { logger.debug("Skipping registration of service providers for " + ExchangeAttributeBuilder.class); return; } - for (ClassPathElement cpe : elements) { - cpe.withOpenTree(tree -> { - return tree.processPath(META_INF_SERVICES_EXCHANGE_ATTRIBUTE_BUILDER, visit -> { - if (visit == null) { - logger.debug("Skipping registration of service providers for " + ExchangeAttributeBuilder.class - + " since no service descriptor file found"); - } else { - // we register all the listed providers since the access log configuration is a runtime construct - // and we won't know at build time which attributes the user application will choose - final ServiceProviderBuildItem serviceProviderBuildItem; - try { - serviceProviderBuildItem = ServiceProviderBuildItem - .allProviders(ExchangeAttributeBuilder.class.getName(), visit.getPath()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - exchangeAttributeBuilderService.produce(serviceProviderBuildItem); - } - return null; - }); - }); + try (final FileSystem jarFileSystem = ZipUtils.newFileSystem( + new URI("jar", codeSource.getLocation().toURI().toString(), null), + Collections.emptyMap())) { + final Path serviceDescriptorFilePath = jarFileSystem.getPath("META-INF", "services", + "io.quarkus.vertx.http.runtime.attribute.ExchangeAttributeBuilder"); + if (!Files.exists(serviceDescriptorFilePath)) { + logger.debug("Skipping registration of service providers for " + ExchangeAttributeBuilder.class + + " since no service descriptor file found"); + return; + } + // we register all the listed providers since the access log configuration is a runtime construct + // and we won't know at build time which attributes the user application will choose + final ServiceProviderBuildItem serviceProviderBuildItem; + serviceProviderBuildItem = ServiceProviderBuildItem.allProviders(ExchangeAttributeBuilder.class.getName(), + serviceDescriptorFilePath); + exchangeAttributeBuilderService.produce(serviceProviderBuildItem); + } catch (IOException | URISyntaxException e) { + throw new BuildException(e, Collections.emptyList()); } } + } diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java index c967fc6ab043c..da79ed3c0c41b 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java @@ -4,12 +4,16 @@ import java.io.IOException; import java.io.Reader; import java.io.StringReader; -import java.io.UncheckedIOException; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystem; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; @@ -66,6 +70,7 @@ import io.quarkus.devconsole.spi.DevConsoleRouteBuildItem; import io.quarkus.devconsole.spi.DevConsoleRuntimeTemplateInfoBuildItem; import io.quarkus.devconsole.spi.DevConsoleTemplateInfoBuildItem; +import io.quarkus.fs.util.ZipUtils; import io.quarkus.maven.dependency.ResolvedDependency; import io.quarkus.netty.runtime.virtual.VirtualChannel; import io.quarkus.netty.runtime.virtual.VirtualServerChannel; @@ -88,7 +93,6 @@ import io.quarkus.qute.Variant; import io.quarkus.runtime.RuntimeValue; import io.quarkus.runtime.TemplateHtmlBuilder; -import io.quarkus.runtime.util.ClassPathUtils; import io.quarkus.utilities.OS; import io.quarkus.vertx.http.deployment.HttpRootPathBuildItem; import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem; @@ -714,61 +718,51 @@ public Optional getVariant() { @BuildStep void collectTemplates(BuildProducer devTemplatePaths) { - final Enumeration devTemplateURLs; try { - devTemplateURLs = DevConsoleProcessor.class.getClassLoader().getResources("/dev-templates"); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - while (devTemplateURLs.hasMoreElements()) { - URL devTemplatesUrl = devTemplateURLs.nextElement(); - ClassPathUtils.consumeAsPath(devTemplatesUrl, devTemplatesDir -> { - final Path classesDir = devTemplatesDir.getParent(); - if (classesDir == null) { - return; - } - final Entry entry = readPomPropertiesIfBuilt(devTemplatesUrl, classesDir); - if (entry == null) { - return; - } - try { - scanTemplates(entry, devTemplatesDir, devTemplatePaths); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - }); - } - } - - private Entry readPomPropertiesIfBuilt(URL devTemplatesURL, final Path classesDir) { - Entry entry = null; - try { - if ("jar".equals(devTemplatesURL.getProtocol())) { - final Path metaInf = classesDir.resolve("META-INF").resolve("maven"); - if (Files.exists(metaInf)) { - entry = ArtifactInfoUtil.groupIdAndArtifactId(metaInf); - } - } else { - final Path rootDir = classesDir.getParent(); - final Path mavenArchiver = rootDir == null ? null : rootDir.resolve("maven-archiver"); - if (mavenArchiver == null || !mavenArchiver.toFile().canRead()) { - // it's a module output dir and the Maven metadata hasn't been generated - return null; + ClassLoader classLoader = DevConsoleProcessor.class.getClassLoader(); + Enumeration devTemplateURLs = classLoader.getResources("/dev-templates"); + while (devTemplateURLs.hasMoreElements()) { + URL devTemplatesURL = devTemplateURLs.nextElement(); + String devTemplatesURLStr = devTemplatesURL.toExternalForm(); + if (devTemplatesURLStr.startsWith("jar:file:") && devTemplatesURLStr.endsWith("!/dev-templates")) { + String jarPath = devTemplatesURLStr.substring(9, devTemplatesURLStr.length() - 15); + if (File.separatorChar == '\\') { + // on Windows this will be /C:/some/path, so turn it into C:\some\path + jarPath = jarPath.substring(1).replace('/', '\\'); + } + try (FileSystem fs = ZipUtils + .newFileSystem(Paths.get(URLDecoder.decode(jarPath, StandardCharsets.UTF_8.name())))) { + scanTemplates(fs, null, fs.getRootDirectories(), devTemplatePaths); + } + } else if ("file".equals(devTemplatesURL.getProtocol())) { + // This can happen if you run an example app in dev mode + // and this app is part of a multi-module project which also declares the extension + // Just try to locate the pom.properties file in the target/maven-archiver directory + // Note that this hack will not work if addMavenDescriptor=false or if the pomPropertiesFile is overriden + Path classes = Paths.get(devTemplatesURL.toURI()).getParent(); + Path target = classes != null ? classes.getParent() : null; + if (target != null) { + Path mavenArchiver = target.resolve("maven-archiver"); + if (mavenArchiver.toFile().canRead()) { + scanTemplates(null, mavenArchiver, Collections.singleton(classes), devTemplatePaths); + } + } } - entry = ArtifactInfoUtil.groupIdAndArtifactId(mavenArchiver); } - } catch (IOException e) { - throw new UncheckedIOException(e); - } - if (entry == null) { - throw new RuntimeException("Missing POM metadata in " + devTemplatesURL); + } catch (IOException | URISyntaxException e) { + throw new RuntimeException(e); } - return entry; } - private void scanTemplates(Entry entry, Path devTemplatesPath, + private void scanTemplates(FileSystem fs, Path pomPropertiesPath, Iterable rootDirectories, BuildProducer devTemplatePaths) throws IOException { + Entry entry = fs != null ? ArtifactInfoUtil.groupIdAndArtifactId(fs) + : ArtifactInfoUtil.groupIdAndArtifactId(pomPropertiesPath); + if (entry == null) { + throw new RuntimeException("Missing pom metadata [fileSystem: " + fs + ", rootDirectories: " + rootDirectories + + ", pomPath: " + pomPropertiesPath + "]"); + } String prefix; // don't move stuff for our "root" dev console artifact, since it includes the main template if (entry.getKey().equals("io.quarkus") @@ -777,34 +771,35 @@ private void scanTemplates(Entry entry, Path devTemplatesPath, else prefix = entry.getKey() + "." + entry.getValue() + "/"; - final Path root = devTemplatesPath.getParent(); - Files.walkFileTree(root, new SimpleFileVisitor() { - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - if (dir.equals(root) || dir.toString().equals("/") || dir.startsWith(devTemplatesPath)) { - return FileVisitResult.CONTINUE; + for (Path root : rootDirectories) { + Path devTemplatesPath = root.resolve("dev-templates"); + Files.walkFileTree(root, new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + if (dir.equals(root) || dir.toString().equals("/") || dir.startsWith(devTemplatesPath)) + return FileVisitResult.CONTINUE; + return FileVisitResult.SKIP_SUBTREE; } - return FileVisitResult.SKIP_SUBTREE; - } - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - String contents = Files.readString(file); - // don't move tags yet, since we don't know how to use them afterwards - String relativePath = devTemplatesPath.relativize(file).toString(); - String correctedPath; - if (File.separatorChar == '\\') { - relativePath = relativePath.replace('\\', '/'); + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + String contents = Files.readString(file); + // don't move tags yet, since we don't know how to use them afterwards + String relativePath = devTemplatesPath.relativize(file).toString(); + String correctedPath; + if (File.separatorChar == '\\') { + relativePath = relativePath.replace('\\', '/'); + } + if (relativePath.startsWith(DevTemplatePathBuildItem.TAGS)) + correctedPath = relativePath; + else + correctedPath = prefix + relativePath; + devTemplatePaths + .produce(new DevTemplatePathBuildItem(correctedPath, contents)); + return super.visitFile(file, attrs); } - if (relativePath.startsWith(DevTemplatePathBuildItem.TAGS)) - correctedPath = relativePath; - else - correctedPath = prefix + relativePath; - devTemplatePaths - .produce(new DevTemplatePathBuildItem(correctedPath, contents)); - return super.visitFile(file, attrs); - } - }); + }); + } } public static class JavaDocResolver implements ValueResolver { diff --git a/extensions/webjars-locator/deployment/src/test/java/io/quarkus/webjar/locator/test/WebJarLocatorRootPathTest.java b/extensions/webjars-locator/deployment/src/test/java/io/quarkus/webjar/locator/test/WebJarLocatorRootPathTest.java index 6f7554e0092ac..68b47e2939b91 100644 --- a/extensions/webjars-locator/deployment/src/test/java/io/quarkus/webjar/locator/test/WebJarLocatorRootPathTest.java +++ b/extensions/webjars-locator/deployment/src/test/java/io/quarkus/webjar/locator/test/WebJarLocatorRootPathTest.java @@ -2,13 +2,13 @@ import static org.hamcrest.core.Is.is; -import java.util.List; +import java.util.Arrays; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import io.quarkus.maven.dependency.ArtifactDependency; +import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.test.QuarkusUnitTest; import io.restassured.RestAssured; @@ -18,11 +18,11 @@ public class WebJarLocatorRootPathTest extends WebJarLocatorTestSupport { @RegisterExtension static QuarkusUnitTest runner = new QuarkusUnitTest() .withApplicationRoot((jar) -> jar - .addAsResource(new StringAsset("Hello!"), META_INF_RESOURCES + "index.html") - .addAsResource(new StringAsset("Test"), META_INF_RESOURCES + "some/path/test.txt")) + .addAsResource(new StringAsset("Hello!"), META_INF_RESOURCES + "/index.html") + .addAsResource(new StringAsset("Test"), META_INF_RESOURCES + "/some/path/test.txt")) .overrideConfigKey("quarkus.http.root-path", "/app") - .setForcedDependencies(List.of(ArtifactDependency.of("org.webjars", "jquery-ui", JQUERY_UI_VERSION), - ArtifactDependency.of("org.webjars", "momentjs", MOMENTJS_VERSION))); + .setForcedDependencies(Arrays.asList(new AppArtifact("org.webjars", "jquery-ui", JQUERY_UI_VERSION), + new AppArtifact("org.webjars", "momentjs", MOMENTJS_VERSION))); @Test public void test() { @@ -30,6 +30,7 @@ public void test() { RestAssured.get("/").then() .statusCode(200) .body(is("Hello!")); + RestAssured.get("/index.html").then() .statusCode(200) .body(is("Hello!")); diff --git a/independent-projects/bootstrap/app-model/pom.xml b/independent-projects/bootstrap/app-model/pom.xml index c51ef8263dda4..d3d813f510eda 100644 --- a/independent-projects/bootstrap/app-model/pom.xml +++ b/independent-projects/bootstrap/app-model/pom.xml @@ -32,10 +32,6 @@ - - io.quarkus - quarkus-fs-util - org.jboss.logging jboss-logging diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifactKey.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifactKey.java index a2fedd9b09d5b..c3d4e1fa6d4b2 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifactKey.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppArtifactKey.java @@ -134,28 +134,28 @@ public boolean equals(Object obj) { return true; if (obj == null) return false; - if (!(obj instanceof ArtifactKey)) + if (getClass() != obj.getClass()) return false; - ArtifactKey other = (ArtifactKey) obj; + AppArtifactKey other = (AppArtifactKey) obj; if (artifactId == null) { - if (other.getArtifactId() != null) + if (other.artifactId != null) return false; - } else if (!artifactId.equals(other.getArtifactId())) + } else if (!artifactId.equals(other.artifactId)) return false; if (classifier == null) { - if (other.getClassifier() != null) + if (other.classifier != null) return false; - } else if (!classifier.equals(other.getClassifier())) + } else if (!classifier.equals(other.classifier)) return false; if (groupId == null) { - if (other.getGroupId() != null) + if (other.groupId != null) return false; - } else if (!groupId.equals(other.getGroupId())) + } else if (!groupId.equals(other.groupId)) return false; if (type == null) { - if (other.getType() != null) + if (other.type != null) return false; - } else if (!type.equals(other.getType())) + } else if (!type.equals(other.type)) return false; return true; } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppDependency.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppDependency.java index 2561406f12736..4199d3eb0143e 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppDependency.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppDependency.java @@ -74,7 +74,7 @@ public String toString() { if (isOptional()) { buf.append("optional "); } - if (isWorkspaceModule()) { + if (isWorkspacetModule()) { buf.append("local "); } if (isRuntimeExtensionArtifact()) { diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/util/BootstrapUtils.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/util/BootstrapUtils.java index 2ab2b907aa6ec..b45657b176003 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/util/BootstrapUtils.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/util/BootstrapUtils.java @@ -83,7 +83,7 @@ public static AppModel convert(ApplicationModel appModel) { new AppArtifactKey(k.getGroupId(), k.getArtifactId(), k.getClassifier(), k.getType()))); appModel.getReloadableWorkspaceDependencies().forEach(k -> builder.addLocalProjectArtifact( - new AppArtifactKey(k.getGroupId(), k.getArtifactId(), k.getClassifier(), k.getType()))); + new AppArtifactKey(k.getGroupId(), k.getArtifactId()))); return builder.build(); } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/util/PathsUtils.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/util/PathsUtils.java new file mode 100644 index 0000000000000..bbae89af02dd6 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/util/PathsUtils.java @@ -0,0 +1,16 @@ +package io.quarkus.bootstrap.util; + +import io.quarkus.bootstrap.model.PathsCollection; +import java.io.File; +import java.util.Collection; + +public class PathsUtils { + + public static PathsCollection toPathsCollection(Collection c) { + final PathsCollection.Builder builder = PathsCollection.builder(); + for (File f : c) { + builder.add(f.toPath()); + } + return builder.build(); + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/ArtifactSources.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/ArtifactSources.java deleted file mode 100644 index c2e4f2a70fe1a..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/ArtifactSources.java +++ /dev/null @@ -1,56 +0,0 @@ -package io.quarkus.bootstrap.workspace; - -import io.quarkus.paths.EmptyPathTree; -import io.quarkus.paths.MultiRootPathTree; -import io.quarkus.paths.PathTree; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public interface ArtifactSources { - - String getClassifier(); - - Collection getSourceDirs(); - - Collection getResourceDirs(); - - default boolean isOutputAvailable() { - for (SourceDir src : getSourceDirs()) { - if (src.isOutputAvailable()) { - return true; - } - } - for (SourceDir src : getResourceDirs()) { - if (src.isOutputAvailable()) { - return true; - } - } - return false; - } - - default PathTree getOutputTree() { - final Collection sourceDirs = getSourceDirs(); - final Collection resourceDirs = getResourceDirs(); - final List trees = new ArrayList<>(sourceDirs.size() + resourceDirs.size()); - for (SourceDir src : sourceDirs) { - final PathTree outputTree = src.getOutputTree(); - if (outputTree != null && !outputTree.isEmpty() && !trees.contains(outputTree)) { - trees.add(outputTree); - } - } - for (SourceDir src : resourceDirs) { - final PathTree outputTree = src.getOutputTree(); - if (outputTree != null && !outputTree.isEmpty() && !trees.contains(outputTree)) { - trees.add(outputTree); - } - } - if (trees.isEmpty()) { - return EmptyPathTree.getInstance(); - } - if (trees.size() == 1) { - return trees.get(0); - } - return new MultiRootPathTree(trees.toArray(new PathTree[0])); - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultArtifactSources.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultArtifactSources.java deleted file mode 100644 index e0be20ac3974f..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultArtifactSources.java +++ /dev/null @@ -1,53 +0,0 @@ -package io.quarkus.bootstrap.workspace; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Objects; - -public class DefaultArtifactSources implements ArtifactSources, Serializable { - - private final String classifier; - private final Collection sources; - private final Collection resources; - - public DefaultArtifactSources(String classifier, Collection sources, Collection resources) { - this.classifier = Objects.requireNonNull(classifier, "The classifier is null"); - this.sources = sources; - this.resources = resources; - } - - @Override - public String getClassifier() { - return classifier; - } - - public void addSources(SourceDir src) { - this.sources.add(src); - } - - @Override - public Collection getSourceDirs() { - return sources; - } - - public void addResources(SourceDir src) { - this.resources.add(src); - } - - @Override - public Collection getResourceDirs() { - return resources; - } - - @Override - public String toString() { - final StringBuilder s = new StringBuilder(); - s.append(classifier); - if (s.length() > 0) { - s.append(' '); - } - s.append("sources: ").append(sources); - s.append(" resources: ").append(resources); - return s.toString(); - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultSourceDir.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultProcessedSources.java similarity index 52% rename from independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultSourceDir.java rename to independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultProcessedSources.java index 39a8ce9b2da12..e5171b4767690 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultSourceDir.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultProcessedSources.java @@ -1,53 +1,36 @@ package io.quarkus.bootstrap.workspace; -import io.quarkus.paths.DirectoryPathTree; -import io.quarkus.paths.PathTree; import java.io.File; import java.io.Serializable; -import java.nio.file.Path; import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.Objects; -public class DefaultSourceDir implements SourceDir, Serializable { +public class DefaultProcessedSources implements ProcessedSources, Serializable { - private final PathTree srcTree; - private final PathTree outputTree; + private final File srcDir; + private final File destinationDir; private final Map data; - public DefaultSourceDir(File srcDir, File destinationDir) { + public DefaultProcessedSources(File srcDir, File destinationDir) { this(srcDir, destinationDir, Collections.emptyMap()); } - public DefaultSourceDir(File srcDir, File destinationDir, Map data) { - this(new DirectoryPathTree(srcDir.toPath()), new DirectoryPathTree(destinationDir.toPath()), data); - } - - public DefaultSourceDir(PathTree srcTree, PathTree outputTree, Map data) { - this.srcTree = srcTree; - this.outputTree = outputTree; + public DefaultProcessedSources(File srcDir, File destinationDir, Map data) { + this.srcDir = srcDir; + this.destinationDir = destinationDir; this.data = data; } @Override - public Path getDir() { - return srcTree.getRoots().iterator().next(); - } - - @Override - public PathTree getSourceTree() { - return srcTree; - } - - @Override - public Path getOutputDir() { - return outputTree.getRoots().iterator().next(); + public File getSourceDir() { + return srcDir; } @Override - public PathTree getOutputTree() { - return outputTree; + public File getDestinationDir() { + return destinationDir; } public T getValue(Object key, Class type) { @@ -57,7 +40,7 @@ public T getValue(Object key, Class type) { @Override public int hashCode() { - return Objects.hash(data, outputTree, srcTree); + return Objects.hash(data, destinationDir, srcDir); } @Override @@ -68,15 +51,15 @@ public boolean equals(Object obj) { return false; if (getClass() != obj.getClass()) return false; - DefaultSourceDir other = (DefaultSourceDir) obj; - return Objects.equals(data, other.data) && Objects.equals(outputTree, other.outputTree) - && Objects.equals(srcTree, other.srcTree); + DefaultProcessedSources other = (DefaultProcessedSources) obj; + return Objects.equals(data, other.data) && Objects.equals(destinationDir, other.destinationDir) + && Objects.equals(srcDir, other.srcDir); } @Override public String toString() { final StringBuilder buf = new StringBuilder(); - buf.append(srcTree.getRoots()).append(" -> ").append(outputTree.getRoots()); + buf.append(srcDir).append(" -> ").append(destinationDir); if (!data.isEmpty()) { final Iterator> i = data.entrySet().iterator(); Map.Entry e = i.next(); diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultWorkspaceModule.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultWorkspaceModule.java index 77c2a1248a735..6377863c7c3ec 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultWorkspaceModule.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultWorkspaceModule.java @@ -4,20 +4,20 @@ import io.quarkus.paths.PathList; import java.io.File; import java.io.Serializable; +import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +import java.util.Iterator; public class DefaultWorkspaceModule implements WorkspaceModule, Serializable { - public static final String MAIN = ""; - public static final String TEST = "tests"; - private final WorkspaceModuleId id; private final File moduleDir; private final File buildDir; + private final Collection mainSources = new ArrayList<>(1); + private final Collection mainResources = new ArrayList<>(1); + private final Collection testSources = new ArrayList<>(1); + private final Collection testResources = new ArrayList<>(1); private PathCollection buildFiles; - private final Map sourcesSets = new HashMap<>(); public DefaultWorkspaceModule(WorkspaceModuleId id, File moduleDir, File buildDir) { super(); @@ -41,23 +41,40 @@ public File getBuildDir() { return buildDir; } - public void addArtifactSources(ArtifactSources src) { - sourcesSets.put(src.getClassifier(), src); + @Override + public Collection getMainSources() { + return mainSources; + } + + public void addMainSources(ProcessedSources mainSources) { + this.mainSources.add(mainSources); } @Override - public boolean hasSources(String classifier) { - return sourcesSets.containsKey(classifier); + public Collection getMainResources() { + return mainResources; + } + + public void addMainResources(ProcessedSources mainResources) { + this.mainResources.add(mainResources); } @Override - public ArtifactSources getSources(String name) { - return sourcesSets.get(name); + public Collection getTestSources() { + return testSources; + } + + public void addTestSources(ProcessedSources testSources) { + this.testSources.add(testSources); } @Override - public Collection getSourceClassifiers() { - return sourcesSets.keySet(); + public Collection getTestResources() { + return testResources; + } + + public void addTestResources(ProcessedSources testResources) { + this.testResources.add(testResources); } public void setBuildFiles(PathCollection buildFiles) { @@ -74,9 +91,22 @@ public String toString() { final StringBuilder buf = new StringBuilder(); buf.append(id); buf.append(" ").append(moduleDir); - sourcesSets.values().forEach(a -> { - buf.append(" ").append(a); - }); + appendSources(buf, "sources", getMainSources()); + appendSources(buf, "resources", getMainResources()); + appendSources(buf, "test-sources", getTestSources()); + appendSources(buf, "test-resources", getTestResources()); return buf.toString(); } + + private void appendSources(StringBuilder buf, String name, Collection sources) { + if (!sources.isEmpty()) { + buf.append(" ").append(name).append("["); + final Iterator i = sources.iterator(); + buf.append(i.next()); + while (i.hasNext()) { + buf.append(";").append(i.next()); + } + buf.append("]"); + } + } } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/ProcessedSources.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/ProcessedSources.java new file mode 100644 index 0000000000000..1ff2191407cf0 --- /dev/null +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/ProcessedSources.java @@ -0,0 +1,14 @@ +package io.quarkus.bootstrap.workspace; + +import java.io.File; + +public interface ProcessedSources { + + File getSourceDir(); + + File getDestinationDir(); + + default T getValue(Object key, Class type) { + return null; + } +} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/SourceDir.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/SourceDir.java deleted file mode 100644 index 731e737a2222c..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/SourceDir.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.quarkus.bootstrap.workspace; - -import io.quarkus.paths.PathTree; -import java.nio.file.Files; -import java.nio.file.Path; - -public interface SourceDir { - - Path getDir(); - - PathTree getSourceTree(); - - default boolean isOutputAvailable() { - final Path outputDir = getOutputDir(); - return outputDir != null && Files.exists(outputDir); - } - - Path getOutputDir(); - - PathTree getOutputTree(); - - default T getValue(Object key, Class type) { - return null; - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/WorkspaceModule.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/WorkspaceModule.java index d28959db8ced7..42e8f02154885 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/WorkspaceModule.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/WorkspaceModule.java @@ -1,8 +1,6 @@ package io.quarkus.bootstrap.workspace; -import io.quarkus.paths.EmptyPathTree; import io.quarkus.paths.PathCollection; -import io.quarkus.paths.PathTree; import java.io.File; import java.util.Collection; @@ -14,33 +12,13 @@ public interface WorkspaceModule { File getBuildDir(); - Collection getSourceClassifiers(); + Collection getMainSources(); - boolean hasSources(String classifier); + Collection getMainResources(); - ArtifactSources getSources(String classifier); + Collection getTestSources(); - default boolean hasMainSources() { - return hasSources(DefaultWorkspaceModule.MAIN); - } - - default boolean hasTestSources() { - return hasSources(DefaultWorkspaceModule.TEST); - } - - default ArtifactSources getMainSources() { - return getSources(DefaultWorkspaceModule.MAIN); - } - - default ArtifactSources getTestSources() { - return getSources(DefaultWorkspaceModule.TEST); - } + Collection getTestResources(); PathCollection getBuildFiles(); - - default PathTree getContentTree(String classifier) { - final ArtifactSources artifactSources = getSources(classifier); - return artifactSources == null || !artifactSources.isOutputAvailable() ? EmptyPathTree.getInstance() - : artifactSources.getOutputTree(); - } } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactDependency.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactDependency.java index dc78018058e29..368913b4acc6b 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactDependency.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ArtifactDependency.java @@ -5,10 +5,6 @@ public class ArtifactDependency extends GACTV implements Dependency, Serializable { - public static ArtifactDependency of(String groupId, String artifactId, String version) { - return new ArtifactDependency(groupId, artifactId, null, ArtifactCoords.TYPE_JAR, version); - } - private final String scope; private int flags; diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/Dependency.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/Dependency.java index a027e48c3c0d3..9cd0e8cd93f06 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/Dependency.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/Dependency.java @@ -26,12 +26,12 @@ default boolean isDeploymentCp() { return isFlagSet(DependencyFlags.DEPLOYMENT_CP); } - default boolean isWorkspaceModule() { + default boolean isWorkspacetModule() { return isFlagSet(DependencyFlags.WORKSPACE_MODULE); } default boolean isReloadable() { - return isFlagSet(DependencyFlags.RELOADABLE) && isWorkspaceModule(); + return isFlagSet(DependencyFlags.RELOADABLE) && isWorkspacetModule(); } default boolean isFlagSet(int flag) { diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACT.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACT.java index 86cc3a3171c5b..11c4ff648b4d2 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACT.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACT.java @@ -127,11 +127,11 @@ public boolean equals(Object obj) { return true; if (obj == null) return false; - if (!(obj instanceof ArtifactKey)) + if (getClass() != obj.getClass()) return false; - ArtifactKey other = (ArtifactKey) obj; - return Objects.equals(artifactId, other.getArtifactId()) && Objects.equals(classifier, other.getClassifier()) - && Objects.equals(groupId, other.getGroupId()) && Objects.equals(type, other.getType()); + GACT other = (GACT) obj; + return Objects.equals(artifactId, other.artifactId) && Objects.equals(classifier, other.classifier) + && Objects.equals(groupId, other.groupId) && Objects.equals(type, other.type); } @Override @@ -148,4 +148,13 @@ public String toString() { } return buf.toString(); } + + public String toGacString() { + final StringBuilder buf = new StringBuilder(); + buf.append(groupId).append(':').append(artifactId); + if (!classifier.isEmpty()) { + buf.append(':').append(classifier); + } + return buf.toString(); + } } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedArtifactDependency.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedArtifactDependency.java index 378f1e5759cb5..aa7274e45168a 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedArtifactDependency.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedArtifactDependency.java @@ -3,7 +3,6 @@ import io.quarkus.bootstrap.workspace.WorkspaceModule; import io.quarkus.paths.PathCollection; import io.quarkus.paths.PathList; -import io.quarkus.paths.PathTree; import java.io.Serializable; import java.nio.file.Path; import java.util.Objects; @@ -12,7 +11,6 @@ public class ResolvedArtifactDependency extends ArtifactDependency implements Re private PathCollection paths; private WorkspaceModule module; - private volatile transient PathTree contentTree; public ResolvedArtifactDependency(ArtifactCoords coords) { this(coords, (PathCollection) null); @@ -58,11 +56,6 @@ public WorkspaceModule getWorkspaceModule() { return module; } - @Override - public PathTree getContentTree() { - return contentTree == null ? contentTree = ResolvableDependency.super.getContentTree() : contentTree; - } - @Override public int hashCode() { final int prime = 31; diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedDependency.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedDependency.java index ddaace060a9c9..0c0b3cd118697 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedDependency.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/ResolvedDependency.java @@ -1,12 +1,7 @@ package io.quarkus.maven.dependency; -import io.quarkus.bootstrap.workspace.ArtifactSources; import io.quarkus.bootstrap.workspace.WorkspaceModule; -import io.quarkus.paths.EmptyPathTree; -import io.quarkus.paths.MultiRootPathTree; import io.quarkus.paths.PathCollection; -import io.quarkus.paths.PathTree; -import java.nio.file.Path; public interface ResolvedDependency extends Dependency { @@ -20,31 +15,4 @@ default boolean isResolved() { default WorkspaceModule getWorkspaceModule() { return null; } - - default ArtifactSources getSources() { - final WorkspaceModule module = getWorkspaceModule(); - return module == null ? null : module.getSources(getClassifier()); - } - - default PathTree getContentTree() { - final WorkspaceModule module = getWorkspaceModule(); - final PathTree workspaceTree = module == null ? EmptyPathTree.getInstance() : module.getContentTree(getClassifier()); - if (!workspaceTree.isEmpty()) { - return workspaceTree; - } - final PathCollection paths = getResolvedPaths(); - if (paths == null || paths.isEmpty()) { - return EmptyPathTree.getInstance(); - } - if (paths.isSinglePath()) { - final Path p = paths.getSinglePath(); - return PathTree.ofDirectoryOrArchive(p); - } - final PathTree[] trees = new PathTree[paths.size()]; - int i = 0; - for (Path p : paths) { - trees[i++] = PathTree.ofDirectoryOrArchive(p); - } - return new MultiRootPathTree(trees); - } } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/ArchivePathTree.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/ArchivePathTree.java deleted file mode 100644 index b50549eb7ace3..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/ArchivePathTree.java +++ /dev/null @@ -1,156 +0,0 @@ -package io.quarkus.paths; - -import io.quarkus.fs.util.ZipUtils; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.FileSystem; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Objects; -import java.util.function.Function; -import java.util.jar.Manifest; - -public class ArchivePathTree extends PathTreeWithManifest implements PathTree { - - private final Path archive; - private final PathFilter pathFilter; - - public ArchivePathTree(Path archive) { - this(archive, null); - } - - ArchivePathTree(Path archive, PathFilter pathFilter) { - this.archive = archive; - this.pathFilter = pathFilter; - } - - @Override - public Collection getRoots() { - return Collections.singletonList(archive); - } - - @Override - public void walk(PathVisitor visitor) { - try (FileSystem fs = openFs()) { - final Path dir = fs.getPath("/"); - PathTreeVisit.walk(archive, dir, pathFilter, getMultiReleaseMapping(), visitor); - } catch (IOException e) { - throw new UncheckedIOException("Failed to read " + archive, e); - } - } - - @Override - public T processPath(String relativePath, Function func, boolean multiReleaseSupport) { - if (!PathFilter.isVisible(pathFilter, relativePath)) { - return func.apply(null); - } - if (multiReleaseSupport) { - relativePath = toMultiReleaseRelativePath(relativePath); - } - try (FileSystem fs = openFs()) { - for (Path root : fs.getRootDirectories()) { - final Path path = root.resolve(relativePath); - if (!Files.exists(path)) { - continue; - } - return PathTreeVisit.processPath(archive, root, path, pathFilter, func); - } - } catch (IOException e) { - throw new UncheckedIOException("Failed to read " + archive, e); - } - return func.apply(null); - } - - private FileSystem openFs() throws IOException { - return ZipUtils.newFileSystem(archive); - } - - @Override - public OpenPathTree openTree() { - try { - return new OpenArchivePathTree(openFs()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - @Override - public int hashCode() { - return Objects.hash(archive, pathFilter); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ArchivePathTree other = (ArchivePathTree) obj; - return Objects.equals(archive, other.archive) && Objects.equals(pathFilter, other.pathFilter); - } - - private class OpenArchivePathTree extends DirectoryPathTree { - - private final FileSystem fs; - - private OpenArchivePathTree(FileSystem fs) { - super(fs.getPath("/"), pathFilter, ArchivePathTree.this); - this.fs = fs; - } - - @Override - protected void initManifest(Manifest m) { - super.initManifest(m); - ArchivePathTree.this.manifestReadLock().lock(); - try { - if (!ArchivePathTree.this.manifestInitialized) { - ArchivePathTree.this.manifestReadLock().unlock(); - ArchivePathTree.this.manifestWriteLock().lock(); - ArchivePathTree.this.initManifest(m); - ArchivePathTree.this.manifestReadLock().lock(); - ArchivePathTree.this.manifestWriteLock().unlock(); - } - } finally { - ArchivePathTree.this.manifestReadLock().unlock(); - } - } - - @Override - protected void initMultiReleaseMapping(Map mrMapping) { - super.initMultiReleaseMapping(mrMapping); - if (ArchivePathTree.this.multiReleaseMapping == null) { - ArchivePathTree.this.initMultiReleaseMapping(mrMapping); - } - } - - @Override - public void close() throws IOException { - Throwable t = null; - try { - super.close(); - } catch (Throwable e) { - t = e; - throw e; - } finally { - try { - fs.close(); - } catch (IOException e) { - if (t != null) { - e.addSuppressed(t); - } - throw e; - } - } - } - - @Override - public PathTree getOriginalTree() { - return ArchivePathTree.this; - } - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/CachingPathTree.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/CachingPathTree.java deleted file mode 100644 index 26ae659cdda57..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/CachingPathTree.java +++ /dev/null @@ -1,191 +0,0 @@ -package io.quarkus.paths; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.file.Path; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Objects; -import java.util.function.Function; -import java.util.jar.Manifest; - -public class CachingPathTree implements OpenPathTree { - - public static CachingPathTree of(PathTree pathTree) { - return new CachingPathTree(pathTree); - } - - private final PathTree delegate; - private volatile LinkedHashMap walkSnapshot; - - private CachingPathTree(PathTree delegate) { - this.delegate = delegate; - } - - @Override - public Collection getRoots() { - return delegate.getRoots(); - } - - @Override - public Manifest getManifest() { - return delegate.getManifest(); - } - - @Override - public void walk(PathVisitor visitor) { - final LinkedHashMap snapshot = walkSnapshot; - if (snapshot != null) { - final PathVisitWrapper wrapper = new PathVisitWrapper(); - for (PathVisitSnapshot visit : snapshot.values()) { - wrapper.target = visit; - visitor.visitPath(wrapper); - if (wrapper.stopWalking) { - break; - } - } - return; - } - - final LinkedHashMap walkSnapshot = new LinkedHashMap<>(); - final PathVisitWrapper wrapper = new PathVisitWrapper(); - delegate.walk(new PathVisitor() { - @Override - public void visitPath(PathVisit visit) { - final PathVisitSnapshot snapshot = new PathVisitSnapshot(visit); - walkSnapshot.put(snapshot.getRelativePath("/"), snapshot); - if (wrapper.stopWalking) { - return; - } - wrapper.target = snapshot; - visitor.visitPath(wrapper); - } - }); - if (this.walkSnapshot == null) { - this.walkSnapshot = walkSnapshot; - } - } - - @Override - public T processPath(String relativePath, Function func, boolean multiReleaseSupport) { - final LinkedHashMap snapshot = walkSnapshot; - if (snapshot != null) { - return func.apply((PathVisit) snapshot.get(relativePath)); - } - return delegate.processPath(relativePath, func, multiReleaseSupport); - } - - @Override - public OpenPathTree openTree() { - return this; - } - - @Override - public void close() throws IOException { - walkSnapshot = null; - if (delegate instanceof OpenPathTree) { - ((OpenPathTree) delegate).close(); - } - } - - @Override - public PathTree getOriginalTree() { - return delegate instanceof OpenPathTree ? ((OpenPathTree) delegate).getOriginalTree() : delegate; - } - - @Override - public int hashCode() { - return Objects.hash(delegate); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - CachingPathTree other = (CachingPathTree) obj; - return Objects.equals(delegate, other.delegate); - } - - private static class PathVisitWrapper implements PathVisit { - PathVisit target; - boolean stopWalking; - - @Override - public Path getRoot() { - return target.getRoot(); - } - - @Override - public Path getPath() { - return target.getPath(); - } - - @Override - public String getRelativePath(String separator) { - return target.getRelativePath(separator); - } - - @Override - public URL getUrl() { - return target.getUrl(); - } - - @Override - public void stopWalking() { - stopWalking = true; - } - } - - private static class PathVisitSnapshot implements PathVisit { - - private final Path root; - private final Path path; - private final String relativePathStr; - private volatile URL url; - - private PathVisitSnapshot(PathVisit visit) { - this.root = visit.getRoot(); - this.path = visit.getPath(); - this.relativePathStr = visit.getRelativePath("/"); - } - - @Override - public Path getRoot() { - return root; - } - - @Override - public Path getPath() { - return path; - } - - @Override - public URL getUrl() { - if (url != null) { - return url; - } - try { - return url = path.toUri().toURL(); - } catch (MalformedURLException e) { - throw new RuntimeException("Failed to translate " + path.toUri() + " to a URL", e); - } - } - - @Override - public String getRelativePath(String separator) { - if (!path.getFileSystem().getSeparator().equals("/")) { - return relativePathStr.replace("/", path.getFileSystem().getSeparator()); - } - return relativePathStr; - } - - @Override - public void stopWalking() { - } - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/DirectoryPathTree.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/DirectoryPathTree.java deleted file mode 100644 index 731ec7df5ac9f..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/DirectoryPathTree.java +++ /dev/null @@ -1,95 +0,0 @@ -package io.quarkus.paths; - -import java.io.IOException; -import java.io.Serializable; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Collection; -import java.util.Collections; -import java.util.Objects; -import java.util.function.Function; - -public class DirectoryPathTree extends PathTreeWithManifest implements OpenPathTree, Serializable { - - private Path dir; - private PathFilter pathFilter; - - public DirectoryPathTree(Path dir) { - this(dir, null); - } - - public DirectoryPathTree(Path dir, PathFilter pathFilter) { - this.dir = dir; - this.pathFilter = pathFilter; - } - - protected DirectoryPathTree(Path dir, PathFilter pathFilter, PathTreeWithManifest pathTreeWithManifest) { - super(pathTreeWithManifest); - this.dir = dir; - this.pathFilter = pathFilter; - } - - @Override - public Collection getRoots() { - return Collections.singletonList(dir); - } - - @Override - public void walk(PathVisitor visitor) { - PathTreeVisit.walk(dir, dir, pathFilter, getMultiReleaseMapping(), visitor); - } - - @Override - public T processPath(String relativePath, Function func, boolean multiReleaseSupport) { - if (!PathFilter.isVisible(pathFilter, relativePath)) { - return func.apply(null); - } - final Path path = dir.resolve(multiReleaseSupport ? toMultiReleaseRelativePath(relativePath) : relativePath); - if (!Files.exists(path)) { - return func.apply(null); - } - return PathTreeVisit.processPath(dir, dir, path, pathFilter, func); - } - - private void writeObject(java.io.ObjectOutputStream out) throws IOException { - out.writeUTF(dir.toAbsolutePath().toString()); - out.writeObject(pathFilter); - } - - private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { - dir = Paths.get(in.readUTF()); - pathFilter = (PathFilter) in.readObject(); - } - - @Override - public OpenPathTree openTree() { - return this; - } - - @Override - public void close() throws IOException { - } - - @Override - public PathTree getOriginalTree() { - return this; - } - - @Override - public int hashCode() { - return Objects.hash(dir, pathFilter); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - DirectoryPathTree other = (DirectoryPathTree) obj; - return Objects.equals(dir, other.dir) && Objects.equals(pathFilter, other.pathFilter); - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/EmptyPathTree.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/EmptyPathTree.java deleted file mode 100644 index bfba4a0867de9..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/EmptyPathTree.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.quarkus.paths; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.Collection; -import java.util.Collections; -import java.util.function.Function; -import java.util.jar.Manifest; - -public class EmptyPathTree implements OpenPathTree { - - private static final EmptyPathTree INSTANCE = new EmptyPathTree(); - - public static EmptyPathTree getInstance() { - return INSTANCE; - } - - @Override - public Collection getRoots() { - return Collections.emptyList(); - } - - @Override - public Manifest getManifest() { - return null; - } - - @Override - public void walk(PathVisitor visitor) { - } - - @Override - public T processPath(String relativePath, Function func, boolean multiReleaseSupport) { - return func.apply(null); - } - - @Override - public OpenPathTree openTree() { - return this; - } - - @Override - public void close() throws IOException { - } - - @Override - public PathTree getOriginalTree() { - return this; - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/FilePathTree.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/FilePathTree.java deleted file mode 100644 index 9ffbd2c5ab468..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/FilePathTree.java +++ /dev/null @@ -1,106 +0,0 @@ -package io.quarkus.paths; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.Collection; -import java.util.Collections; -import java.util.Objects; -import java.util.function.Function; -import java.util.jar.Manifest; - -class FilePathTree implements OpenPathTree { - - private final Path file; - private final PathFilter pathFilter; - - FilePathTree(Path file) { - this(file, null); - } - - FilePathTree(Path file, PathFilter pathFilter) { - this.file = file; - this.pathFilter = pathFilter; - } - - @Override - public Collection getRoots() { - return Collections.singletonList(file); - } - - @Override - public Manifest getManifest() { - return null; - } - - @Override - public void walk(PathVisitor visitor) { - if (pathFilter != null) { - final String pathStr = file.getFileSystem().getSeparator().equals("/") ? file.toString() - : file.toString().replace('\\', '/'); - if (!pathFilter.isVisible(pathStr)) { - return; - } - return; - } - visitor.visitPath(new PathVisit() { - - @Override - public Path getRoot() { - return file; - } - - @Override - public Path getPath() { - return file; - } - - @Override - public void stopWalking() { - } - - @Override - public String getRelativePath(String separator) { - return ""; - } - }); - } - - @Override - public T processPath(String relativePath, Function func, boolean multiReleaseSupport) { - if (relativePath.isEmpty()) { - return PathTreeVisit.processPath(file, file, file, pathFilter, func); - } - return func.apply(null); - } - - @Override - public OpenPathTree openTree() { - return this; - } - - @Override - public void close() throws IOException { - } - - @Override - public PathTree getOriginalTree() { - return this; - } - - @Override - public int hashCode() { - return Objects.hash(file, pathFilter); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - FilePathTree other = (FilePathTree) obj; - return Objects.equals(file, other.file) && Objects.equals(pathFilter, other.pathFilter); - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/MultiRootPathTree.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/MultiRootPathTree.java deleted file mode 100644 index 9fe8db765520a..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/MultiRootPathTree.java +++ /dev/null @@ -1,97 +0,0 @@ -package io.quarkus.paths; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.function.Function; -import java.util.jar.Manifest; - -public class MultiRootPathTree implements OpenPathTree { - - private final PathTree[] trees; - private final List roots; - - public MultiRootPathTree(PathTree... trees) { - this.trees = trees; - final ArrayList tmp = new ArrayList<>(); - for (PathTree t : trees) { - tmp.addAll(t.getRoots()); - } - tmp.trimToSize(); - roots = tmp; - } - - @Override - public Collection getRoots() { - return roots; - } - - @Override - public Manifest getManifest() { - for (PathTree tree : trees) { - final Manifest m = tree.getManifest(); - if (m != null) { - return m; - } - } - return null; - } - - @Override - public void walk(PathVisitor visitor) { - if (trees.length == 0) { - return; - } - for (PathTree t : trees) { - t.walk(visitor); - } - } - - @Override - public T processPath(String relativePath, Function func, boolean multiReleaseSupport) { - for (PathTree tree : trees) { - T result = tree.processPath(relativePath, func, multiReleaseSupport); - if (result != null) { - return result; - } - } - return null; - } - - @Override - public OpenPathTree openTree() { - return this; - } - - @Override - public void close() throws IOException { - } - - @Override - public PathTree getOriginalTree() { - return this; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.hashCode(trees); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - MultiRootPathTree other = (MultiRootPathTree) obj; - return Arrays.equals(trees, other.trees); - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/OpenPathTree.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/OpenPathTree.java deleted file mode 100644 index a3089609db5f2..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/OpenPathTree.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.quarkus.paths; - -import java.io.Closeable; - -public interface OpenPathTree extends PathTree, Closeable { - - PathTree getOriginalTree(); -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathCollection.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathCollection.java index a91d730a151a3..ff5d13b0072b6 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathCollection.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathCollection.java @@ -1,9 +1,6 @@ package io.quarkus.paths; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Stream; public interface PathCollection extends Iterable { @@ -29,12 +26,4 @@ default Path getSinglePath() { PathCollection addAllFirst(Iterable i); Path resolveExistingOrNull(String path); - - default Stream stream() { - final List list = new ArrayList<>(size()); - for (Path p : this) { - list.add(p); - } - return list.stream(); - } } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathFilter.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathFilter.java deleted file mode 100644 index 678a6b26be193..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathFilter.java +++ /dev/null @@ -1,108 +0,0 @@ -package io.quarkus.paths; - -import io.quarkus.util.GlobUtil; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.regex.Pattern; - -public class PathFilter implements Serializable { - - public static boolean isVisible(PathFilter filter, String path) { - if (filter == null) { - return true; - } - return filter.isVisible(path.replace('\\', '/')); - } - - public static PathFilter forIncludes(Collection includes) { - return new PathFilter(includes, null); - } - - public static PathFilter forExcludes(Collection excludes) { - return new PathFilter(null, excludes); - } - - private List includes; - private List excludes; - - public PathFilter(Collection includes, Collection excludes) { - this.includes = compile(includes); - this.excludes = compile(excludes); - } - - public boolean isVisible(String pathStr) { - if (includes != null && !includes.isEmpty()) { - int i = 0; - while (i < includes.size()) { - if (includes.get(i).matcher(pathStr).matches()) { - break; - } - ++i; - } - if (i == includes.size()) { - return false; - } - } - if (excludes != null) { - for (Pattern pattern : excludes) { - if (pattern.matcher(pathStr).matches()) { - return false; - } - } - return true; - } - return true; - } - - @Override - public int hashCode() { - return Objects.hash(excludes, includes); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - PathFilter other = (PathFilter) obj; - return Objects.equals(excludes, other.excludes) && Objects.equals(includes, other.includes); - } - - @Override - public String toString() { - final StringBuilder s = new StringBuilder(); - if (includes != null && !includes.isEmpty()) { - s.append("includes ").append(includes.get(0).pattern()); - for (int i = 1; i < includes.size(); ++i) { - s.append(",").append(includes.get(i)); - } - } - if (excludes != null && !excludes.isEmpty()) { - if (s.length() > 0) { - s.append(" "); - } - s.append("excludes ").append(excludes.get(0).pattern()); - for (int i = 1; i < excludes.size(); ++i) { - s.append(",").append(excludes.get(i)); - } - } - return s.toString(); - } - - private static List compile(Collection expressions) { - if (expressions == null) { - return null; - } - final List compiled = new ArrayList<>(expressions.size()); - for (String expr : expressions) { - compiled.add(Pattern.compile(GlobUtil.toRegexPattern(expr))); - } - return compiled; - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathList.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathList.java index e858c9b730253..84a39c330f744 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathList.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathList.java @@ -7,10 +7,10 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Objects; public class PathList implements PathCollection, Serializable { @@ -133,23 +133,6 @@ public String toString() { return buf.append(']').toString(); } - @Override - public int hashCode() { - return Objects.hash(paths); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - PathList other = (PathList) obj; - return Objects.equals(paths, other.paths); - } - private void writeObject(java.io.ObjectOutputStream out) throws IOException { out.writeInt(paths.size()); for (Path p : paths) { @@ -165,4 +148,8 @@ private void readObject(java.io.ObjectInputStream in) throws IOException, ClassN } this.paths = Collections.unmodifiableList(paths); } -} + + public Collection toList() { + return new ArrayList<>(paths); + } +} \ No newline at end of file diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTree.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTree.java deleted file mode 100644 index 5acc965350128..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTree.java +++ /dev/null @@ -1,71 +0,0 @@ -package io.quarkus.paths; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.Collection; -import java.util.function.Function; -import java.util.jar.Manifest; - -public interface PathTree { - - static PathTree of(Path p) { - try { - BasicFileAttributes fileAttributes = Files.readAttributes(p, BasicFileAttributes.class); - if (fileAttributes.isDirectory()) { - return new DirectoryPathTree(p); - } - - return new FilePathTree(p); - } catch (IOException e) { - throw new IllegalArgumentException(p + " does not exist", e); - } - } - - static PathTree ofDirectoryOrArchive(Path p) { - try { - BasicFileAttributes fileAttributes = Files.readAttributes(p, BasicFileAttributes.class); - if (fileAttributes.isDirectory()) { - return new DirectoryPathTree(p); - } - - return new ArchivePathTree(p); - } catch (IOException e) { - throw new IllegalArgumentException(p + " does not exist", e); - } - } - - static PathTree ofArchive(Path archive) { - if (!Files.exists(archive)) { - throw new IllegalArgumentException(archive + " does not exist"); - } - return new ArchivePathTree(archive); - } - - static PathTreeBuilder builder() { - return new PathTreeBuilder(false); - } - - static PathTreeBuilder archiveBuilder() { - return new PathTreeBuilder(true); - } - - Collection getRoots(); - - default boolean isEmpty() { - return getRoots().isEmpty(); - } - - Manifest getManifest(); - - void walk(PathVisitor visitor); - - default T processPath(String relativePath, Function func) { - return processPath(relativePath, func, true); - } - - T processPath(String relativePath, Function func, boolean multiReleaseSupport); - - OpenPathTree openTree(); -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTreeBuilder.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTreeBuilder.java deleted file mode 100644 index fb8b2333a3df3..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTreeBuilder.java +++ /dev/null @@ -1,71 +0,0 @@ -package io.quarkus.paths; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -public class PathTreeBuilder { - - private final boolean archive; - private Path root; - private List includes; - private List excludes; - - public PathTreeBuilder(boolean archive) { - this.archive = archive; - } - - public PathTreeBuilder setRoot(Path root) { - this.root = root; - return this; - } - - Path getRoot() { - return root; - } - - public PathTreeBuilder include(String expr) { - if (includes == null) { - includes = new ArrayList<>(1); - } - includes.add(expr); - return this; - } - - List getIncludes() { - return includes; - } - - public PathTreeBuilder exclude(String expr) { - if (excludes == null) { - excludes = new ArrayList<>(1); - } - excludes.add(expr); - return this; - } - - List getExcludes() { - return includes; - } - - PathFilter getPathFilter() { - return includes == null && excludes == null ? null : new PathFilter(includes, excludes); - } - - public PathTree build() { - if (root == null) { - throw new RuntimeException("The tree root has not been provided"); - } - if (!Files.exists(root)) { - throw new IllegalArgumentException(root + " does not exist"); - } - if (archive) { - return new ArchivePathTree(root, getPathFilter()); - } - if (Files.isDirectory(root)) { - return new DirectoryPathTree(root, getPathFilter()); - } - return new FilePathTree(root, getPathFilter()); - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTreeVisit.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTreeVisit.java deleted file mode 100644 index e9bb7675618a9..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTreeVisit.java +++ /dev/null @@ -1,122 +0,0 @@ -package io.quarkus.paths; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Stream; - -class PathTreeVisit implements PathVisit { - - static void walk(Path root, Path rootDir, PathFilter pathFilter, Map multiReleaseMapping, - PathVisitor visitor) { - final PathTreeVisit visit = new PathTreeVisit(root, rootDir, pathFilter, multiReleaseMapping); - try (Stream files = Files.walk(rootDir)) { - final Iterator i = files.iterator(); - while (i.hasNext()) { - if (!visit.setCurrent(i.next())) { - continue; - } - visitor.visitPath(visit); - if (visit.isStopWalking()) { - break; - } - } - } catch (IOException e) { - throw new UncheckedIOException("Failed to walk directory " + root, e); - } - visit.visitMultiReleasePaths(visitor); - } - - static T processPath(Path root, Path rootDir, Path path, PathFilter pathFilter, Function func) { - final PathTreeVisit visit = new PathTreeVisit(root, rootDir, pathFilter, Collections.emptyMap()); - if (visit.setCurrent(path)) { - return func.apply(visit); - } - return func.apply(null); - } - - private final Path root; - private final Path baseDir; - private final PathFilter pathFilter; - private final Map multiReleaseMapping; - - private Path current; - private String relativePath; - private boolean stopWalking; - - private PathTreeVisit(Path root, Path rootDir, PathFilter pathFilter, Map multiReleaseMapping) { - this.root = root; - this.baseDir = rootDir; - this.pathFilter = pathFilter; - this.multiReleaseMapping = multiReleaseMapping == null || multiReleaseMapping.isEmpty() ? Collections.emptyMap() - : new HashMap<>(multiReleaseMapping); - } - - @Override - public Path getRoot() { - return root; - } - - @Override - public Path getPath() { - return current; - } - - @Override - public void stopWalking() { - stopWalking = true; - } - - boolean isStopWalking() { - return stopWalking; - } - - @Override - public String getRelativePath(String separator) { - if (relativePath == null) { - return PathUtils.asString(baseDir.relativize(current), separator); - } - if (!current.getFileSystem().getSeparator().equals(separator)) { - return relativePath.replace(current.getFileSystem().getSeparator(), separator); - } - return relativePath; - } - - private boolean setCurrent(Path path) { - current = path; - relativePath = null; - if (pathFilter != null) { - relativePath = baseDir.relativize(path).toString(); - if (!PathFilter.isVisible(pathFilter, relativePath)) { - return false; - } - } - if (!multiReleaseMapping.isEmpty()) { - if (relativePath == null) { - relativePath = baseDir.relativize(path).toString(); - } - final String mrPath = multiReleaseMapping.remove(relativePath); - if (mrPath != null) { - current = baseDir.resolve(mrPath); - } - } - return true; - } - - private void visitMultiReleasePaths(PathVisitor visitor) { - for (Map.Entry mrEntry : multiReleaseMapping.entrySet()) { - relativePath = mrEntry.getKey(); - if (pathFilter != null && !PathFilter.isVisible(pathFilter, relativePath)) { - continue; - } - current = baseDir.resolve(mrEntry.getValue()); - visitor.visitPath(this); - } - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTreeWithManifest.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTreeWithManifest.java deleted file mode 100644 index 27f043eeaada3..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathTreeWithManifest.java +++ /dev/null @@ -1,193 +0,0 @@ -package io.quarkus.paths; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; -import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.jar.Manifest; -import java.util.stream.Stream; -import org.jboss.logging.Logger; - -public abstract class PathTreeWithManifest implements PathTree { - - private static final String META_INF_VERSIONS = "META-INF/versions/"; - public static final int JAVA_VERSION; - - static { - try { - final String versionStr = "version"; - Object v = Runtime.class.getMethod(versionStr).invoke(null); - List list = (List) v.getClass().getMethod(versionStr).invoke(v); - JAVA_VERSION = list.get(0); - } catch (Exception e) { - //version 8 - throw new IllegalStateException( - "Failed to obtain the Java vesion from java.lang.Runtime, possibly it's Java 8 which is not supported anymore", - e); - } - } - - private final ReentrantReadWriteLock manifestInfoLock = new ReentrantReadWriteLock(); - private transient Manifest manifest; - protected transient boolean manifestInitialized; - protected volatile Map multiReleaseMapping; - - public PathTreeWithManifest() { - } - - protected PathTreeWithManifest(PathTreeWithManifest pathTreeWithManifest) { - pathTreeWithManifest.manifestReadLock().lock(); - try { - this.manifest = pathTreeWithManifest.manifest; - this.manifestInitialized = pathTreeWithManifest.manifestInitialized; - this.multiReleaseMapping = pathTreeWithManifest.multiReleaseMapping; - } finally { - pathTreeWithManifest.manifestReadLock().unlock(); - } - } - - @Override - public Manifest getManifest() { - manifestReadLock().lock(); - try { - if (manifestInitialized) { - return manifest; - } - manifestReadLock().unlock(); - final Manifest m = processPath("META-INF/MANIFEST.MF", ManifestReader.INSTANCE, false); - manifestWriteLock().lock(); - initManifest(m); - manifestReadLock().lock(); - manifestWriteLock().unlock(); - } finally { - manifestReadLock().unlock(); - } - return manifest; - } - - protected void initManifest(Manifest m) { - manifest = m; - manifestInitialized = true; - } - - protected WriteLock manifestWriteLock() { - return manifestInfoLock.writeLock(); - } - - protected ReadLock manifestReadLock() { - return manifestInfoLock.readLock(); - } - - public boolean isMultiReleaseJar() { - return isMultiReleaseJar(getManifest()); - } - - protected Map getMultiReleaseMapping() { - if (multiReleaseMapping != null) { - return multiReleaseMapping; - } - final Map mrMapping = isMultiReleaseJar() - ? processPath(META_INF_VERSIONS, MultiReleaseMappingReader.INSTANCE, false) - : Collections.emptyMap(); - initMultiReleaseMapping(mrMapping); - return mrMapping; - } - - protected void initMultiReleaseMapping(final Map mrMapping) { - multiReleaseMapping = mrMapping; - } - - protected String toMultiReleaseRelativePath(String relativePath) { - return getMultiReleaseMapping().getOrDefault(relativePath, relativePath); - } - - private static boolean isMultiReleaseJar(final Manifest m) { - return m != null && Boolean.parseBoolean(m.getMainAttributes().getValue("Multi-Release")); - } - - private static class MultiReleaseMappingReader implements Function> { - - private static final MultiReleaseMappingReader INSTANCE = new MultiReleaseMappingReader(); - - @Override - public Map apply(PathVisit visit) { - if (visit == null) { - return Collections.emptyMap(); - } - final Path versionsDir = visit.getPath(); - if (!Files.isDirectory(versionsDir)) { - return Collections.emptyMap(); - } - final Path root = visit.getPath().getRoot(); - final TreeMap>> versionContentMap = new TreeMap<>(); - try (Stream versions = Files.list(versionsDir)) { - versions.forEach(versionDir -> { - if (!Files.isDirectory(versionDir)) { - return; - } - final int version; - try { - version = Integer.parseInt(versionDir.getFileName().toString()); - if (version > JAVA_VERSION) { - return; - } - } catch (NumberFormatException e) { - Logger.getLogger(PathTreeWithManifest.class) - .debug("Failed to parse " + versionDir + " entry", e); - return; - } - versionContentMap.put(version, new Consumer>() { - @Override - public void accept(Map map) { - try (Stream versionContent = Files.walk(versionDir)) { - versionContent.forEach(p -> { - final String relativePath = versionDir.relativize(p).toString(); - if (!relativePath.isEmpty()) { - map.put(relativePath, root.relativize(p).toString()); - } - }); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - }); - - }); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - final Map multiReleaseMapping = new HashMap<>(); - for (Consumer> c : versionContentMap.values()) { - c.accept(multiReleaseMapping); - } - return multiReleaseMapping; - } - } - - private static class ManifestReader implements Function { - private static final ManifestReader INSTANCE = new ManifestReader(); - - @Override - public Manifest apply(PathVisit visit) { - if (visit == null) { - return null; - } - try (InputStream is = Files.newInputStream(visit.getPath())) { - return new Manifest(is); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - } -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathUtils.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathUtils.java deleted file mode 100644 index a87a7f83e3e0a..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathUtils.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.quarkus.paths; - -import java.nio.file.Path; - -public interface PathUtils { - - static String asString(final Path path, String separator) { - if (path.getFileSystem().getSeparator().equals(separator)) { - return path.toString(); - } - final int nameCount = path.getNameCount(); - if (nameCount == 0) { - return ""; - } - if (nameCount == 1) { - return path.getName(0).toString(); - } - final StringBuilder s = new StringBuilder(); - s.append(path.getName(0)); - for (int i = 1; i < nameCount; ++i) { - s.append('/').append(path.getName(i).toString()); - } - return s.toString(); - } - -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathVisit.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathVisit.java deleted file mode 100644 index 261b7ef6c6716..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathVisit.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.quarkus.paths; - -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.file.Path; - -public interface PathVisit { - - Path getRoot(); - - Path getPath(); - - default URL getUrl() { - try { - return getPath().toUri().toURL(); - } catch (MalformedURLException e) { - throw new RuntimeException("Failed to translate " + getPath().toUri() + " to " + URL.class.getName(), e); - } - } - - String getRelativePath(String separator); - - void stopWalking(); -} diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathVisitor.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathVisitor.java deleted file mode 100644 index 2ffbb2cf22148..0000000000000 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/PathVisitor.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.quarkus.paths; - -public interface PathVisitor { - - void visitPath(PathVisit visit); -} diff --git a/independent-projects/bootstrap/core/pom.xml b/independent-projects/bootstrap/core/pom.xml index 7863d8238f0eb..0f4a3dfb153cc 100644 --- a/independent-projects/bootstrap/core/pom.xml +++ b/independent-projects/bootstrap/core/pom.xml @@ -45,6 +45,10 @@ io.quarkus quarkus-bootstrap-gradle-resolver + + io.quarkus + quarkus-fs-util + io.smallrye.common smallrye-common-io diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/BootstrapAppModelFactory.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/BootstrapAppModelFactory.java index 7b0c31f4f7468..c9e7b9c4cd4dc 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/BootstrapAppModelFactory.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/BootstrapAppModelFactory.java @@ -1,6 +1,7 @@ package io.quarkus.bootstrap; import io.quarkus.bootstrap.app.CurationResult; +import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.resolver.AppModelResolver; import io.quarkus.bootstrap.resolver.AppModelResolverException; @@ -22,6 +23,7 @@ import io.quarkus.maven.dependency.ArtifactDependency; import io.quarkus.maven.dependency.ArtifactKey; import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACT; import io.quarkus.maven.dependency.GACTV; import io.quarkus.maven.dependency.ResolvedArtifactDependency; import io.quarkus.maven.dependency.ResolvedDependency; @@ -38,10 +40,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import org.apache.maven.model.Dependency; import org.apache.maven.model.Model; import org.jboss.logging.Logger; @@ -105,8 +107,10 @@ public BootstrapAppModelFactory setDevMode(boolean devMode) { return this; } - public BootstrapAppModelFactory setLocalArtifacts(Set localArtifacts) { - this.reloadableModules = new HashSet<>(localArtifacts); + public BootstrapAppModelFactory setLocalArtifacts(Set localArtifacts) { + this.reloadableModules = localArtifacts.stream() + .map(k -> new GACT(k.getGroupId(), k.getArtifactId(), k.getClassifier(), k.getType())) + .collect(Collectors.toSet()); return this; } diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/IDELauncherImpl.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/IDELauncherImpl.java index 3f90687f6105b..4368e1f28fb19 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/IDELauncherImpl.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/IDELauncherImpl.java @@ -8,10 +8,7 @@ import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; import io.quarkus.bootstrap.util.BootstrapUtils; import io.quarkus.bootstrap.utils.BuildToolHelper; -import io.quarkus.bootstrap.workspace.ArtifactSources; -import io.quarkus.bootstrap.workspace.SourceDir; import io.quarkus.bootstrap.workspace.WorkspaceModule; -import io.quarkus.maven.dependency.ResolvedDependency; import java.io.Closeable; import java.io.IOException; import java.nio.file.Path; @@ -45,26 +42,25 @@ public static Closeable launch(Path classesDir, Map context) { final ApplicationModel quarkusModel = BuildToolHelper.enableGradleAppModelForDevMode(classesDir); context.put(BootstrapConstants.SERIALIZED_APP_MODEL, BootstrapUtils.serializeAppModel(quarkusModel, false)); - final Path launchingModulePath = quarkusModel.getApplicationModule().getMainSources().getSourceDirs().iterator() - .next().getOutputDir(); + final Path launchingModulePath = quarkusModel.getApplicationModule().getMainSources().iterator().next() + .getDestinationDir().toPath(); // Gradle uses a different output directory for classes, we override the one used by the IDE builder.setProjectRoot(launchingModulePath) .setApplicationRoot(launchingModulePath) .setTargetDirectory(quarkusModel.getApplicationModule().getBuildDir().toPath()); - for (ResolvedDependency dep : quarkusModel.getDependencies()) { - final WorkspaceModule module = dep.getWorkspaceModule(); - if (module == null) { - continue; - } - final ArtifactSources sources = module.getSources(dep.getClassifier()); - for (SourceDir dir : sources.getSourceDirs()) { - builder.addAdditionalApplicationArchive(new AdditionalDependency(dir.getOutputDir(), true, false)); - } - for (SourceDir dir : sources.getResourceDirs()) { - builder.addAdditionalApplicationArchive(new AdditionalDependency(dir.getOutputDir(), true, false)); - } + for (WorkspaceModule additionalModule : quarkusModel.getWorkspaceModules()) { + additionalModule.getMainSources().forEach(src -> { + builder.addAdditionalApplicationArchive( + new AdditionalDependency(src.getDestinationDir().toPath(), true, false)); + + }); + additionalModule.getMainResources().forEach(src -> { + builder.addAdditionalApplicationArchive( + new AdditionalDependency(src.getDestinationDir().toPath(), true, false)); + + }); } } else { builder.setApplicationRoot(classesDir) diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/AdditionalDependency.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/AdditionalDependency.java index 0639e25332691..8c550a165cd68 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/AdditionalDependency.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/AdditionalDependency.java @@ -38,10 +38,16 @@ public AdditionalDependency(Path archivePath, boolean hotReloadable, boolean for } /** + * @deprecated in favor of {@link #AdditionalDependency(PathCollection, boolean, boolean)} * @param archivePath archive paths * @param hotReloadable whether the dependency is reloadable * @param forceApplicationArchive whether it should be added as an application archive */ + @Deprecated + public AdditionalDependency(PathsCollection archivePath, boolean hotReloadable, boolean forceApplicationArchive) { + this(PathList.from(archivePath), hotReloadable, forceApplicationArchive); + } + public AdditionalDependency(PathCollection paths, boolean hotReloadable, boolean forceApplicationArchive) { this.paths = paths; this.hotReloadable = hotReloadable; diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java index f5632d9b247ba..b12c6d051bf6c 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java @@ -12,12 +12,11 @@ import io.quarkus.maven.dependency.ArtifactKey; import io.quarkus.maven.dependency.Dependency; import io.quarkus.maven.dependency.ResolvedDependency; -import io.quarkus.paths.OpenPathTree; -import io.quarkus.paths.PathTree; import java.io.IOException; import java.io.Serializable; import java.nio.file.Path; import java.security.ProtectionDomain; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -49,7 +48,7 @@ public class CuratedApplication implements Serializable, AutoCloseable { * * This should not be used for hot reloadable elements */ - private final Map augmentationElements = new HashMap<>(); + private final Map> augmentationElements = new HashMap<>(); /** * The augmentation class loader. @@ -172,19 +171,20 @@ public void accept(ClassPathElement classPathElement) { } }; } - ClassPathElement cpe = augmentationElements.get(artifact.getKey()); - if (cpe != null) { - consumer.accept(cpe); + List cpeList = augmentationElements.get(artifact.getKey()); + if (cpeList != null) { + for (ClassPathElement cpe : cpeList) { + consumer.accept(cpe); + } return; } - final PathTree contentTree = artifact.getContentTree(); - if (contentTree.isEmpty()) { - consumer.accept(ClassPathElement.EMPTY); - return; + cpeList = new ArrayList<>(2); + for (Path path : artifact.getResolvedPaths()) { + final ClassPathElement element = ClassPathElement.fromPath(path); + consumer.accept(element); + cpeList.add(element); } - cpe = ClassPathElement.fromDependency(artifact); - consumer.accept(cpe); - augmentationElements.put(artifact.getKey(), cpe); + augmentationElements.put(artifact.getKey(), cpeList); } private void addCpElement(QuarkusClassLoader.Builder builder, ResolvedDependency dep, ClassPathElement element) { @@ -223,7 +223,7 @@ public synchronized QuarkusClassLoader getAugmentClassLoader() { } for (Path i : quarkusBootstrap.getAdditionalDeploymentArchives()) { - builder.addElement(ClassPathElement.fromPath(i, false)); + builder.addElement(ClassPathElement.fromPath(i)); } Map banned = new HashMap<>(); for (List i : configuredClassLoading.removedResources.values()) { @@ -231,7 +231,7 @@ public synchronized QuarkusClassLoader getAugmentClassLoader() { banned.put(j, new byte[0]); } } - builder.addBannedElement(new MemoryClassPathElement(banned, false)); + builder.addBannedElement(new MemoryClassPathElement(banned)); augmentClassLoader = builder.build(); } return augmentClassLoader; @@ -254,18 +254,16 @@ public synchronized QuarkusClassLoader getBaseRuntimeClassLoader() { .setAssertionsEnabled(quarkusBootstrap.isAssertionsEnabled()); builder.addClassLoaderEventListeners(quarkusBootstrap.getClassLoaderEventListeners()); - final boolean flatTestClassPath = quarkusBootstrap.getMode() == QuarkusBootstrap.Mode.TEST - && quarkusBootstrap.isFlatClassPath(); - if (flatTestClassPath) { + if (quarkusBootstrap.getMode() == QuarkusBootstrap.Mode.TEST && quarkusBootstrap.isFlatClassPath()) { //in test mode we have everything in the base class loader //there is no need to restart so there is no need for an additional CL for (Path root : quarkusBootstrap.getApplicationRoot()) { - builder.addElement(ClassPathElement.fromPath(root, true)); + builder.addElement(ClassPathElement.fromPath(root)); } } else { for (Path root : quarkusBootstrap.getApplicationRoot()) { - builder.addBannedElement(new ClassFilteredBannedElement(ClassPathElement.fromPath(root, true))); + builder.addBannedElement(new ClassFilteredBannedElement(ClassPathElement.fromPath(root))); } } @@ -274,38 +272,31 @@ public synchronized QuarkusClassLoader getBaseRuntimeClassLoader() { for (AdditionalDependency i : quarkusBootstrap.getAdditionalApplicationArchives()) { if (!i.isHotReloadable()) { for (Path root : i.getResolvedPaths()) { - builder.addElement(ClassPathElement.fromPath(root, true)); + builder.addElement(ClassPathElement.fromPath(root)); } } else { for (Path root : i.getResolvedPaths()) { hotReloadPaths.add(root); - builder.addBannedElement(new ClassFilteredBannedElement(ClassPathElement.fromPath(root, true))); + builder.addBannedElement(new ClassFilteredBannedElement(ClassPathElement.fromPath(root))); } } } - builder.setResettableElement(new MemoryClassPathElement(Collections.emptyMap(), true)); + builder.setResettableElement(new MemoryClassPathElement(Collections.emptyMap())); Map banned = new HashMap<>(); for (List i : configuredClassLoading.removedResources.values()) { for (String j : i) { banned.put(j, new byte[0]); } } - builder.addBannedElement(new MemoryClassPathElement(banned, true)); + builder.addBannedElement(new MemoryClassPathElement(banned)); - for (ResolvedDependency dependency : appModel.getDependencies()) { - if (!dependency.isRuntimeCp() || - isHotReloadable(dependency, hotReloadPaths) || - configuredClassLoading.reloadableArtifacts.contains(dependency.getKey())) { + for (ResolvedDependency dependency : appModel.getRuntimeDependencies()) { + if (isHotReloadable(dependency, hotReloadPaths)) { continue; } - if (!flatTestClassPath && dependency.isReloadable() - && appModel.getReloadableWorkspaceDependencies().contains(dependency.getKey())) { - if (dependency.getType().equals(ArtifactCoords.TYPE_JAR)) { - builder.addBannedElement(new ClassFilteredBannedElement(ClassPathElement.fromDependency(dependency))); - } + if (configuredClassLoading.reloadableArtifacts.contains(dependency.getKey())) { continue; } - if (configuredClassLoading.removedArtifacts.contains(dependency.getKey())) { processCpElement(dependency, builder::addBannedElement); } else { @@ -319,7 +310,7 @@ public synchronized QuarkusClassLoader getBaseRuntimeClassLoader() { } private static boolean isHotReloadable(ResolvedDependency a, Set hotReloadPaths) { - for (Path p : a.getContentTree().getRoots()) { + for (Path p : a.getResolvedPaths()) { if (hotReloadPaths.contains(p)) { return true; } @@ -337,22 +328,19 @@ public QuarkusClassLoader createDeploymentClassLoader() { .setAggregateParentResources(true); for (Path root : quarkusBootstrap.getApplicationRoot()) { - builder.addElement(ClassPathElement.fromPath(root, true)); + builder.addElement(ClassPathElement.fromPath(root)); } - builder.setResettableElement(new MemoryClassPathElement(Collections.emptyMap(), false)); + builder.setResettableElement(new MemoryClassPathElement(Collections.emptyMap())); //additional user class path elements first for (AdditionalDependency i : quarkusBootstrap.getAdditionalApplicationArchives()) { for (Path root : i.getResolvedPaths()) { - builder.addElement(ClassPathElement.fromPath(root, true)); + builder.addElement(ClassPathElement.fromPath(root)); } } - for (ResolvedDependency dependency : appModel.getDependencies()) { - if (dependency.isRuntimeCp() && - dependency.getType().equals(ArtifactCoords.TYPE_JAR) && - (dependency.isReloadable() && appModel.getReloadableWorkspaceDependencies().contains(dependency.getKey()) || - configuredClassLoading.reloadableArtifacts.contains(dependency.getKey()))) { + for (ResolvedDependency dependency : appModel.getRuntimeDependencies()) { + if (configuredClassLoading.reloadableArtifacts.contains(dependency.getKey())) { processCpElement(dependency, element -> addCpElement(builder, dependency, element)); } } @@ -374,23 +362,20 @@ public QuarkusClassLoader createRuntimeClassLoader(ClassLoader base, Map addCpElement(builder, dependency, element)); } } @@ -431,21 +416,6 @@ static class ClassFilteredBannedElement implements ClassPathElement { this.delegate = delegate; } - @Override - public ArtifactKey getDependencyKey() { - return delegate.getDependencyKey(); - } - - @Override - public boolean isRuntime() { - return delegate.isRuntime(); - } - - @Override - public T withOpenTree(Function func) { - return delegate.withOpenTree(func); - } - @Override public Path getRoot() { return delegate.getRoot(); diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/QuarkusBootstrap.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/QuarkusBootstrap.java index 6a84ff753b861..c3113a8e06e20 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/QuarkusBootstrap.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/QuarkusBootstrap.java @@ -3,7 +3,9 @@ import io.quarkus.bootstrap.BootstrapAppModelFactory; import io.quarkus.bootstrap.BootstrapException; import io.quarkus.bootstrap.classloading.ClassLoaderEventListener; +import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.resolver.AppModelResolver; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; import io.quarkus.bootstrap.resolver.update.DependenciesOrigin; @@ -14,8 +16,6 @@ import io.quarkus.maven.dependency.Dependency; import io.quarkus.maven.dependency.GACT; import io.quarkus.maven.dependency.ResolvedDependency; -import io.quarkus.paths.PathCollection; -import io.quarkus.paths.PathList; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; @@ -43,7 +43,7 @@ public class QuarkusBootstrap implements Serializable { /** * The root of the application, where the application classes live. */ - private final PathCollection applicationRoot; + private final PathsCollection applicationRoot; /** * The root of the project. This may be different to the application root for tests that @@ -93,7 +93,7 @@ public class QuarkusBootstrap implements Serializable { private final boolean disableClasspathCache; private final ApplicationModel existingModel; private final boolean rebuild; - private final Set localArtifacts; + private final Set localArtifacts; private final List classLoadListeners; private final boolean auxiliaryApplication; private final boolean hostApplicationIsTestOnly; @@ -179,7 +179,7 @@ public CuratedApplication bootstrap() throws BootstrapException { return new CuratedApplication(this, appModelFactory.resolveAppModel(), classLoadingConfig); } - private static ConfiguredClassLoading createClassLoadingConfig(PathCollection applicationRoot, Mode mode) { + private static ConfiguredClassLoading createClassLoadingConfig(PathsCollection applicationRoot, Mode mode) { //look for an application.properties for (Path path : applicationRoot) { Path props = path.resolve("application.properties"); @@ -262,7 +262,7 @@ public AppModelResolver getAppModelResolver() { return appModelResolver; } - public PathCollection getApplicationRoot() { + public PathsCollection getApplicationRoot() { return applicationRoot; } @@ -304,7 +304,7 @@ public static Builder builder() { @Deprecated public static Builder builder(Path applicationRoot) { - return new Builder().setApplicationRoot(PathList.of(applicationRoot)); + return new Builder().setApplicationRoot(PathsCollection.of(applicationRoot)); } public String getBaseName() { @@ -385,7 +385,7 @@ public static class Builder { public boolean hostApplicationIsTestOnly; boolean flatClassPath; boolean rebuild; - PathCollection applicationRoot; + PathsCollection applicationRoot; String baseName; Path projectRoot; ClassLoader baseClassLoader = ClassLoader.getSystemClassLoader(); @@ -410,18 +410,18 @@ public static class Builder { List forcedDependencies = new ArrayList<>(); boolean disableClasspathCache; ApplicationModel existingModel; - final Set localArtifacts = new HashSet<>(); + final Set localArtifacts = new HashSet<>(); boolean auxiliaryApplication; public Builder() { } public Builder setApplicationRoot(Path applicationRoot) { - this.applicationRoot = PathList.of(applicationRoot); + this.applicationRoot = PathsCollection.of(applicationRoot); return this; } - public Builder setApplicationRoot(PathCollection applicationRoot) { + public Builder setApplicationRoot(PathsCollection applicationRoot) { if (appArtifact != null) { throw new IllegalStateException("Cannot set both app artifact and application root"); } @@ -546,7 +546,7 @@ public Builder setAppArtifact(ResolvedDependency appArtifact) { throw new IllegalStateException("Cannot set both application root and app artifact"); } this.appArtifact = appArtifact; - this.applicationRoot = PathList.from(appArtifact.getResolvedPaths()); + this.applicationRoot = PathsCollection.from(appArtifact.getResolvedPaths()); if (appArtifact.getResolvedPaths().isSinglePath()) { this.projectRoot = appArtifact.getResolvedPaths().getSinglePath(); } @@ -597,16 +597,11 @@ public Builder setExistingModel(ApplicationModel existingModel) { return this; } - public Builder addLocalArtifact(ArtifactKey key) { + public Builder addLocalArtifact(AppArtifactKey key) { localArtifacts.add(key); return this; } - public Builder clearLocalArtifacts() { - localArtifacts.clear(); - return this; - } - public Builder setRebuild(boolean value) { this.rebuild = value; return this; @@ -622,6 +617,7 @@ public Builder setAssertionsEnabled(boolean assertionsEnabled) { return this; } + @SuppressWarnings("AssertWithSideEffects") private boolean inheritedAssertionsEnabled() { boolean result = false; assert result = true; @@ -631,7 +627,8 @@ private boolean inheritedAssertionsEnabled() { public QuarkusBootstrap build() { Objects.requireNonNull(applicationRoot, "Application root must not be null"); if (appArtifact != null) { - localArtifacts.add(appArtifact.getKey()); + localArtifacts + .add(new AppArtifactKey(appArtifact.getGroupId(), appArtifact.getArtifactId())); } ConfiguredClassLoading classLoadingConfig = createClassLoadingConfig(applicationRoot, mode); diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/AbstractClassPathElement.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/AbstractClassPathElement.java index a8bf5e0ee7106..2982a5c26c4b4 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/AbstractClassPathElement.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/AbstractClassPathElement.java @@ -9,33 +9,28 @@ public abstract class AbstractClassPathElement implements ClassPathElement { private static final Logger log = Logger.getLogger(AbstractClassPathElement.class); - protected volatile Manifest manifest; - protected volatile boolean manifestInitialized = false; + private volatile Manifest manifest; + private volatile boolean initialized = false; @Override public Manifest getManifest() { - if (manifestInitialized) { + if (initialized) { return manifest; } synchronized (this) { - if (manifestInitialized) { + if (initialized) { return manifest; } - manifest = readManifest(); - manifestInitialized = true; - } - return manifest; - } - - protected Manifest readManifest() { - final ClassPathResource mf = getResource("META-INF/MANIFEST.MF"); - if (mf != null) { - try { - return new Manifest(new ByteArrayInputStream(mf.getData())); - } catch (IOException e) { - log.warnf("Failed to parse manifest for %s", toString(), e); + ClassPathResource mf = getResource("META-INF/MANIFEST.MF"); + if (mf != null) { + try { + manifest = new Manifest(new ByteArrayInputStream(mf.getData())); + } catch (IOException e) { + log.warnf("Failed to parse manifest for %s", toString()); + } } + initialized = true; + return manifest; } - return null; } } diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/ClassPathElement.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/ClassPathElement.java index 8018b08c48b52..8ce92e2f85006 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/ClassPathElement.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/ClassPathElement.java @@ -1,16 +1,11 @@ package io.quarkus.bootstrap.classloading; -import io.quarkus.maven.dependency.ArtifactKey; -import io.quarkus.maven.dependency.ResolvedDependency; -import io.quarkus.paths.EmptyPathTree; -import io.quarkus.paths.OpenPathTree; -import io.quarkus.paths.PathTree; import java.io.Closeable; +import java.nio.file.Files; import java.nio.file.Path; import java.security.ProtectionDomain; import java.util.Collections; import java.util.Set; -import java.util.function.Function; import java.util.jar.Manifest; /** @@ -19,32 +14,12 @@ */ public interface ClassPathElement extends Closeable { - /** - * If this classpath element represents a Maven artifact, the method will return its key, - * otherwise - null. - * - * @return the key of the Maven artifact this classpath element represents or null, in case - * this element does not represent any Maven artifact - */ - default ArtifactKey getDependencyKey() { - return null; - } - /** * * @return The element root, or null if not applicable */ Path getRoot(); - /** - * Processes the content of this classpath element and returns a result. - * - * @param result type - * @param func content processing function - * @return processing result - */ - T withOpenTree(Function func); - /** * Loads a resource from the class path element, or null if it does not exist. * @@ -68,23 +43,11 @@ default ArtifactKey getDependencyKey() { Manifest getManifest(); - /** - * Checks whether this is a runtime classpath element - * - * @return true in case this is a runtime classpath element, otherwise - false - */ - boolean isRuntime(); - /** * Creates an element from a file system path */ - static ClassPathElement fromPath(Path path, boolean runtime) { - return new PathTreeClassPathElement(PathTree.ofDirectoryOrArchive(path), - runtime); - } - - static ClassPathElement fromDependency(ResolvedDependency dep) { - return new PathTreeClassPathElement(dep.getContentTree(), dep.isRuntimeCp(), dep.getKey()); + static ClassPathElement fromPath(Path path) { + return Files.isDirectory(path) ? new DirectoryClassPathElement(path) : new JarClassPathElement(path); } static ClassPathElement EMPTY = new ClassPathElement() { @@ -93,16 +56,6 @@ public Path getRoot() { return null; } - @Override - public boolean isRuntime() { - return false; - } - - @Override - public T withOpenTree(Function func) { - return func.apply(EmptyPathTree.getInstance()); - } - @Override public ClassPathResource getResource(String name) { return null; diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/DirectoryClassPathElement.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/DirectoryClassPathElement.java index 0a3b4566a6471..c4c5d9eafd7ab 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/DirectoryClassPathElement.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/DirectoryClassPathElement.java @@ -1,7 +1,5 @@ package io.quarkus.bootstrap.classloading; -import io.quarkus.paths.DirectoryPathTree; -import io.quarkus.paths.OpenPathTree; import java.io.File; import java.io.IOException; import java.io.InterruptedIOException; @@ -18,33 +16,18 @@ import java.util.HashSet; import java.util.Set; import java.util.function.Consumer; -import java.util.function.Function; import java.util.stream.Stream; /** * A class path element that represents a file on the file system - * - * @deprecated in favor of {@link PathTreeClassPathElement} */ -@Deprecated public class DirectoryClassPathElement extends AbstractClassPathElement { private final Path root; - private final boolean runtime; - public DirectoryClassPathElement(Path root, boolean runtime) { + public DirectoryClassPathElement(Path root) { assert root != null : "root is null"; this.root = root.normalize(); - this.runtime = runtime; - } - - public T withOpenTree(Function func) { - return func.apply(new DirectoryPathTree(root)); - } - - @Override - public boolean isRuntime() { - return runtime; } @Override diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/FilteredClassPathElement.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/FilteredClassPathElement.java index 3ede15f2d5b32..73189520c89d2 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/FilteredClassPathElement.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/FilteredClassPathElement.java @@ -1,14 +1,11 @@ package io.quarkus.bootstrap.classloading; -import io.quarkus.maven.dependency.ArtifactKey; -import io.quarkus.paths.OpenPathTree; import java.io.IOException; import java.nio.file.Path; import java.security.ProtectionDomain; import java.util.Collection; import java.util.HashSet; import java.util.Set; -import java.util.function.Function; import java.util.jar.Manifest; public class FilteredClassPathElement implements ClassPathElement { @@ -21,21 +18,6 @@ public FilteredClassPathElement(ClassPathElement delegate, Collection re this.removed = new HashSet<>(removed); } - @Override - public ArtifactKey getDependencyKey() { - return delegate.getDependencyKey(); - } - - @Override - public boolean isRuntime() { - return delegate.isRuntime(); - } - - @Override - public T withOpenTree(Function func) { - return delegate.withOpenTree(func); - } - @Override public Path getRoot() { return delegate.getRoot(); diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/JarClassPathElement.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/JarClassPathElement.java index cbd9736632282..dd191c4c95232 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/JarClassPathElement.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/JarClassPathElement.java @@ -1,7 +1,5 @@ package io.quarkus.bootstrap.classloading; -import io.quarkus.paths.OpenPathTree; -import io.quarkus.paths.PathTree; import io.smallrye.common.io.jar.JarEntries; import io.smallrye.common.io.jar.JarFiles; import java.io.ByteArrayOutputStream; @@ -33,10 +31,7 @@ /** * A class path element that represents a file on the file system - * - * @deprecated in favor of {@link PathTreeClassPathElement} */ -@Deprecated public class JarClassPathElement implements ClassPathElement { public static final int JAVA_VERSION; @@ -68,13 +63,12 @@ public class JarClassPathElement implements ClassPathElement { private final Path root; private final Lock readLock; private final Lock writeLock; - private final boolean runtime; //Closing the jarFile requires the exclusive lock, while reading data from the jarFile requires the shared lock. private final JarFile jarFile; private volatile boolean closed; - public JarClassPathElement(Path root, boolean runtime) { + public JarClassPathElement(Path root) { try { jarPath = root.toUri().toURL(); this.root = root; @@ -85,21 +79,6 @@ public JarClassPathElement(Path root, boolean runtime) { } catch (IOException e) { throw new UncheckedIOException("Error while reading file as JAR: " + root, e); } - this.runtime = runtime; - } - - @Override - public boolean isRuntime() { - return runtime; - } - - @Override - public T withOpenTree(Function func) { - try (OpenPathTree openTree = PathTree.ofArchive(root).openTree()) { - return func.apply(openTree); - } catch (IOException e) { - throw new UncheckedIOException(e); - } } @Override diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/MemoryClassPathElement.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/MemoryClassPathElement.java index d4bf595561421..cc875a8cb9600 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/MemoryClassPathElement.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/MemoryClassPathElement.java @@ -1,7 +1,5 @@ package io.quarkus.bootstrap.classloading; -import io.quarkus.paths.EmptyPathTree; -import io.quarkus.paths.OpenPathTree; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @@ -16,22 +14,14 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; -import java.util.function.Function; public class MemoryClassPathElement extends AbstractClassPathElement { private volatile Map resources; private volatile long lastModified = System.currentTimeMillis(); - private final boolean runtime; - public MemoryClassPathElement(Map resources, boolean runtime) { + public MemoryClassPathElement(Map resources) { this.resources = resources; - this.runtime = runtime; - } - - @Override - public boolean isRuntime() { - return runtime; } public void reset(Map resources) { @@ -58,11 +48,6 @@ public Path getRoot() { return null; } - @Override - public T withOpenTree(Function func) { - return func.apply(EmptyPathTree.getInstance()); - } - @Override public ClassPathResource getResource(String name) { byte[] res = resources.get(name); diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/PathTreeClassPathElement.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/PathTreeClassPathElement.java deleted file mode 100644 index 8cbac3b7f2ccc..0000000000000 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/PathTreeClassPathElement.java +++ /dev/null @@ -1,279 +0,0 @@ -package io.quarkus.bootstrap.classloading; - -import io.quarkus.maven.dependency.ArtifactKey; -import io.quarkus.paths.OpenPathTree; -import io.quarkus.paths.PathTree; -import io.quarkus.paths.PathVisit; -import io.quarkus.paths.PathVisitor; -import java.io.IOException; -import java.io.InterruptedIOException; -import java.io.UncheckedIOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.CodeSource; -import java.security.ProtectionDomain; -import java.security.cert.Certificate; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.function.Function; -import java.util.jar.Manifest; - -public class PathTreeClassPathElement extends AbstractClassPathElement { - - static class ZipFileMayHaveChangedException extends RuntimeException { - public ZipFileMayHaveChangedException(Throwable cause) { - super(cause); - } - } - - static { - //force this class to be loaded - //if quarkus is recompiled it needs to have already - //been loaded - //this is just a convenience for quarkus devs that means exit - //should work properly if you recompile while quarkus is running - new ZipFileMayHaveChangedException(null); - } - - private final ReadWriteLock lock; - private final OpenPathTree pathTree; - private final boolean runtime; - private final ArtifactKey dependencyKey; - private volatile boolean closed; - private volatile Set resources; - - public PathTreeClassPathElement(PathTree pathTree, boolean runtime) { - this(pathTree, runtime, null); - } - - public PathTreeClassPathElement(PathTree pathTree, boolean runtime, ArtifactKey dependencyKey) { - this.pathTree = Objects.requireNonNull(pathTree, "Path tree is null").openTree(); - this.lock = new ReentrantReadWriteLock(); - this.runtime = runtime; - this.dependencyKey = dependencyKey; - } - - @Override - public boolean isRuntime() { - return runtime; - } - - @Override - public ArtifactKey getDependencyKey() { - return dependencyKey; - } - - @Override - public Path getRoot() { - return pathTree.getOriginalTree().getRoots().iterator().next(); - } - - /** - * Sometimes Vert.x may be looking for a resource like 'META-INF/resources//index.html'. - * This method will make sure there are no duplicate separators. - * - * @param path path to santize - * @return sanitized path - */ - private static String sanitize(String path) { - var i = path.indexOf("//"); - if (i < 0) { - return path; - } - final StringBuilder sb = new StringBuilder(path.length()); - sb.append(path, 0, ++i); - while (i < path.length()) { - final char c = path.charAt(i); - if (c == '/') { - ++i; - continue; - } - var j = path.indexOf("//", i + 1); - if (j < 0) { - sb.append(path, i, path.length()); - break; - } - sb.append(path, i, ++j); - i = j; - } - return sb.toString(); - } - - @Override - public ClassPathResource getResource(String name) { - final String sanitized = sanitize(name); - final Set resources = this.resources; - if (resources != null && !resources.contains(sanitized)) { - return null; - } - return withOpenTree( - tree -> tree.processPath(sanitized, visit -> visit == null ? null : new PathTreeClassPathResource(visit))); - } - - @Override - public T withOpenTree(Function func) { - lock.readLock().lock(); - try { - if (closed) { - //we still need this to work if it is closed, so shutdown hooks work - //once it is closed it simply does not hold on to any resources - try (OpenPathTree openTree = pathTree.getOriginalTree().openTree()) { - return func.apply(openTree); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } else { - return func.apply(pathTree); - } - } finally { - lock.readLock().unlock(); - } - } - - @Override - public Set getProvidedResources() { - Set resources = this.resources; - if (resources == null) { - resources = withOpenTree(tree -> { - final Set relativePaths = new HashSet<>(); - tree.walk(new PathVisitor() { - @Override - public void visitPath(PathVisit visit) { - final String relativePath = visit.getRelativePath("/"); - if (relativePath.isEmpty()) { - return; - } - relativePaths.add(relativePath); - } - }); - return relativePaths; - }); - this.resources = resources; - } - return resources; - } - - @Override - protected Manifest readManifest() { - return withOpenTree(OpenPathTree::getManifest); - } - - @Override - public ProtectionDomain getProtectionDomain(ClassLoader classLoader) { - URL url = null; - final Path root = getRoot(); - try { - url = root.toUri().toURL(); - } catch (MalformedURLException e) { - throw new RuntimeException("Unable to create protection domain for " + root, e); - } - CodeSource codesource = new CodeSource(url, (Certificate[]) null); - ProtectionDomain protectionDomain = new ProtectionDomain(codesource, null, classLoader, null); - return protectionDomain; - } - - @Override - public void close() throws IOException { - lock.writeLock().lock(); - resources = null; - try { - pathTree.close(); - closed = true; - } finally { - lock.writeLock().unlock(); - } - } - - private class PathTreeClassPathResource implements ClassPathResource { - - private final String name; - private final Path path; - private volatile URL url; - - private PathTreeClassPathResource(PathVisit visit) { - name = visit.getRelativePath("/"); - path = visit.getPath(); - } - - @Override - public ClassPathElement getContainingElement() { - return PathTreeClassPathElement.this; - } - - @Override - public String getPath() { - return name; - } - - @Override - public URL getUrl() { - if (url != null) { - return url; - } - lock.readLock().lock(); - try { - if (closed) { - return url = withOpenTree( - tree -> tree.processPath(name, visit -> visit == null ? null : visit.getUrl())); - } - return url = path.toUri().toURL(); - } catch (MalformedURLException e) { - throw new RuntimeException("Failed to translate " + path + " to URL", e); - } finally { - lock.readLock().unlock(); - } - } - - @Override - public byte[] getData() { - lock.readLock().lock(); - try { - if (closed) { - return withOpenTree( - tree -> tree.processPath(name, visit -> visit == null ? null : readPath(visit.getPath()))); - } - return readPath(path); - } finally { - lock.readLock().unlock(); - } - } - - @Override - public boolean isDirectory() { - lock.readLock().lock(); - try { - if (closed) { - return withOpenTree(tree -> tree.processPath(name, - visit -> visit == null ? null : Files.isDirectory(visit.getPath()))); - } - return Files.isDirectory(path); - } finally { - lock.readLock().unlock(); - } - } - - private byte[] readPath(Path path) { - try { - try { - return Files.readAllBytes(path); - } catch (InterruptedIOException e) { - // if we are interrupted reading data we finish the op, then just - // re-interrupt the thread state - final byte[] bytes = Files.readAllBytes(path); - Thread.currentThread().interrupt(); - return bytes; - } - } catch (IOException e) { - if (!closed) { - throw new ZipFileMayHaveChangedException(e); - } - throw new RuntimeException("Unable to read " + path.toUri(), e); - } - } - } -} diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java index 55961a70b3f70..9a118eba79a4c 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java @@ -38,15 +38,6 @@ public class QuarkusClassLoader extends ClassLoader implements Closeable { registerAsParallelCapable(); } - public static List getElements(String resourceName, boolean localOnly) { - final ClassLoader ccl = Thread.currentThread().getContextClassLoader(); - if (!(ccl instanceof QuarkusClassLoader)) { - throw new IllegalStateException("The current classloader is not an instance of " - + QuarkusClassLoader.class.getName() + " but " + ccl.getClass().getName()); - } - return ((QuarkusClassLoader) ccl).getElementsWithResource(resourceName, localOnly); - } - private final String name; private final List elements; private final ConcurrentMap protectionDomains = new ConcurrentHashMap<>(); @@ -104,7 +95,7 @@ private QuarkusClassLoader(Builder builder) { this.parent = builder.parent; this.parentFirst = builder.parentFirst; this.resettableElement = builder.resettableElement; - this.transformedClasses = new MemoryClassPathElement(builder.transformedClasses, true); + this.transformedClasses = new MemoryClassPathElement(builder.transformedClasses); this.aggregateParentResources = builder.aggregateParentResources; this.classLoaderEventListeners = builder.classLoaderEventListeners.isEmpty() ? Collections.emptyList() : builder.classLoaderEventListeners; @@ -160,7 +151,7 @@ public void reset(Map generatedResources, Map tr throw new IllegalStateException("Classloader is not resettable"); } synchronized (this) { - this.transformedClasses = new MemoryClassPathElement(transformedClasses, true); + this.transformedClasses = new MemoryClassPathElement(transformedClasses); resettableElement.reset(generatedResources); state = null; } @@ -538,6 +529,7 @@ public List getLocalClassNames() { return ret; } + @SuppressWarnings("unused") public Class visibleDefineClass(String name, byte[] b, int off, int len) throws ClassFormatError { return super.defineClass(name, b, off, len); } diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/devmode/DependenciesFilter.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/devmode/DependenciesFilter.java index 388c6db0fda70..c96b13143616a 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/devmode/DependenciesFilter.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/devmode/DependenciesFilter.java @@ -1,8 +1,7 @@ package io.quarkus.bootstrap.devmode; import io.quarkus.bootstrap.model.ApplicationModel; -import io.quarkus.maven.dependency.GACTV; -import io.quarkus.maven.dependency.ResolvedDependency; +import io.quarkus.bootstrap.workspace.WorkspaceModule; import java.util.ArrayList; import java.util.List; import org.jboss.logging.Logger; @@ -11,29 +10,22 @@ public class DependenciesFilter { private static final Logger log = Logger.getLogger(DependenciesFilter.class); - public static List getReloadableModules(ApplicationModel appModel) { - final List reloadable = new ArrayList<>(); + public static List getReloadableModules(ApplicationModel appModel) { + final List reloadable = new ArrayList<>(); if (appModel.getApplicationModule() != null) { - reloadable.add(appModel.getAppArtifact()); + reloadable.add(appModel.getApplicationModule()); } appModel.getDependencies().forEach(d -> { - if (d.isReloadable()) { - reloadable.add(d); - } else if (d.isWorkspaceModule()) { - //if this project also contains Quarkus extensions we do no want to include these in the discovery - //a bit of an edge case, but if you try and include a sample project with your extension you will - //run into problems without this - final StringBuilder msg = new StringBuilder(); - msg.append("Local Quarkus extension dependency "); - msg.append(d.getGroupId()).append(":").append(d.getArtifactId()).append(":"); - if (!d.getClassifier().isEmpty()) { - msg.append(d.getClassifier()).append(":"); + final WorkspaceModule module = d.getWorkspaceModule(); + if (module != null) { + if (d.isReloadable()) { + reloadable.add(module); + } else { + //if this project also contains Quarkus extensions we do no want to include these in the discovery + //a bit of an edge case, but if you try and include a sample project with your extension you will + //run into problems without this + log.warn("Local Quarkus extension dependency " + module.getId() + " will not be hot-reloadable"); } - if (!GACTV.TYPE_JAR.equals(d.getType())) { - msg.append(d.getType()).append(":"); - } - msg.append(d.getVersion()).append(" will not be hot-reloadable"); - log.warn(msg.toString()); } }); return reloadable; diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/classloader/ClassLoadingInterruptTestCase.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/classloader/ClassLoadingInterruptTestCase.java index f5414309f2240..6b27afb523a52 100644 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/classloader/ClassLoadingInterruptTestCase.java +++ b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/classloader/ClassLoadingInterruptTestCase.java @@ -22,7 +22,7 @@ public void testClassLoaderWhenThreadInterrupted() throws Exception { jar.as(ExplodedExporter.class).exportExploded(path.toFile(), "tmp"); ClassLoader cl = QuarkusClassLoader.builder("test", getClass().getClassLoader(), false) - .addElement(new DirectoryClassPathElement(path.resolve("tmp"), true)) + .addElement(new DirectoryClassPathElement(path.resolve("tmp"))) .build(); Class c = cl.loadClass(InterruptClass.class.getName()); Assertions.assertNotEquals(c, InterruptClass.class); diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/classloader/ClassLoadingResourceUrlTestCase.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/classloader/ClassLoadingResourceUrlTestCase.java index 6eba0bca06557..b496f0d6c7f45 100644 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/classloader/ClassLoadingResourceUrlTestCase.java +++ b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/classloader/ClassLoadingResourceUrlTestCase.java @@ -36,7 +36,7 @@ public void testUrlReturnedFromClassLoaderDirectory() throws Exception { jar.as(ExplodedExporter.class).exportExploded(path.toFile(), "tmp"); ClassLoader cl = QuarkusClassLoader.builder("test", getClass().getClassLoader(), false) - .addElement(new DirectoryClassPathElement(path.resolve("tmp"), true)) + .addElement(new DirectoryClassPathElement(path.resolve("tmp"))) .build(); URL res = cl.getResource("a.txt"); Assertions.assertNotNull(res); @@ -72,7 +72,7 @@ public void testResourceAsStreamForDirectory() throws Exception { try { jar.as(ExplodedExporter.class).exportExploded(tmpDir.toFile(), "tmpcltest"); final ClassLoader cl = QuarkusClassLoader.builder("test", getClass().getClassLoader(), false) - .addElement(new DirectoryClassPathElement(tmpDir.resolve("tmpcltest"), true)) + .addElement(new DirectoryClassPathElement(tmpDir.resolve("tmpcltest"))) .build(); try (final InputStream is = cl.getResourceAsStream("b/")) { @@ -99,7 +99,7 @@ public void testUrlReturnedFromClassLoaderJarFile() throws Exception { jar.as(ZipExporter.class).exportTo(path.toFile(), true); ClassLoader cl = QuarkusClassLoader.builder("test", getClass().getClassLoader(), false) - .addElement(new JarClassPathElement(path, true)) + .addElement(new JarClassPathElement(path)) .build(); URL res = cl.getResource("a.txt"); Assertions.assertNotNull(res); @@ -126,8 +126,7 @@ public void testMemoryUrlConnections() throws Exception { ClassLoader cl = QuarkusClassLoader.builder("test", getClass().getClassLoader(), false) .addElement( - new MemoryClassPathElement(Collections.singletonMap("a.txt", "hello".getBytes(StandardCharsets.UTF_8)), - true)) + new MemoryClassPathElement(Collections.singletonMap("a.txt", "hello".getBytes(StandardCharsets.UTF_8)))) .build(); URL res = cl.getResource("a.txt"); Assertions.assertNotNull(res); diff --git a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/classloader/MultiReleaseJarTestCase.java b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/classloader/MultiReleaseJarTestCase.java index e83045c75dccc..31ae2151e12a8 100644 --- a/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/classloader/MultiReleaseJarTestCase.java +++ b/independent-projects/bootstrap/core/src/test/java/io/quarkus/bootstrap/classloader/MultiReleaseJarTestCase.java @@ -55,7 +55,7 @@ void setUp(@TempDir Path tempDirectory) throws IOException { @DisabledOnJre(JRE.JAVA_8) public void shouldLoadMultiReleaseJarOnJDK9Plus() throws IOException { try (QuarkusClassLoader cl = QuarkusClassLoader.builder("test", getClass().getClassLoader(), false) - .addElement(new JarClassPathElement(jarPath, true)) + .addElement(new JarClassPathElement(jarPath)) .build()) { URL resource = cl.getResource("foo.txt"); assertNotNull(resource, "foo.txt was not found in generated JAR"); @@ -72,7 +72,7 @@ public void shouldLoadMultiReleaseJarOnJDK9Plus() throws IOException { @EnabledOnJre(JRE.JAVA_8) public void shouldLoadMultiReleaseJarOnJDK8() throws IOException { try (QuarkusClassLoader cl = QuarkusClassLoader.builder("test", getClass().getClassLoader(), false) - .addElement(new JarClassPathElement(jarPath, true)) + .addElement(new JarClassPathElement(jarPath)) .build()) { URL resource = cl.getResource("foo.txt"); assertNotNull(resource, "foo.txt was not found in generated JAR"); diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/BootstrapAppModelResolver.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/BootstrapAppModelResolver.java index a12e38f0e36ee..b573358a34c76 100644 --- a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/BootstrapAppModelResolver.java +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/BootstrapAppModelResolver.java @@ -8,19 +8,23 @@ import io.quarkus.bootstrap.resolver.maven.BootstrapMavenException; import io.quarkus.bootstrap.resolver.maven.BuildDependencyGraphVisitor; import io.quarkus.bootstrap.resolver.maven.DeploymentInjectingDependencyVisitor; +import io.quarkus.bootstrap.resolver.maven.DeploymentInjectionException; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; import io.quarkus.bootstrap.resolver.maven.SimpleDependencyGraphTransformationContext; -import io.quarkus.bootstrap.workspace.ArtifactSources; -import io.quarkus.bootstrap.workspace.SourceDir; +import io.quarkus.bootstrap.workspace.ProcessedSources; import io.quarkus.bootstrap.workspace.WorkspaceModule; +import io.quarkus.fs.util.ZipUtils; import io.quarkus.maven.dependency.ArtifactCoords; import io.quarkus.maven.dependency.ArtifactKey; import io.quarkus.maven.dependency.DependencyFlags; +import io.quarkus.maven.dependency.GACT; import io.quarkus.maven.dependency.ResolvableDependency; import io.quarkus.maven.dependency.ResolvedDependency; import io.quarkus.maven.dependency.ResolvedDependencyBuilder; import io.quarkus.paths.PathCollection; import io.quarkus.paths.PathList; +import java.io.IOException; +import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -192,9 +196,11 @@ private ApplicationModel doResolveModel(ArtifactCoords coords, } final ResolvedDependency appArtifact = resolve(coords, mvnArtifact, managedRepos); + final boolean preferWorkspacePaths = !containsExtensionMetadata(appArtifact) && (devmode || test); + final ApplicationModelBuilder appBuilder = new ApplicationModelBuilder().setAppArtifact(appArtifact); if (appArtifact.getWorkspaceModule() != null) { - appBuilder.addReloadableWorkspaceModule(appArtifact.getKey()); + appBuilder.addReloadableWorkspaceModule(new GACT(appArtifact.getGroupId(), appArtifact.getArtifactId())); } if (!reloadableModules.isEmpty()) { appBuilder.addReloadableWorkspaceModules(reloadableModules); @@ -228,6 +234,7 @@ private ApplicationModel doResolveModel(ArtifactCoords coords, final DeploymentInjectingDependencyVisitor deploymentInjector; try { deploymentInjector = new DeploymentInjectingDependencyVisitor(mvn, managedDeps, repos, appBuilder, + preferWorkspacePaths, collectReloadableDeps && reloadableModules.isEmpty()); deploymentInjector.injectDeploymentDependencies(resolvedDeps); } catch (BootstrapDependencyProcessingException e) { @@ -276,7 +283,7 @@ private ApplicationModel doResolveModel(ArtifactCoords coords, } } appBuilder.addDependency( - toAppArtifact(dep.getArtifact(), module) + toAppArtifact(dep.getArtifact(), module, false) .setScope(dep.getDependency().getScope()) .setFlags(flags).build()); } @@ -288,6 +295,36 @@ private ApplicationModel doResolveModel(ArtifactCoords coords, return appBuilder.build(); } + private static boolean containsExtensionMetadata(ResolvedDependency dep) { + if (!ArtifactCoords.TYPE_JAR.equals(dep.getType())) { + return false; + } + for (Path path : dep.getResolvedPaths()) { + if (!Files.exists(path)) { + continue; + } + if (Files.isDirectory(path)) { + if (containsExtensionMetadata(path)) { + return true; + } + } else { + try (FileSystem artifactFs = ZipUtils.newFileSystem(path)) { + if (containsExtensionMetadata(artifactFs.getPath(""))) { + return true; + } + } catch (IOException e) { + throw new DeploymentInjectionException("Failed to read " + path, e); + } + } + } + return false; + } + + private static boolean containsExtensionMetadata(final Path path) { + return Files.exists(path.resolve(BootstrapConstants.BUILD_STEPS_PATH)) + || Files.exists(path.resolve(BootstrapConstants.DESCRIPTOR_PATH)); + } + private io.quarkus.maven.dependency.ResolvedDependency resolve(ArtifactCoords appArtifact, Artifact mvnArtifact, List managedRepos) throws BootstrapMavenException { @@ -307,15 +344,26 @@ private io.quarkus.maven.dependency.ResolvedDependency resolve(ArtifactCoords ap PathCollection resolvedPaths = null; if ((devmode || test) && resolvedModule != null) { - final ArtifactSources artifactSources = resolvedModule.getSources(appArtifact.getClassifier()); - if (artifactSources != null) { - final PathList.Builder pathBuilder = PathList.builder(); - collectSourceDirs(pathBuilder, artifactSources.getSourceDirs()); - collectSourceDirs(pathBuilder, artifactSources.getResourceDirs()); - if (!pathBuilder.isEmpty()) { - resolvedPaths = pathBuilder.build(); + final PathList.Builder pathBuilder = PathList.builder(); + for (ProcessedSources src : resolvedModule.getMainSources()) { + if (src.getDestinationDir().exists()) { + final Path p = src.getDestinationDir().toPath(); + if (!pathBuilder.contains(p)) { + pathBuilder.add(p); + } + } + } + for (ProcessedSources src : resolvedModule.getMainResources()) { + if (src.getDestinationDir().exists()) { + final Path p = src.getDestinationDir().toPath(); + if (!pathBuilder.contains(p)) { + pathBuilder.add(p); + } } } + if (!pathBuilder.isEmpty()) { + resolvedPaths = pathBuilder.build(); + } } if (resolvedPaths == null) { if (resolvedArtifact == null || resolvedArtifact.getResolvedPaths() == null) { @@ -328,17 +376,6 @@ private io.quarkus.maven.dependency.ResolvedDependency resolve(ArtifactCoords ap .setResolvedPaths(resolvedPaths).build(); } - private static void collectSourceDirs(final PathList.Builder pathBuilder, Collection resources) { - for (SourceDir src : resources) { - if (Files.exists(src.getOutputDir())) { - final Path p = src.getOutputDir(); - if (!pathBuilder.contains(p)) { - pathBuilder.add(p); - } - } - } - } - private void collectPlatformProperties(ApplicationModelBuilder appBuilder, List managedDeps) throws AppModelResolverException { final PlatformImportsImpl platformReleases = new PlatformImportsImpl(); @@ -467,11 +504,11 @@ private static Artifact toAetherArtifact(ArtifactCoords artifact) { } private ResolvedDependencyBuilder toAppArtifact(Artifact artifact) { - return toAppArtifact(artifact, null); + return toAppArtifact(artifact, null, false); } - private ResolvedDependencyBuilder toAppArtifact(Artifact artifact, WorkspaceModule module) { - return DeploymentInjectingDependencyVisitor.toAppArtifact(artifact, module); + private ResolvedDependencyBuilder toAppArtifact(Artifact artifact, WorkspaceModule module, boolean preferWorkspacePaths) { + return DeploymentInjectingDependencyVisitor.toAppArtifact(artifact, module, preferWorkspacePaths); } private static List toAetherDeps(Collection directDeps) { diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/DeploymentInjectingDependencyVisitor.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/DeploymentInjectingDependencyVisitor.java index 011d401834bc0..909dcb2e824f9 100644 --- a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/DeploymentInjectingDependencyVisitor.java +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/DeploymentInjectingDependencyVisitor.java @@ -7,6 +7,7 @@ import io.quarkus.bootstrap.resolver.AppModelResolverException; import io.quarkus.bootstrap.util.BootstrapUtils; import io.quarkus.bootstrap.util.DependencyNodeUtils; +import io.quarkus.bootstrap.workspace.ProcessedSources; import io.quarkus.bootstrap.workspace.WorkspaceModule; import io.quarkus.fs.util.ZipUtils; import io.quarkus.maven.dependency.ArtifactDependency; @@ -14,6 +15,7 @@ import io.quarkus.maven.dependency.DependencyFlags; import io.quarkus.maven.dependency.GACT; import io.quarkus.maven.dependency.ResolvedDependencyBuilder; +import io.quarkus.paths.PathCollection; import io.quarkus.paths.PathList; import java.io.BufferedReader; import java.io.IOException; @@ -66,6 +68,7 @@ public static Artifact getRuntimeArtifact(DependencyNode dep) { private final List managedDeps; private final List mainRepos; private final ApplicationModelBuilder appBuilder; + private final boolean preferWorkspacePaths; private final boolean collectReloadableModules; private boolean collectingTopExtensionRuntimeNodes = true; @@ -79,9 +82,10 @@ public static Artifact getRuntimeArtifact(DependencyNode dep) { public final Set allRuntimeDeps = new HashSet<>(); public DeploymentInjectingDependencyVisitor(MavenArtifactResolver resolver, List managedDeps, - List mainRepos, ApplicationModelBuilder appBuilder, + List mainRepos, ApplicationModelBuilder appBuilder, boolean preferWorkspacePaths, boolean collectReloadableModules) throws BootstrapDependencyProcessingException { + this.preferWorkspacePaths = preferWorkspacePaths; this.collectReloadableModules = collectReloadableModules; // we need to be able to take into account whether the deployment dependencies are on an optional dependency branch // for that we are going to use a custom dependency selector and re-initialize the resolver to use it @@ -193,17 +197,17 @@ private void visitRuntimeDependency(DependencyNode node) { module = resolver.getProjectModuleResolver().getProjectModule(artifact.getGroupId(), artifact.getArtifactId()); } - final ResolvedDependencyBuilder newRtDep = toAppArtifact(artifact, module) - .setRuntimeCp() - .setDeploymentCp() - .setOptional(node.getDependency().isOptional()) - .setScope(node.getDependency().getScope()) - .setDirect(collectingDirectDeps); + final ResolvedDependencyBuilder newRtDep = toAppArtifact(artifact, module, + preferWorkspacePaths && extDep == null && collectingTopExtensionRuntimeNodes) + .setRuntimeCp() + .setDeploymentCp() + .setOptional(node.getDependency().isOptional()) + .setScope(node.getDependency().getScope()) + .setDirect(collectingDirectDeps); if (module != null) { newRtDep.setWorkspaceModule().setReloadable(); if (collectReloadableModules) { - appBuilder.addReloadableWorkspaceModule(new GACT(artifact.getGroupId(), artifact.getArtifactId(), - artifact.getClassifier(), artifact.getExtension())); + appBuilder.addReloadableWorkspaceModule(new GACT(artifact.getGroupId(), artifact.getArtifactId())); } } if (extDep != null) { @@ -366,7 +370,7 @@ private void clearReloadable(DependencyNode node) { clearReloadable(child); } final io.quarkus.maven.dependency.Dependency dep = appBuilder.getDependency(getKey(node.getArtifact())); - if (dep != null && dep.isWorkspaceModule()) { + if (dep != null && dep.isWorkspacetModule()) { ((ArtifactDependency) dep).clearFlag(DependencyFlags.RELOADABLE); } } @@ -628,7 +632,8 @@ public static GACT getKey(Artifact a) { return new GACT(a.getGroupId(), a.getArtifactId(), a.getClassifier(), a.getExtension()); } - public static ResolvedDependencyBuilder toAppArtifact(Artifact artifact, WorkspaceModule module) { + public static ResolvedDependencyBuilder toAppArtifact(Artifact artifact, WorkspaceModule module, + boolean preferWorkspacePaths) { return ResolvedDependencyBuilder.newInstance() .setWorkspaceModule(module) .setGroupId(artifact.getGroupId()) @@ -636,7 +641,35 @@ public static ResolvedDependencyBuilder toAppArtifact(Artifact artifact, Workspa .setClassifier(artifact.getClassifier()) .setType(artifact.getExtension()) .setVersion(artifact.getVersion()) - .setResolvedPaths(artifact.getFile() == null ? PathList.empty() : PathList.of(artifact.getFile().toPath())); + .setResolvedPaths(getResolvedPaths(artifact, module, preferWorkspacePaths)); + } + + public static PathCollection getResolvedPaths(Artifact artifact, WorkspaceModule module, boolean preferWorkspacePaths) { + if (preferWorkspacePaths && module != null) { + final PathList.Builder pathBuilder = PathList.builder(); + if ("tests".equals(artifact.getClassifier())) { + collectResolvedPaths(pathBuilder, module.getTestSources()); + collectResolvedPaths(pathBuilder, module.getTestResources()); + } else { + collectResolvedPaths(pathBuilder, module.getMainSources()); + collectResolvedPaths(pathBuilder, module.getMainResources()); + } + if (!pathBuilder.isEmpty()) { + return pathBuilder.build(); + } + } + return artifact.getFile() == null ? PathList.empty() : PathList.of(artifact.getFile().toPath()); + } + + private static void collectResolvedPaths(final PathList.Builder pathBuilder, Collection srcs) { + for (ProcessedSources src : srcs) { + if (src.getDestinationDir().exists()) { + final Path p = src.getDestinationDir().toPath(); + if (!pathBuilder.contains(p)) { + pathBuilder.add(p); + } + } + } } private static String toGactv(Artifact a) { diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalProject.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalProject.java index ab394ecba39cd..18030bb14e296 100644 --- a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalProject.java +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalProject.java @@ -2,25 +2,19 @@ import io.quarkus.bootstrap.model.AppArtifact; import io.quarkus.bootstrap.model.AppArtifactKey; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenContext; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenException; -import io.quarkus.bootstrap.workspace.DefaultArtifactSources; -import io.quarkus.bootstrap.workspace.DefaultSourceDir; +import io.quarkus.bootstrap.workspace.DefaultProcessedSources; import io.quarkus.bootstrap.workspace.DefaultWorkspaceModule; -import io.quarkus.bootstrap.workspace.SourceDir; import io.quarkus.bootstrap.workspace.WorkspaceModule; -import io.quarkus.maven.dependency.ArtifactCoords; import io.quarkus.maven.dependency.GAV; -import io.quarkus.paths.DirectoryPathTree; -import io.quarkus.paths.PathCollection; -import io.quarkus.paths.PathFilter; import io.quarkus.paths.PathList; import java.io.IOException; import java.nio.file.Files; 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; @@ -29,11 +23,8 @@ import org.apache.maven.model.Build; import org.apache.maven.model.Model; import org.apache.maven.model.Parent; -import org.apache.maven.model.Plugin; -import org.apache.maven.model.PluginExecution; import org.apache.maven.model.Resource; import org.apache.maven.model.building.ModelBuildingResult; -import org.codehaus.plexus.util.xml.Xpp3Dom; /** * @@ -137,7 +128,6 @@ static Path locateCurrentProjectPom(Path path, boolean required) throws Bootstra final List modules = new ArrayList<>(0); private AppArtifactKey key; private final ModelBuildingResult modelBuildingResult; - private WorkspaceModule module; LocalProject(ModelBuildingResult modelBuildingResult, LocalWorkspace workspace) { this.rawModel = modelBuildingResult.getRawModel(); @@ -247,25 +237,25 @@ public Path getSourcesDir() { return getSourcesSourcesDir().getParent(); } - public PathCollection getResourcesSourcesDirs() { + public PathsCollection getResourcesSourcesDirs() { final List resources = rawModel.getBuild() == null ? Collections.emptyList() : rawModel.getBuild().getResources(); if (resources.isEmpty()) { - return PathList.of(resolveRelativeToBaseDir(null, "src/main/resources")); + return PathsCollection.of(resolveRelativeToBaseDir(null, "src/main/resources")); } - return PathList.from(resources.stream() + return PathsCollection.from(resources.stream() .map(Resource::getDirectory) .map(resourcesDir -> resolveRelativeToBaseDir(resourcesDir, "src/main/resources")) .collect(Collectors.toCollection(LinkedHashSet::new))); } - public PathCollection getTestResourcesSourcesDirs() { + public PathsCollection getTestResourcesSourcesDirs() { final List resources = rawModel.getBuild() == null ? Collections.emptyList() : rawModel.getBuild().getTestResources(); if (resources.isEmpty()) { - return PathList.of(resolveRelativeToBaseDir(null, "src/test/resources")); + return PathsCollection.of(resolveRelativeToBaseDir(null, "src/test/resources")); } - return PathList.from(resources.stream() + return PathsCollection.from(resources.stream() .map(Resource::getDirectory) .map(resourcesDir -> resolveRelativeToBaseDir(resourcesDir, "src/test/resources")) .collect(Collectors.toCollection(LinkedHashSet::new))); @@ -327,127 +317,49 @@ private static String configuredBuildDir(LocalProject project, Function includes = collectChildValues(dom.getChild("includes")); - final List excludes = collectChildValues(dom.getChild("excludes")); - if (includes == null && excludes == null) { - return null; - } - final PathFilter filter = new PathFilter(includes, excludes); - final String classifier = getClassifier(dom, test); - final Collection sources = Collections.singletonList( - new DefaultSourceDir(new DirectoryPathTree(test ? getTestSourcesSourcesDir() : getSourcesSourcesDir()), - new DirectoryPathTree(test ? getTestClassesDir() : getClassesDir(), filter), - Collections.emptyMap())); - final Collection resources = test ? collectTestResources(filter) : collectMainResources(filter); - return new DefaultArtifactSources(classifier, sources, resources); - } - - private List collectChildValues(final Xpp3Dom container) { - if (container == null) { - return null; - } - final Xpp3Dom[] excludeElements = container.getChildren(); - final List list = new ArrayList<>(excludeElements.length); - for (Xpp3Dom child : container.getChildren()) { - list.add(child.getValue()); - } - return list; - } - - private static String getClassifier(Xpp3Dom dom, boolean test) { - final Xpp3Dom classifier = dom.getChild("classifier"); - return classifier == null ? (test ? DefaultWorkspaceModule.TEST : DefaultWorkspaceModule.MAIN) : classifier.getValue(); - } - - private Collection collectMainResources(PathFilter filter) { + private void addMainResources(DefaultWorkspaceModule module) { final List resources = rawModel.getBuild() == null ? Collections.emptyList() : rawModel.getBuild().getResources(); if (resources.isEmpty()) { - return Collections.singletonList(new DefaultSourceDir( - new DirectoryPathTree(resolveRelativeToBaseDir(null, "src/main/resources")), - new DirectoryPathTree(getClassesDir(), filter), Collections.emptyMap())); - } - final List sourceDirs = new ArrayList<>(resources.size()); - for (Resource r : resources) { - sourceDirs.add( - new DefaultSourceDir( - new DirectoryPathTree(resolveRelativeToBaseDir(r.getDirectory(), "src/main/resources")), - new DirectoryPathTree((r.getTargetPath() == null ? getClassesDir() - : getClassesDir() - .resolve(stripProjectBasedirPrefix(r.getTargetPath(), PROJECT_OUTPUT_DIR))), - filter), - Collections.emptyMap())); + module.addMainResources(new DefaultProcessedSources( + resolveRelativeToBaseDir(null, "src/main/resources").toFile(), getClassesDir().toFile())); + } else { + for (Resource r : resources) { + module.addMainResources( + new DefaultProcessedSources(resolveRelativeToBaseDir(r.getDirectory(), "src/main/resources").toFile(), + (r.getTargetPath() == null ? getClassesDir() + : getClassesDir() + .resolve(stripProjectBasedirPrefix(r.getTargetPath(), PROJECT_OUTPUT_DIR))) + .toFile())); + } } - return sourceDirs; } - private Collection collectTestResources(PathFilter filter) { + private void addTestResources(DefaultWorkspaceModule module) { final List resources = rawModel.getBuild() == null ? Collections.emptyList() : rawModel.getBuild().getTestResources(); if (resources.isEmpty()) { - return Collections.singletonList(new DefaultSourceDir( - new DirectoryPathTree(resolveRelativeToBaseDir(null, "src/test/resources")), - new DirectoryPathTree(getTestClassesDir(), filter), Collections.emptyMap())); - } - final List sourceDirs = new ArrayList<>(resources.size()); - for (Resource r : resources) { - sourceDirs.add( - new DefaultSourceDir( - new DirectoryPathTree(resolveRelativeToBaseDir(r.getDirectory(), "src/test/resources")), - new DirectoryPathTree((r.getTargetPath() == null ? getTestClassesDir() - : getTestClassesDir() - .resolve(stripProjectBasedirPrefix(r.getTargetPath(), PROJECT_OUTPUT_DIR))), - filter), - Collections.emptyMap())); + module.addTestResources(new DefaultProcessedSources( + resolveRelativeToBaseDir(null, "src/test/resources").toFile(), getTestClassesDir().toFile())); + } else { + for (Resource r : resources) { + module.addTestResources( + new DefaultProcessedSources(resolveRelativeToBaseDir(r.getDirectory(), "src/test/resources").toFile(), + (r.getTargetPath() == null ? getTestClassesDir() + : getTestClassesDir() + .resolve(stripProjectBasedirPrefix(r.getTargetPath(), PROJECT_OUTPUT_DIR))) + .toFile())); + } } - return sourceDirs; } } diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalWorkspace.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalWorkspace.java index 937e1adfc08f1..0e23ded7abfc1 100644 --- a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalWorkspace.java +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/workspace/LocalWorkspace.java @@ -1,10 +1,10 @@ package io.quarkus.bootstrap.resolver.maven.workspace; +import io.quarkus.bootstrap.model.AppArtifactCoords; import io.quarkus.bootstrap.model.AppArtifactKey; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenContext; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenException; import io.quarkus.bootstrap.workspace.WorkspaceModule; -import io.quarkus.maven.dependency.ArtifactCoords; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -104,48 +104,51 @@ public File findArtifact(Artifact artifact) { && lp.getVersion().equals(resolvedVersion))) { return null; } - - if (ArtifactCoords.TYPE_POM.equals(artifact.getExtension())) { - final File pom = lp.getRawModel().getPomFile(); - // if the pom exists we should also check whether the main artifact can also be resolved from the workspace - if (pom.exists() && ("pom".equals(lp.getRawModel().getPackaging()) - || mvnCtx != null && mvnCtx.isPreferPomsFromWorkspace() - || Files.exists(lp.getOutputDir()) - || emptyJarOutput(lp, artifact) != null)) { - return pom; - } - } - - // Check whether the artifact exists in the project's output dir. - // It could also be a project with no sources/resources, in which case Maven will create an empty JAR - // if it has previously been packaged we can use it - Path path = lp.getOutputDir().resolve(getFileName(artifact)); - if (Files.exists(path)) { - return path.toFile(); - } - if (!Objects.equals(artifact.getClassifier(), lp.getAppArtifact().getClassifier())) { if ("tests".equals(artifact.getClassifier())) { //special classifier used for test jars - path = lp.getTestClassesDir(); + final Path path = lp.getTestClassesDir(); if (Files.exists(path)) { return path.toFile(); } } - // otherwise, this artifact hasn't been built yet return null; } + final String type = artifact.getExtension(); + if (type.equals(AppArtifactCoords.TYPE_JAR)) { + Path path = lp.getClassesDir(); + if (Files.exists(path)) { + return path.toFile(); + } - if (ArtifactCoords.TYPE_JAR.equals(artifact.getExtension())) { - path = lp.getClassesDir(); + // it could be a project with no sources/resources, in which case Maven will create an empty JAR + // if it has previously been packaged we can return it + path = lp.getOutputDir().resolve(getFileName(artifact)); if (Files.exists(path)) { return path.toFile(); } + path = emptyJarOutput(lp, artifact); if (path != null) { return path.toFile(); } + // otherwise, this project hasn't been built yet + } else if (type.equals(AppArtifactCoords.TYPE_POM)) { + final File pom = lp.getRawModel().getPomFile(); + // if the pom exists we should also check whether the main artifact can also be resolved from the workspace + if (pom.exists() && ("pom".equals(lp.getRawModel().getPackaging()) + || mvnCtx != null && mvnCtx.isPreferPomsFromWorkspace() + || Files.exists(lp.getOutputDir()) + || emptyJarOutput(lp, artifact) != null)) { + return pom; + } + } else { + // check whether the artifact exists in the project's output dir + final Path path = lp.getOutputDir().resolve(getFileName(artifact)); + if (Files.exists(path)) { + return path.toFile(); + } } return null; } @@ -159,7 +162,7 @@ private Path emptyJarOutput(LocalProject lp, Artifact artifact) { // so the Maven resolver will succeed resolving it from the repo. // If the artifact does not exist in the local repo, we are creating an empty classes directory in the target directory. if (!Files.exists(lp.getSourcesSourcesDir()) - && lp.getResourcesSourcesDirs().stream().noneMatch(Files::exists) + && lp.getResourcesSourcesDirs().toList().stream().noneMatch(Files::exists) && !isFoundInLocalRepo(artifact)) { try { final Path classesDir = lp.getClassesDir(); diff --git a/independent-projects/bootstrap/maven-resolver/src/test/java/io/quarkus/bootstrap/workspace/test/LocalWorkspaceDiscoveryTest.java b/independent-projects/bootstrap/maven-resolver/src/test/java/io/quarkus/bootstrap/workspace/test/LocalWorkspaceDiscoveryTest.java index fd2dc1a8504e9..e3d3045021bdd 100644 --- a/independent-projects/bootstrap/maven-resolver/src/test/java/io/quarkus/bootstrap/workspace/test/LocalWorkspaceDiscoveryTest.java +++ b/independent-projects/bootstrap/maven-resolver/src/test/java/io/quarkus/bootstrap/workspace/test/LocalWorkspaceDiscoveryTest.java @@ -14,9 +14,8 @@ import io.quarkus.bootstrap.resolver.maven.workspace.LocalProject; import io.quarkus.bootstrap.resolver.maven.workspace.LocalWorkspace; import io.quarkus.bootstrap.util.IoUtils; -import io.quarkus.bootstrap.workspace.SourceDir; +import io.quarkus.bootstrap.workspace.ProcessedSources; import io.quarkus.bootstrap.workspace.WorkspaceModule; -import io.quarkus.paths.PathTree; import java.io.File; import java.net.URL; import java.nio.file.Files; @@ -578,13 +577,12 @@ private void testMavenCiFriendlyVersion(String placeholder, String testResourceD final WorkspaceModule wsModule = module1.toWorkspaceModule(); Assertions.assertThat(wsModule.getModuleDir()).isEqualTo(module1Dir.toFile()); Assertions.assertThat(wsModule.getBuildDir()).isEqualTo(module1Dir.resolve("target").toFile()); - SourceDir src = wsModule.getMainSources().getResourceDirs().iterator().next(); - PathTree sourceTree = src.getSourceTree(); - Assertions.assertThat(sourceTree).isNotNull(); - Collection roots = sourceTree.getRoots(); - Assertions.assertThat(roots).hasSize(1); - Assertions.assertThat(roots.iterator().next()).isEqualTo(module1Dir.resolve("build")); - Assertions.assertThat(src.getOutputDir()).isEqualTo(module1Dir.resolve("target/classes/META-INF/resources")); + Collection c = wsModule.getMainResources(); + Assertions.assertThat(c).hasSize(1); + final ProcessedSources src = c.iterator().next(); + Assertions.assertThat(src.getSourceDir()).isEqualTo(module1Dir.resolve("build").toFile()); + Assertions.assertThat(src.getDestinationDir()) + .isEqualTo(module1Dir.resolve("target/classes/META-INF/resources").toFile()); } private void assertCompleteWorkspace(final LocalProject project) { diff --git a/integration-tests/gradle/src/test/java/io/quarkus/gradle/builder/QuarkusModelBuilderTest.java b/integration-tests/gradle/src/test/java/io/quarkus/gradle/builder/QuarkusModelBuilderTest.java index 5b2e2e81559c6..aa30735417aa6 100644 --- a/integration-tests/gradle/src/test/java/io/quarkus/gradle/builder/QuarkusModelBuilderTest.java +++ b/integration-tests/gradle/src/test/java/io/quarkus/gradle/builder/QuarkusModelBuilderTest.java @@ -19,9 +19,8 @@ import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.resolver.QuarkusGradleModelFactory; -import io.quarkus.bootstrap.workspace.SourceDir; +import io.quarkus.bootstrap.workspace.ProcessedSources; import io.quarkus.bootstrap.workspace.WorkspaceModule; -import io.quarkus.paths.PathTree; class QuarkusModelBuilderTest { @@ -58,40 +57,29 @@ private void assertProjectModule(WorkspaceModule projectModule, File projectDir, assertEquals(projectDir, projectModule.getModuleDir()); assertEquals(new File(projectDir, "build"), projectModule.getBuildDir()); - SourceDir src = projectModule.getMainSources().getSourceDirs().iterator().next(); + ProcessedSources src = projectModule.getMainSources().iterator().next(); assertNotNull(src); - assertThat(src.getOutputDir()).isEqualTo(projectDir.toPath().resolve("build/classes/java/main")); - PathTree sourceTree = src.getSourceTree(); - assertThat(sourceTree).isNotNull(); - assertThat(sourceTree.getRoots()).hasSize(1); - assertThat(sourceTree.getRoots().iterator().next()).isEqualTo(projectDir.toPath().resolve("src/main/java")); + assertThat(src.getDestinationDir()).isEqualTo(new File(projectDir, "build/classes/java/main")); + assertThat(src.getSourceDir()).isEqualTo(new File(projectDir, "src/main/java")); - src = projectModule.getMainSources().getResourceDirs().iterator().next(); + src = projectModule.getMainResources().iterator().next(); assertNotNull(src); - assertThat(src.getOutputDir()).isEqualTo(projectDir.toPath().resolve("build/resources/main")); - sourceTree = src.getSourceTree(); - assertThat(sourceTree).isNotNull(); - assertThat(sourceTree.getRoots()).hasSize(1); - assertThat(sourceTree.getRoots().iterator().next()).isEqualTo(projectDir.toPath().resolve("src/main/resources")); + assertThat(src.getDestinationDir()).isEqualTo(new File(projectDir, "build/resources/main")); + assertThat(src.getSourceDir()).isEqualTo(new File(projectDir, "src/main/resources")); if (withTests) { - src = projectModule.getTestSources().getSourceDirs().iterator().next(); + src = projectModule.getTestSources().iterator().next(); assertNotNull(src); - assertThat(src.getOutputDir()).isEqualTo(projectDir.toPath().resolve("build/classes/java/test")); - sourceTree = src.getSourceTree(); - assertThat(sourceTree).isNotNull(); - assertThat(sourceTree.getRoots()).hasSize(1); - assertThat(sourceTree.getRoots().iterator().next()).isEqualTo(projectDir.toPath().resolve("src/test/java")); + assertThat(src.getDestinationDir()).isEqualTo(new File(projectDir, "build/classes/java/test")); + assertThat(src.getSourceDir()).isEqualTo(new File(projectDir, "src/test/java")); - src = projectModule.getTestSources().getResourceDirs().iterator().next(); + src = projectModule.getTestResources().iterator().next(); assertNotNull(src); - assertThat(src.getOutputDir()).isEqualTo(projectDir.toPath().resolve("build/resources/test")); - sourceTree = src.getSourceTree(); - assertThat(sourceTree).isNotNull(); - assertThat(sourceTree.getRoots()).hasSize(1); - assertThat(sourceTree.getRoots().iterator().next()).isEqualTo(projectDir.toPath().resolve("src/test/resources")); + assertThat(src.getDestinationDir()).isEqualTo(new File(projectDir, "build/resources/test")); + assertThat(src.getSourceDir()).isEqualTo(new File(projectDir, "src/test/resources")); } else { - assertThat(projectModule.getTestSources()).isNull(); + assertThat(projectModule.getTestSources()).isEmpty(); + assertThat(projectModule.getTestResources()).isEmpty(); } } diff --git a/integration-tests/maven/src/test/java/io/quarkus/maven/it/DevMojoIT.java b/integration-tests/maven/src/test/java/io/quarkus/maven/it/DevMojoIT.java index 9c909316689df..11b04aef7c854 100644 --- a/integration-tests/maven/src/test/java/io/quarkus/maven/it/DevMojoIT.java +++ b/integration-tests/maven/src/test/java/io/quarkus/maven/it/DevMojoIT.java @@ -1183,70 +1183,4 @@ public void testPropertyExpansion() throws IOException, MavenInvocationException assertThat(DevModeTestUtils.getHttpResponse("/app/hello/")).isEqualTo("hello"); assertThat(DevModeTestUtils.getHttpResponse("/app/hello/applicationName")).isEqualTo("myapp"); } - - @Test - public void testMultiJarModuleDevModeMocks() throws MavenInvocationException, IOException { - testDir = initProject("projects/multijar-module", "projects/multijar-module-devmode-mocks"); - run(false, "clean", "package", "-DskipTests", "-Dqdev"); - - String greeting = DevModeTestUtils.getHttpResponse("/hello"); - assertThat(greeting).contains("acme other mock-service"); - - // Update TestBean - File resource = new File(testDir, "beans/src/test/java/org/acme/testlib/mock/MockService.java"); - filter(resource, Collections.singletonMap("return \"mock-service\";", "return \"mock-service!\";")); - await() - .pollDelay(300, TimeUnit.MILLISECONDS) - .atMost(1, TimeUnit.MINUTES) - .until(() -> DevModeTestUtils.getHttpResponse("/hello").contains("acme other mock-service!")); - - // Update AcmeBean - resource = new File(testDir, "beans/src/main/java/org/acme/AcmeBean.java"); - filter(resource, Collections.singletonMap("return \"acme\";", "return \"acme!\";")); - await() - .pollDelay(100, TimeUnit.MILLISECONDS) - .atMost(1, TimeUnit.MINUTES) - .until(() -> DevModeTestUtils.getHttpResponse("/hello").contains("acme! other mock-service!")); - - // Update Other bean - resource = new File(testDir, "beans/src/main/java/org/acme/Other.java"); - filter(resource, Collections.singletonMap("return \"other\";", "return \"other!\";")); - await() - .pollDelay(300, TimeUnit.MILLISECONDS) - .atMost(1, TimeUnit.MINUTES) - .until(() -> DevModeTestUtils.getHttpResponse("/hello").contains("acme! other! mock-service!")); - } - - @Test - public void testMultiJarModuleDevMode() throws MavenInvocationException, IOException { - testDir = initProject("projects/multijar-module", "projects/multijar-module-devmode"); - run(false, "clean", "package", "-DskipTests"); - - String greeting = DevModeTestUtils.getHttpResponse("/hello"); - assertThat(greeting).contains("acme other acme-service"); - - // Update TestBean - File resource = new File(testDir, "beans/src/main/java/org/acme/AcmeService.java"); - filter(resource, Collections.singletonMap("return \"acme-service\";", "return \"acme-service!\";")); - await() - .pollDelay(300, TimeUnit.MILLISECONDS) - .atMost(1, TimeUnit.MINUTES) - .until(() -> DevModeTestUtils.getHttpResponse("/hello").contains("acme other acme-service!")); - - // Update AcmeBean - resource = new File(testDir, "beans/src/main/java/org/acme/AcmeBean.java"); - filter(resource, Collections.singletonMap("return \"acme\";", "return \"acme!\";")); - await() - .pollDelay(100, TimeUnit.MILLISECONDS) - .atMost(1, TimeUnit.MINUTES) - .until(() -> DevModeTestUtils.getHttpResponse("/hello").contains("acme! other acme-service!")); - - // Update Other bean - resource = new File(testDir, "beans/src/main/java/org/acme/Other.java"); - filter(resource, Collections.singletonMap("return \"other\";", "return \"other!\";")); - await() - .pollDelay(300, TimeUnit.MILLISECONDS) - .atMost(1, TimeUnit.MINUTES) - .until(() -> DevModeTestUtils.getHttpResponse("/hello").contains("acme! other! acme-service!")); - } } diff --git a/integration-tests/maven/src/test/java/io/quarkus/maven/it/PackageIT.java b/integration-tests/maven/src/test/java/io/quarkus/maven/it/PackageIT.java index 567b0669a9e3a..b21ceb165a3a4 100644 --- a/integration-tests/maven/src/test/java/io/quarkus/maven/it/PackageIT.java +++ b/integration-tests/maven/src/test/java/io/quarkus/maven/it/PackageIT.java @@ -282,18 +282,6 @@ public void testNativeSourcesPackage() throws Exception { } - @Test - public void testMultiJarModulesPackage() throws Exception { - testDir = initProject("projects/multijar-module", "projects/multijar-module-package"); - - running = new RunningInvoker(testDir, false); - final MavenProcessInvocationResult result = running.execute( - Arrays.asList("package"), - Collections.emptyMap()); - - assertThat(result.getProcess().waitFor()).isEqualTo(0); - } - private int getNumberOfFilesEndingWith(File dir, String suffix) { return getFilesEndingWith(dir, suffix).size(); } diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/pom.xml b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/pom.xml deleted file mode 100644 index 5579bf66c978a..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/pom.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - 4.0.0 - - - org.acme - acme-parent - ${revision}.${changelist}${sha1} - - - acme-beans - - - - io.quarkus - quarkus-arc - - - - - - - maven-jar-plugin - 3.2.0 - - - default-jar - - jar - - - - org/acme/Other.class - - - - - other-jar - - jar - - - other - - META-INF/beans.xml - org/acme/Other.class - - - - - mocks-jar - - test-jar - - - mocks - - META-INF/beans.xml - org/acme/testlib/mock/** - - - - - test-jar - - test-jar - - - - META-INF/beans.xml - application.properties - org/acme/testlib/TestMessage.class - - - - - - - - diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/AcmeBean.java b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/AcmeBean.java deleted file mode 100644 index 584659014dabb..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/AcmeBean.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.acme; - -import javax.enterprise.context.ApplicationScoped; - -@ApplicationScoped -public class AcmeBean implements Named { - - @Override - public String getName() { - return "acme"; - } -} \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/AcmeService.java b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/AcmeService.java deleted file mode 100644 index 67f01f369b7c3..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/AcmeService.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.acme; - -public class AcmeService implements Service { - - public String getId() { - return "acme-service"; - } -} \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/AcmeServiceProducer.java b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/AcmeServiceProducer.java deleted file mode 100644 index 29da0b9e97dca..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/AcmeServiceProducer.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.acme; - -import javax.enterprise.context.Dependent; -import javax.enterprise.inject.Produces; -import io.quarkus.arc.DefaultBean; - -@Dependent -public class AcmeServiceProducer { - - @Produces - @DefaultBean - public Service getAcmeService() { - return new AcmeService(); - } -} \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Named.java b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Named.java deleted file mode 100644 index f7e31250c73a7..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Named.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.acme; - -public interface Named { - String getName(); -} \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Other.java b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Other.java deleted file mode 100644 index ada2f2240fe2b..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Other.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.acme; - -import javax.enterprise.context.ApplicationScoped; - -@ApplicationScoped -public class Other implements Named { - - @Override - public String getName() { - return "other"; - } -} \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Printer.java b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Printer.java deleted file mode 100644 index 8f09858b6b25c..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Printer.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.acme; - -import javax.enterprise.context.ApplicationScoped; - -@ApplicationScoped -public class Printer { - - public static interface Message { - - String getMessage(); - } - - public void println(Message msg) { - System.out.println(msg.getMessage()); - } -} diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Service.java b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Service.java deleted file mode 100644 index fcaf87c2e147f..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/java/org/acme/Service.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.acme; - -public interface Service { - - String getId(); -} \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/resources/META-INF/beans.xml b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/main/resources/META-INF/beans.xml deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/java/org/acme/testlib/TestMessage.java b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/java/org/acme/testlib/TestMessage.java deleted file mode 100644 index e0da3a0e0e942..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/java/org/acme/testlib/TestMessage.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.acme.testlib; - -import org.acme.Printer; - -public class TestMessage implements Printer.Message { - - private final String msg; - - public TestMessage(String msg) { - this.msg = msg; - } - - @Override - public String getMessage() { - return msg; - } -} diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/java/org/acme/testlib/mock/MockService.java b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/java/org/acme/testlib/mock/MockService.java deleted file mode 100644 index 6fef7c5749ea5..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/java/org/acme/testlib/mock/MockService.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.acme.testlib.mock; - -import org.acme.Service; - -public class MockService implements Service { - - public String getId() { - return "mock-service"; - } -} \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/java/org/acme/testlib/mock/MockServiceProducer.java b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/java/org/acme/testlib/mock/MockServiceProducer.java deleted file mode 100644 index 34bacc873345d..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/java/org/acme/testlib/mock/MockServiceProducer.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.acme.testlib.mock; - -import javax.enterprise.context.Dependent; -import javax.enterprise.inject.Produces; -import io.quarkus.arc.DefaultBean; -import org.acme.Service; - -@Dependent -public class MockServiceProducer { - - @Produces - public Service getMockService() { - return new MockService(); - } -} \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/resources/META-INF/beans.xml b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/resources/META-INF/beans.xml deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/resources/application.properties b/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/resources/application.properties deleted file mode 100644 index f16a861cf4ada..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/beans/src/test/resources/application.properties +++ /dev/null @@ -1,2 +0,0 @@ -config_ordinal=256 -greeting=bonjour \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/pom.xml b/integration-tests/maven/src/test/resources/projects/multijar-module/pom.xml deleted file mode 100644 index 3d52e99f5f45b..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/pom.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - 4.0.0 - - org.acme - acme-parent - ${revision}.${changelist}${sha1} - pom - - - 2.0.0 - local - - io.quarkus - quarkus-bom - @project.version@ - 3.0.0-M5 - UTF-8 - 11 - 11 - - - beans - runner - - - - - - ${quarkus.platform.group-id} - quarkus-maven-plugin - ${quarkus.platform.version} - - - - - - - - ${quarkus.platform.group-id} - ${quarkus.platform.artifact-id} - ${quarkus.platform.version} - pom - import - - - org.acme - acme-beans - \${project.version} - - - org.acme - acme-beans - other - \${project.version} - - - org.acme - acme-beans - mocks - \${project.version} - - - org.acme - acme-beans - - test-jar - \${project.version} - - - org.acme - acme-runner - \${project.version} - - - - - diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/runner/pom.xml b/integration-tests/maven/src/test/resources/projects/multijar-module/runner/pom.xml deleted file mode 100644 index e449aba924883..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/runner/pom.xml +++ /dev/null @@ -1,139 +0,0 @@ - - - 4.0.0 - - org.acme - acme-parent - ${revision}.${changelist}${sha1} - - acme-runner - - - - io.quarkus - quarkus-resteasy - - - org.acme - acme-beans - - - org.acme - acme-beans - other - - - org.acme - acme-beans - - test-jar - test - - - org.acme - acme-beans - mocks - test - - - io.quarkus - quarkus-junit5 - test - - - io.rest-assured - rest-assured - test - - - - - - - maven-surefire-plugin - ${surefire-plugin.version} - - - org.jboss.logmanager.LogManager - ${maven.home} - - - - - ${quarkus.platform.group-id} - quarkus-maven-plugin - ${quarkus.platform.version} - - - - build - - - - - - - - - - - qdev - - - qdev - - - - - org.acme - acme-beans - mocks - - - - clean quarkus:dev - - - - native - - - native - - - - native - - - - - org.apache.maven.plugins - maven-surefire-plugin - - ${skipTests} - - - - maven-failsafe-plugin - ${surefire-plugin.version} - - - - integration-test - verify - - - - ${project.build.directory}/${project.build.finalName}-runner - org.jboss.logmanager.LogManager - ${maven.home} - - - - - - - - - - diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/runner/src/main/java/org/acme/HelloResource.java b/integration-tests/maven/src/test/resources/projects/multijar-module/runner/src/main/java/org/acme/HelloResource.java deleted file mode 100644 index 99680447b5e04..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/runner/src/main/java/org/acme/HelloResource.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.acme; - -import org.eclipse.microprofile.config.inject.ConfigProperty; - -import javax.inject.Inject; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import java.io.IOException; -import java.net.URL; -import java.util.Enumeration; -import org.eclipse.microprofile.config.inject.ConfigProperty; - -@Path("/hello") -public class HelloResource { - - @Inject - AcmeBean acme; - - @Inject - Other other; - - @Inject - Service service; - - @ConfigProperty(name="greeting") - String greeting; - - @GET - @Produces(MediaType.TEXT_PLAIN) - public String hello() { - return greeting + " " + acme.getName() + " " + other.getName() + " " + service.getId(); - } -} diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/runner/src/main/resources/application.properties b/integration-tests/maven/src/test/resources/projects/multijar-module/runner/src/main/resources/application.properties deleted file mode 100644 index e617a433772cb..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/runner/src/main/resources/application.properties +++ /dev/null @@ -1,4 +0,0 @@ -#quarkus.test.continuous-testing=enabled -#quarkus.test.basic-console=true -quarkus.live-reload.instrumentation=false -greeting=hello \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources/projects/multijar-module/runner/src/test/java/org/acme/ResourceTest.java b/integration-tests/maven/src/test/resources/projects/multijar-module/runner/src/test/java/org/acme/ResourceTest.java deleted file mode 100644 index a1f4aa6ef7664..0000000000000 --- a/integration-tests/maven/src/test/resources/projects/multijar-module/runner/src/test/java/org/acme/ResourceTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.acme; - -import static io.restassured.RestAssured.given; -import static org.hamcrest.CoreMatchers.is; - -import java.util.UUID; -import javax.inject.Inject; - -import org.junit.jupiter.api.Test; - -import org.acme.testlib.TestMessage; - -import io.quarkus.test.junit.QuarkusTest; - -@QuarkusTest -public class ResourceTest { - - @Inject - Service service; - - @Inject - Printer printer; - - @Test - public void testHelloEndpoint() { - given() - .when().get("/hello") - .then() - .statusCode(200) - .body(is("bonjour acme other mock-service")); - } - - @Test - public void testPrintMessage() { - // this is testing the TestMessage class can be loaded - printer.println(new TestMessage("test message")); - } -} diff --git a/test-framework/jacoco/deployment/src/main/java/io/quarkus/jacoco/deployment/JacocoProcessor.java b/test-framework/jacoco/deployment/src/main/java/io/quarkus/jacoco/deployment/JacocoProcessor.java index 631df156e1785..6bdd6abf9b20b 100644 --- a/test-framework/jacoco/deployment/src/main/java/io/quarkus/jacoco/deployment/JacocoProcessor.java +++ b/test-framework/jacoco/deployment/src/main/java/io/quarkus/jacoco/deployment/JacocoProcessor.java @@ -3,7 +3,6 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; import java.util.HashSet; @@ -18,7 +17,8 @@ import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.bootstrap.utils.BuildToolHelper; -import io.quarkus.bootstrap.workspace.SourceDir; +import io.quarkus.bootstrap.workspace.ProcessedSources; +import io.quarkus.bootstrap.workspace.WorkspaceModule; import io.quarkus.deployment.ApplicationArchive; import io.quarkus.deployment.IsTest; import io.quarkus.deployment.annotations.BuildProducer; @@ -118,11 +118,11 @@ public byte[] apply(String className, byte[] bytes) { } if (model.getApplicationModule() != null) { - addProjectModule(model.getAppArtifact(), config, info, includes, excludes, classes, sources); + addProjectModule(model.getApplicationModule(), config, info, includes, excludes, classes, sources); } for (ResolvedDependency d : model.getDependencies()) { - if (d.isRuntimeCp() && d.isWorkspaceModule()) { - addProjectModule(d, config, info, includes, excludes, classes, sources); + if (d.isRuntimeCp() && d.isWorkspacetModule()) { + addProjectModule(d.getWorkspaceModule(), config, info, includes, excludes, classes, sources); } } @@ -132,15 +132,13 @@ public byte[] apply(String className, byte[] bytes) { } } - private void addProjectModule(ResolvedDependency module, JacocoConfig config, ReportInfo info, String includes, + private void addProjectModule(WorkspaceModule module, JacocoConfig config, ReportInfo info, String includes, String excludes, Set classes, Set sources) throws Exception { - info.savedData.add(new File(module.getWorkspaceModule().getBuildDir(), config.dataFile).getAbsolutePath()); - for (SourceDir src : module.getSources().getSourceDirs()) { - for (Path p : src.getSourceTree().getRoots()) { - sources.add(p.toAbsolutePath().toString()); - } - if (Files.isDirectory(src.getOutputDir())) { - for (final File file : FileUtils.getFiles(src.getOutputDir().toFile(), includes, excludes, + info.savedData.add(new File(module.getBuildDir(), config.dataFile).getAbsolutePath()); + for (ProcessedSources src : module.getMainSources()) { + sources.add(src.getSourceDir().getAbsolutePath()); + if (src.getDestinationDir().isDirectory()) { + for (final File file : FileUtils.getFiles(src.getDestinationDir(), includes, excludes, true)) { if (file.getName().endsWith(".class")) { classes.add(file.getAbsolutePath()); diff --git a/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusDevModeTest.java b/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusDevModeTest.java index 2f589f825fa7d..0a24231b861a8 100644 --- a/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusDevModeTest.java +++ b/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusDevModeTest.java @@ -48,6 +48,7 @@ import org.junit.jupiter.api.extension.TestInstanceFactoryContext; import org.junit.jupiter.api.extension.TestInstantiationException; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.deployment.dev.CompilationProvider; import io.quarkus.deployment.dev.DevModeContext; import io.quarkus.deployment.dev.DevModeMain; @@ -56,7 +57,6 @@ import io.quarkus.dev.testing.TestScanningLock; import io.quarkus.fs.util.ZipUtils; import io.quarkus.maven.dependency.GACT; -import io.quarkus.paths.PathList; import io.quarkus.runtime.LaunchMode; import io.quarkus.runtime.configuration.ProfileManager; import io.quarkus.runtime.util.ClassPathUtils; @@ -392,12 +392,13 @@ private DevModeContext exportArchive(Path deploymentDir, Path testSourceDir, Pat DevModeContext.ModuleInfo.Builder moduleBuilder = new DevModeContext.ModuleInfo.Builder() .setArtifactKey(GACT.fromString("io.quarkus.test:app-under-test")) + .setName("default") .setProjectDirectory(deploymentDir.toAbsolutePath().toString()) - .setSourcePaths(PathList.of(deploymentSourcePath.toAbsolutePath())) + .setSourcePaths(PathsCollection.of(deploymentSourcePath.toAbsolutePath())) .setClassesPath(classes.toAbsolutePath().toString()) - .setResourcePaths(PathList.of(deploymentResourcePath.toAbsolutePath())) + .setResourcePaths(PathsCollection.of(deploymentResourcePath.toAbsolutePath())) .setResourcesOutputPath(classes.toAbsolutePath().toString()) - .setSourceParents(PathList.of(deploymentSourceParentPath.toAbsolutePath())) + .setSourceParents(PathsCollection.of(deploymentSourceParentPath.toAbsolutePath())) .setPreBuildOutputDir(targetDir.resolve("generated-sources").toAbsolutePath().toString()) .setTargetDir(targetDir.toAbsolutePath().toString()); @@ -442,9 +443,9 @@ private DevModeContext exportArchive(Path deploymentDir, Path testSourceDir, Pat }); } moduleBuilder - .setTestSourcePaths(PathList.of(deploymentTestSourcePath.toAbsolutePath())) + .setTestSourcePaths(PathsCollection.of(deploymentTestSourcePath.toAbsolutePath())) .setTestClassesPath(testClasses.toAbsolutePath().toString()) - .setTestResourcePaths(PathList.of(deploymentTestResourcePath.toAbsolutePath())) + .setTestResourcePaths(PathsCollection.of(deploymentTestResourcePath.toAbsolutePath())) .setTestResourcesOutputPath(testClasses.toAbsolutePath().toString()); } @@ -833,7 +834,7 @@ private void copyFromSource(Path projectSourcesDir, Path deploymentSourcesDir, P private Path copySourceFilesForClass(Path projectSourcesDir, Path deploymentSourcesDir, Path classesDir, Path classFile) { for (CompilationProvider provider : compilationProviders) { Path source = provider.getSourcePath(classFile, - PathList.of(projectSourcesDir.toAbsolutePath()), + PathsCollection.of(projectSourcesDir.toAbsolutePath()), classesDir.toAbsolutePath().toString()); if (source != null) { String relative = projectSourcesDir.relativize(source).toString(); @@ -855,7 +856,7 @@ private Path findTargetSourceFilesForPath(Path projectSourcesDir, Path deploymen Path classFile) { for (CompilationProvider provider : compilationProviders) { Path source = provider.getSourcePath(classFile, - PathList.of(projectSourcesDir.toAbsolutePath()), + PathsCollection.of(projectSourcesDir.toAbsolutePath()), classesDir.toAbsolutePath().toString()); if (source != null) { String relative = projectSourcesDir.relativize(source).toString(); diff --git a/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusUnitTest.java b/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusUnitTest.java index 860f6aa74c2f8..652437ba117a8 100644 --- a/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusUnitTest.java +++ b/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusUnitTest.java @@ -557,7 +557,7 @@ public boolean test(String s) { QuarkusClassLoader .builder("QuarkusUnitTest ClassLoader", getClass().getClassLoader(), false) .addClassLoaderEventListeners(this.classLoadListeners) - .addBannedElement(ClassPathElement.fromPath(testLocation, true)).build()); + .addBannedElement(ClassPathElement.fromPath(testLocation)).build()); } builder.addClassLoaderEventListeners(this.classLoadListeners); curatedApplication = builder.build().bootstrap(); diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java index 89756decef6d5..b29378e583965 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java @@ -24,12 +24,10 @@ import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.runner.Timing; import io.quarkus.bootstrap.utils.BuildToolHelper; -import io.quarkus.bootstrap.workspace.ArtifactSources; -import io.quarkus.bootstrap.workspace.SourceDir; import io.quarkus.deployment.dev.testing.CurrentTestApplication; -import io.quarkus.paths.PathList; import io.quarkus.runtime.configuration.ProfileManager; import io.quarkus.test.common.PathTestHelper; import io.quarkus.test.common.QuarkusTestResource; @@ -57,7 +55,7 @@ protected PrepareResult createAugmentor(ExtensionContext context, Class { + if (src.getDestinationDir().exists()) { + final Path classesDir = src.getDestinationDir().toPath(); + if (!rootBuilder.contains(classesDir)) { + rootBuilder.add(classesDir); } } - } - for (SourceDir src : model.getApplicationModule().getMainSources().getSourceDirs()) { - if (Files.exists(src.getOutputDir())) { - final Path classesDir = src.getOutputDir(); + }); + model.getApplicationModule().getMainSources().forEach(src -> { + if (src.getDestinationDir().exists()) { + final Path classesDir = src.getDestinationDir().toPath(); if (!rootBuilder.contains(classesDir)) { rootBuilder.add(classesDir); } } - } + }); } } else if (System.getProperty(BootstrapConstants.OUTPUT_SOURCES_DIR) != null) { final String[] sourceDirectories = System.getProperty(BootstrapConstants.OUTPUT_SOURCES_DIR).split(","); diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/IntegrationTestUtil.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/IntegrationTestUtil.java index b7249b5b111eb..b253d9d039cdb 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/IntegrationTestUtil.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/IntegrationTestUtil.java @@ -42,11 +42,9 @@ import io.quarkus.bootstrap.app.CuratedApplication; import io.quarkus.bootstrap.app.QuarkusBootstrap; import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.utils.BuildToolHelper; -import io.quarkus.bootstrap.workspace.ArtifactSources; -import io.quarkus.bootstrap.workspace.SourceDir; import io.quarkus.deployment.builditem.DevServicesLauncherConfigResultBuildItem; -import io.quarkus.paths.PathList; import io.quarkus.runtime.configuration.ProfileManager; import io.quarkus.runtime.logging.LoggingSetupRecorder; import io.quarkus.test.common.ArtifactLauncher; @@ -201,7 +199,7 @@ static ArtifactLauncher.InitContext.DevServicesLaunchResult handleDevServices(Ex Path testClassLocation = getTestClassesLocation(requiredTestClass); final Path appClassLocation = getAppClassLocationForTestLocation(testClassLocation.toString()); - final PathList.Builder rootBuilder = PathList.builder(); + PathsCollection.Builder rootBuilder = PathsCollection.builder(); if (!appClassLocation.equals(testClassLocation)) { rootBuilder.add(testClassLocation); @@ -215,6 +213,7 @@ static ArtifactLauncher.InitContext.DevServicesLaunchResult handleDevServices(Ex final QuarkusBootstrap.Builder runnerBuilder = QuarkusBootstrap.builder() .setIsolateDeployment(true) .setMode(QuarkusBootstrap.Mode.TEST); + QuarkusTestProfile profileInstance = null; final Path projectRoot = Paths.get("").normalize().toAbsolutePath(); runnerBuilder.setProjectRoot(projectRoot); @@ -238,25 +237,22 @@ static ArtifactLauncher.InitContext.DevServicesLaunchResult handleDevServices(Ex if (System.getProperty(BootstrapConstants.SERIALIZED_TEST_APP_MODEL) == null) { ApplicationModel model = BuildToolHelper.enableGradleAppModelForTest(projectRoot); if (model != null && model.getApplicationModule() != null) { - final ArtifactSources testSources = model.getApplicationModule().getTestSources(); - if (testSources != null) { - for (SourceDir src : testSources.getSourceDirs()) { - if (!Files.exists(src.getOutputDir())) { - final Path classes = src.getOutputDir(); - if (!rootBuilder.contains(classes)) { - rootBuilder.add(classes); - } + model.getApplicationModule().getTestSources().forEach(src -> { + if (!src.getDestinationDir().exists()) { + final Path classes = src.getDestinationDir().toPath(); + if (!rootBuilder.contains(classes)) { + rootBuilder.add(classes); } } - } - for (SourceDir src : model.getApplicationModule().getMainSources().getSourceDirs()) { - if (!Files.exists(src.getOutputDir())) { - final Path classes = src.getOutputDir(); + }); + model.getApplicationModule().getMainSources().forEach(src -> { + if (!src.getDestinationDir().exists()) { + final Path classes = src.getDestinationDir().toPath(); if (!rootBuilder.contains(classes)) { rootBuilder.add(classes); } } - } + }); } } else if (System.getProperty(BootstrapConstants.OUTPUT_SOURCES_DIR) != null) { final String[] sourceDirectories = System.getProperty(BootstrapConstants.OUTPUT_SOURCES_DIR).split(",");