diff options
author | gjoranv <gv@verizonmedia.com> | 2019-07-19 11:25:40 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-19 11:25:40 +0200 |
commit | 4b04f0b6da1c27f7be90e2a87f29aad10d70d5b8 (patch) | |
tree | 2c5d1396a3f3d14bcc3701fd428bc13f945e6624 | |
parent | 65d7e907c52092fa9488f662aa7eded976d4bd2e (diff) | |
parent | 3a548ea896592654e8d0ebff204b5ac7f751220a (diff) |
Merge pull request #10058 from vespa-engine/gjoranv/bundle-plugin-improvements
Gjoranv/bundle plugin improvements
10 files changed, 212 insertions, 43 deletions
diff --git a/bundle-plugin-test/src/test/java/com/yahoo/BundleIT.java b/bundle-plugin-test/src/test/java/com/yahoo/BundleIT.java index 5b4fdda06f7..932b78a5c8d 100644 --- a/bundle-plugin-test/src/test/java/com/yahoo/BundleIT.java +++ b/bundle-plugin-test/src/test/java/com/yahoo/BundleIT.java @@ -18,6 +18,7 @@ import java.util.jar.JarFile; import java.util.jar.Manifest; import java.util.zip.ZipEntry; +import static com.yahoo.osgi.maven.ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.anyOf; import static org.hamcrest.CoreMatchers.containsString; @@ -143,9 +144,9 @@ public class BundleIT { @SuppressWarnings("unchecked") @Test public void bundle_class_path_mappings_are_generated() throws URISyntaxException, IOException { - URL mappingsUrl = getClass().getResource("/" + com.yahoo.osgi.maven.ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME); + URL mappingsUrl = getClass().getResource("/" + CLASSPATH_MAPPINGS_FILENAME); assertNotNull( - "Could not find " + ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME + " in the test output directory", + "Could not find " + CLASSPATH_MAPPINGS_FILENAME + " in the test output directory", mappingsUrl); ProjectBundleClassPaths bundleClassPaths = ProjectBundleClassPaths.load(Paths.get(mappingsUrl.toURI())); diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/bundle/AnalyzeBundle.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/bundle/AnalyzeBundle.java index 798fea2644e..0626c786822 100644 --- a/bundle-plugin/src/main/java/com/yahoo/container/plugin/bundle/AnalyzeBundle.java +++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/bundle/AnalyzeBundle.java @@ -11,10 +11,14 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.jar.Manifest; import java.util.stream.Collectors; /** + * "Public package" in this context means a package that is either exported or declared as "Global-Package" + * in a bundle's manifest. + * * @author Tony Vaagenes * @author ollivir */ @@ -23,10 +27,18 @@ public class AnalyzeBundle { public final List<Export> exports; public final List<String> globals; - public PublicPackages(List<Export> exports, List<String> globals) { + PublicPackages(List<Export> exports, List<String> globals) { this.exports = exports; this.globals = globals; } + + public Set<String> exportedPackageNames() { + return exports.stream() + .map(Export::getPackageNames) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + } + } public static PublicPackages publicPackagesAggregated(Collection<File> jarFiles) { diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageTally.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageTally.java index 13bbc63192c..9f5fd2236e7 100644 --- a/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageTally.java +++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageTally.java @@ -1,6 +1,7 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.plugin.classanalysis; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Sets; import com.yahoo.container.plugin.util.Maps; @@ -10,6 +11,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; /** * @author Tony Vaagenes @@ -19,7 +21,8 @@ public class PackageTally { private final Map<String, Optional<ExportPackageAnnotation>> definedPackagesMap; private final Set<String> referencedPackagesUnfiltered; - public PackageTally(Map<String, Optional<ExportPackageAnnotation>> definedPackagesMap, Set<String> referencedPackagesUnfiltered) { + @VisibleForTesting + PackageTally(Map<String, Optional<ExportPackageAnnotation>> definedPackagesMap, Set<String> referencedPackagesUnfiltered) { this.definedPackagesMap = definedPackagesMap; this.referencedPackagesUnfiltered = referencedPackagesUnfiltered; } @@ -41,6 +44,19 @@ public class PackageTally { } /** + * Returns the set of packages that is referenced from this tally, but not included in the given set of available packages. + * + * @param definedAndExportedPackages Set of available packages (usually all packages defined in the generated bundle's project + all exported packages of dependencies) + * @return The set of missing packages, that may cause problem when the bundle is deployed in an OSGi container runtime. + */ + public Set<String> referencedPackagesMissingFrom(Set<String> definedAndExportedPackages) { + return Sets.difference(referencedPackages(), definedAndExportedPackages).stream() + .filter(pkg -> !pkg.startsWith("java.")) + .filter(pkg -> !pkg.equals(com.yahoo.api.annotations.PublicApi.class.getPackageName())) + .collect(Collectors.toSet()); + } + + /** * Represents the classes for two package tallies that are deployed as a single unit. * <p> * ExportPackageAnnotations from this has precedence over the other. diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/mojo/Artifacts.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/mojo/Artifacts.java index fff88d413d0..a0d0e143724 100644 --- a/bundle-plugin/src/main/java/com/yahoo/container/plugin/mojo/Artifacts.java +++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/mojo/Artifacts.java @@ -12,8 +12,8 @@ import java.util.List; * @author Tony Vaagenes * @author ollivir */ -public class Artifacts { - public static class ArtifactSet { +class Artifacts { + static class ArtifactSet { private final List<Artifact> jarArtifactsToInclude; private final List<Artifact> jarArtifactsProvided; private final List<Artifact> nonJarArtifacts; @@ -24,20 +24,20 @@ public class Artifacts { this.nonJarArtifacts = nonJarArtifacts; } - public List<Artifact> getJarArtifactsToInclude() { + List<Artifact> getJarArtifactsToInclude() { return jarArtifactsToInclude; } - public List<Artifact> getJarArtifactsProvided() { + List<Artifact> getJarArtifactsProvided() { return jarArtifactsProvided; } - public List<Artifact> getNonJarArtifacts() { + List<Artifact> getNonJarArtifacts() { return nonJarArtifacts; } } - public static ArtifactSet getArtifacts(MavenProject project) { + static ArtifactSet getArtifacts(MavenProject project) { List<Artifact> jarArtifactsToInclude = new ArrayList<>(); List<Artifact> jarArtifactsProvided = new ArrayList<>(); @@ -63,7 +63,7 @@ public class Artifacts { return new ArtifactSet(jarArtifactsToInclude, jarArtifactsProvided, nonJarArtifactsToInclude); } - public static Collection<Artifact> getArtifactsToInclude(MavenProject project) { + static Collection<Artifact> getArtifactsToInclude(MavenProject project) { return getArtifacts(project).getJarArtifactsToInclude(); } } diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/mojo/GenerateOsgiManifestMojo.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/mojo/GenerateOsgiManifestMojo.java index 9c9957ae718..04f2428d284 100644 --- a/bundle-plugin/src/main/java/com/yahoo/container/plugin/mojo/GenerateOsgiManifestMojo.java +++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/mojo/GenerateOsgiManifestMojo.java @@ -10,14 +10,12 @@ import com.yahoo.container.plugin.classanalysis.PackageTally; import com.yahoo.container.plugin.osgi.ExportPackageParser; import com.yahoo.container.plugin.osgi.ExportPackages; import com.yahoo.container.plugin.osgi.ExportPackages.Export; -import com.yahoo.container.plugin.osgi.ImportPackages; import com.yahoo.container.plugin.osgi.ImportPackages.Import; import com.yahoo.container.plugin.util.Strings; import org.apache.commons.lang3.tuple.Pair; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; @@ -41,6 +39,9 @@ import java.util.jar.Manifest; import java.util.stream.Collectors; import java.util.stream.Stream; +import static com.yahoo.container.plugin.bundle.AnalyzeBundle.publicPackagesAggregated; +import static com.yahoo.container.plugin.osgi.ExportPackages.exportsByPackageName; +import static com.yahoo.container.plugin.osgi.ImportPackages.calculateImports; import static com.yahoo.container.plugin.util.Files.allDescendantFiles; import static com.yahoo.container.plugin.util.IO.withFileOutputStream; import static com.yahoo.container.plugin.util.JarFiles.withInputStream; @@ -90,32 +91,43 @@ public class GenerateOsgiManifestMojo extends AbstractMojo { @Parameter(alias = "X-Jersey-Binding") private String jerseyBinding = null; - public void execute() throws MojoExecutionException, MojoFailureException { + public void execute() throws MojoExecutionException { try { Artifacts.ArtifactSet artifactSet = Artifacts.getArtifacts(project); warnOnUnsupportedArtifacts(artifactSet.getNonJarArtifacts()); - AnalyzeBundle.PublicPackages publicPackagesFromProvidedJars = AnalyzeBundle.publicPackagesAggregated( + // Packages from Export-Package and Global-Package headers in provided scoped jars + AnalyzeBundle.PublicPackages publicPackagesFromProvidedJars = publicPackagesAggregated( artifactSet.getJarArtifactsProvided().stream().map(Artifact::getFile).collect(Collectors.toList())); - PackageTally includedJarPackageTally = definedPackages(artifactSet.getJarArtifactsToInclude()); - PackageTally projectPackageTally = analyzeProjectClasses(); - PackageTally pluginPackageTally = projectPackageTally.combine(includedJarPackageTally); + // Packages from Export-Package headers in provided scoped jars + Set<String> exportedPackagesFromProvidedDeps = publicPackagesFromProvidedJars.exportedPackageNames(); - Set<String> definedPackages = new HashSet<>(projectPackageTally.definedPackages()); - definedPackages.addAll(includedJarPackageTally.definedPackages()); + // Packaged defined in this project's code + PackageTally projectPackages = getProjectClassesTally(); - warnIfPackagesDefinedOverlapsGlobalPackages(definedPackages, publicPackagesFromProvidedJars.globals); + // Packages defined in compile scoped jars + PackageTally compileJarsPackages = definedPackages(artifactSet.getJarArtifactsToInclude()); - if (getLog().isDebugEnabled()) { - getLog().debug("Referenced packages = " + pluginPackageTally.referencedPackages()); - getLog().debug("Defined packages = " + pluginPackageTally.definedPackages()); - getLog().debug("Exported packages of dependencies = " + publicPackagesFromProvidedJars.exports.stream() - .map(e -> "(" + e.getPackageNames().toString() + ", " + e.version().orElse("")).collect(Collectors.joining(", "))); + // The union of packages in the project and compile scoped jars + PackageTally includedPackages = projectPackages.combine(compileJarsPackages); + + warnIfPackagesDefinedOverlapsGlobalPackages(includedPackages.definedPackages(), publicPackagesFromProvidedJars.globals); + logDebugPackageSets(publicPackagesFromProvidedJars, includedPackages); + + if (hasJdiscCoreProvided(artifactSet.getJarArtifactsProvided())) { + // jdisc_core being provided guarantees that log output does not contain its exported packages + logMissingPackages(exportedPackagesFromProvidedDeps, projectPackages, compileJarsPackages, includedPackages); + } else { + getLog().warn("This project does not have jdisc_core as provided dependency, so the " + + "generated 'Import-Package' OSGi header may be missing important packages."); } + logOverlappingPackages(projectPackages, exportedPackagesFromProvidedDeps); + logUnnecessaryPackages(compileJarsPackages, exportedPackagesFromProvidedDeps); - Map<String, Import> calculatedImports = ImportPackages.calculateImports(pluginPackageTally.referencedPackages(), - pluginPackageTally.definedPackages(), ExportPackages.exportsByPackageName(publicPackagesFromProvidedJars.exports)); + Map<String, Import> calculatedImports = calculateImports(includedPackages.referencedPackages(), + includedPackages.definedPackages(), + exportsByPackageName(publicPackagesFromProvidedJars.exports)); Map<String, Optional<String>> manualImports = emptyToNone(importPackage).map(GenerateOsgiManifestMojo::getManualImports) .orElseGet(HashMap::new); @@ -123,17 +135,74 @@ public class GenerateOsgiManifestMojo extends AbstractMojo { calculatedImports.remove(packageName); } createManifestFile(new File(project.getBuild().getOutputDirectory()), manifestContent(project, - artifactSet.getJarArtifactsToInclude(), manualImports, calculatedImports.values(), pluginPackageTally)); + artifactSet.getJarArtifactsToInclude(), manualImports, calculatedImports.values(), includedPackages)); } catch (Exception e) { - throw new MojoExecutionException("Failed generating osgi manifest.", e); + throw new MojoExecutionException("Failed generating osgi manifest", e); + } + } + + private void logDebugPackageSets(AnalyzeBundle.PublicPackages publicPackagesFromProvidedJars, PackageTally includedPackages) { + if (getLog().isDebugEnabled()) { + getLog().debug("Referenced packages = " + includedPackages.referencedPackages()); + getLog().debug("Defined packages = " + includedPackages.definedPackages()); + getLog().debug("Exported packages of dependencies = " + publicPackagesFromProvidedJars.exports.stream() + .map(e -> "(" + e.getPackageNames().toString() + ", " + e.version().orElse("")).collect(Collectors.joining(", "))); + } + } + + private boolean hasJdiscCoreProvided(List<Artifact> providedArtifacts) { + return providedArtifacts.stream().anyMatch(artifact -> artifact.getArtifactId().equals("jdisc_core")); + } + + private void logMissingPackages(Set<String> exportedPackagesFromProvidedJars, + PackageTally projectPackages, + PackageTally compileJarPackages, + PackageTally includedPackages) { + + Set<String> definedAndExportedPackages = Sets.union(includedPackages.definedPackages(), exportedPackagesFromProvidedJars); + + Set<String> missingProjectPackages = projectPackages.referencedPackagesMissingFrom(definedAndExportedPackages); + if (! missingProjectPackages.isEmpty()) { + getLog().warn("Packages unavailable runtime are referenced from project classes " + + "(annotations can usually be ignored): " + missingProjectPackages); + } + + Set<String> missingCompilePackages = compileJarPackages.referencedPackagesMissingFrom(definedAndExportedPackages); + if (! missingCompilePackages.isEmpty()) { + getLog().info("Packages unavailable runtime are referenced from compile scoped jars " + + "(annotations can usually be ignored): " + missingCompilePackages); + } + } + + private void logOverlappingPackages(PackageTally projectPackages, + Set<String> exportedPackagesFromProvidedDeps) { + Set<String> overlappingProjectPackages = Sets.intersection(projectPackages.definedPackages(), exportedPackagesFromProvidedDeps); + if (! overlappingProjectPackages.isEmpty()) { + getLog().warn("Project classes use the following packages that are already defined in provided scoped dependencies: " + + overlappingProjectPackages); + } + } + + /* + * This mostly detects packages re-exported via composite bundles like jdisc_core and container-disc. + * An artifact can only be represented once, either in compile or provided scope. So if the project + * adds an artifact in compile scope that we deploy as a pre-installed bundle, we won't see the same + * artifact as provided via container-dev and hence can't detect the duplicate packages. + */ + private void logUnnecessaryPackages(PackageTally compileJarsPackages, + Set<String> exportedPackagesFromProvidedDeps) { + Set<String> unnecessaryPackages = Sets.intersection(compileJarsPackages.definedPackages(), exportedPackagesFromProvidedDeps); + if (! unnecessaryPackages.isEmpty()) { + getLog().info("Compile scoped jars contain the following packages that are most likely " + + "available from jdisc runtime: " + unnecessaryPackages); } } private static void warnIfPackagesDefinedOverlapsGlobalPackages(Set<String> internalPackages, List<String> globalPackages) throws MojoExecutionException { Set<String> overlap = Sets.intersection(internalPackages, new HashSet<>(globalPackages)); - if (overlap.isEmpty() == false) { + if (! overlap.isEmpty()) { throw new MojoExecutionException( "The following packages are both global and included in the bundle:\n " + String.join("\n ", overlap)); } @@ -173,7 +242,7 @@ public class GenerateOsgiManifestMojo extends AbstractMojo { Pair.of("WebInfUrl", webInfUrl), // Pair.of("Import-Package", importPackage), // Pair.of("Export-Package", exportPackage))) { - if (element.getValue() != null && element.getValue().isEmpty() == false) { + if (element.getValue() != null && ! element.getValue().isEmpty()) { ret.put(element.getKey(), element.getValue()); } } @@ -232,7 +301,7 @@ public class GenerateOsgiManifestMojo extends AbstractMojo { } private void warnOnUnsupportedArtifacts(Collection<Artifact> nonJarArtifacts) { - List<Artifact> unsupportedArtifacts = nonJarArtifacts.stream().filter(a -> "pom".equals(a.getType()) == false) + List<Artifact> unsupportedArtifacts = nonJarArtifacts.stream().filter(a -> ! a.getType().equals("pom")) .collect(Collectors.toList()); unsupportedArtifacts.forEach(artifact -> getLog() @@ -240,7 +309,7 @@ public class GenerateOsgiManifestMojo extends AbstractMojo { artifact.getId(), artifact.getType()))); } - private PackageTally analyzeProjectClasses() { + private PackageTally getProjectClassesTally() { File outputDirectory = new File(project.getBuild().getOutputDirectory()); List<ClassFileMetaData> analyzedClasses = allDescendantFiles(outputDirectory).filter(file -> file.getName().endsWith(".class")) @@ -258,7 +327,7 @@ public class GenerateOsgiManifestMojo extends AbstractMojo { List<ClassFileMetaData> analyzedClasses = new ArrayList<>(); for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements();) { JarEntry entry = entries.nextElement(); - if (entry.isDirectory() == false && entry.getName().endsWith(".class")) { + if (! entry.isDirectory() && entry.getName().endsWith(".class")) { analyzedClasses.add(analyzeClass(jarFile, entry)); } } @@ -305,10 +374,7 @@ public class GenerateOsgiManifestMojo extends AbstractMojo { } private static Optional<String> emptyToNone(String str) { - return Optional.ofNullable(str).map(String::trim).filter(s -> s.isEmpty() == false); + return Optional.ofNullable(str).map(String::trim).filter(s -> ! s.isEmpty()); } - private static boolean isClassToAnalyze(String name) { - return name.endsWith(".class") && name.endsWith("module-info.class") == false; - } } diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/osgi/ImportPackages.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/osgi/ImportPackages.java index b58248ec4a6..a3031cb7ad7 100644 --- a/bundle-plugin/src/main/java/com/yahoo/container/plugin/osgi/ImportPackages.java +++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/osgi/ImportPackages.java @@ -74,8 +74,9 @@ public class ImportPackages { } } - public static Map<String, Import> calculateImports(Set<String> referencedPackages, Set<String> implementedPackages, - Map<String, ExportPackages.Export> exportedPackages) { + public static Map<String, Import> calculateImports(Set<String> referencedPackages, + Set<String> implementedPackages, + Map<String, ExportPackages.Export> exportedPackages) { Map<String, Import> ret = new HashMap<>(); for (String undefinedPackage : Sets.difference(referencedPackages, implementedPackages)) { ExportPackages.Export export = exportedPackages.get(undefinedPackage); diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/util/JdkPackages.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/util/JdkPackages.java new file mode 100644 index 00000000000..0786272bc70 --- /dev/null +++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/util/JdkPackages.java @@ -0,0 +1,39 @@ +package com.yahoo.container.plugin.util; + +import java.net.URL; + +/** + * @author gjoranv + */ +public class JdkPackages { + + /** + * Returns a boolean indicating (via best effort) if the given package is part of the JDK. + */ + public static boolean isJdkPackage(String pkg) { + return hasJdkExclusivePrefix(pkg) + || isResourceInPlatformClassLoader(pkg); // TODO: must be a class, not a package, due to module encapsulation + } + + private static boolean isResourceInPlatformClassLoader(String klass) { + String klassAsPath = klass.replaceAll("\\.", "/") + ".class"; + URL resource = getPlatformClassLoader().getResource(klassAsPath); + return !(resource == null); + } + + private static ClassLoader getPlatformClassLoader() { + ClassLoader platform = JdkPackages.class.getClassLoader().getParent(); + + // Will fail upon changes in classloader hierarchy between JDK versions + assert (platform.getName().equals("platform")); + + return platform; + } + + private static boolean hasJdkExclusivePrefix(String pkg) { + return pkg.startsWith("java.") + || pkg.startsWith("sun."); + } + +} + diff --git a/bundle-plugin/src/test/java/com/yahoo/container/plugin/bundle/AnalyzeBundleTest.java b/bundle-plugin/src/test/java/com/yahoo/container/plugin/bundle/AnalyzeBundleTest.java index 8cccf0598ab..a09604b842b 100644 --- a/bundle-plugin/src/test/java/com/yahoo/container/plugin/bundle/AnalyzeBundleTest.java +++ b/bundle-plugin/src/test/java/com/yahoo/container/plugin/bundle/AnalyzeBundleTest.java @@ -11,8 +11,10 @@ import org.junit.rules.ExpectedException; import java.io.File; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import static com.yahoo.container.plugin.classanalysis.TestUtilities.throwableMessage; import static org.hamcrest.CoreMatchers.containsString; @@ -28,6 +30,7 @@ import static org.junit.Assert.assertThat; */ public class AnalyzeBundleTest { private final List<ExportPackages.Export> exports; + private final Set<String> exportedPackageNames; private final Map<String, ExportPackages.Export> exportsByPackageName; File jarDir = new File("src/test/resources/jar"); @@ -37,6 +40,7 @@ public class AnalyzeBundleTest { File simple = new File(jarDir, "simple1.jar"); PublicPackages pp = AnalyzeBundle.publicPackagesAggregated(Arrays.asList(notOsgi, simple)); this.exports = pp.exports; + this.exportedPackageNames = pp.exportedPackageNames(); this.exportsByPackageName = ExportPackages.exportsByPackageName(exports); } @@ -55,6 +59,11 @@ public class AnalyzeBundleTest { assertThat(exportsByPackageName.keySet(), hasItem("com.yahoo.sample.exported.package")); } + @Test + public void exported_class_names_can_be_retrieved() { + assertThat(exportedPackageNames, is(new HashSet<>(exports.get(0).getPackageNames()))); + } + @Rule public ExpectedException exception = ExpectedException.none(); diff --git a/bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/PackageTallyTest.java b/bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/PackageTallyTest.java new file mode 100644 index 00000000000..e80562c2c13 --- /dev/null +++ b/bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/PackageTallyTest.java @@ -0,0 +1,24 @@ +// Copyright 2019 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.container.plugin.classanalysis; + +import org.junit.Test; + +import java.util.Set; + +import static java.util.Collections.emptyMap; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +/** + * @author gjoranv + */ +public class PackageTallyTest { + + @Test + public void referenced_packages_missing_from_are_detected() { + PackageTally tally = new PackageTally(emptyMap(), Set.of("p1", "java.util", "com.yahoo.api.annotations", "missing")); + Set<String> missingPackages = tally.referencedPackagesMissingFrom(Set.of("p1")); + assertThat(missingPackages, is(Set.of("missing"))); + } + +} diff --git a/bundle-plugin/src/test/java/com/yahoo/container/plugin/osgi/ImportPackageTest.java b/bundle-plugin/src/test/java/com/yahoo/container/plugin/osgi/ImportPackageTest.java index 23960323a31..b76151c790e 100644 --- a/bundle-plugin/src/test/java/com/yahoo/container/plugin/osgi/ImportPackageTest.java +++ b/bundle-plugin/src/test/java/com/yahoo/container/plugin/osgi/ImportPackageTest.java @@ -109,8 +109,9 @@ public class ImportPackageTest { is("com.yahoo.exported;version=\"[1.2.3,2)\"")); } - private static Set<Import> calculateImports(Set<String> referencedPackages, Set<String> implementedPackages, - Map<String, Export> exportedPackages) { + private static Set<Import> calculateImports(Set<String> referencedPackages, + Set<String> implementedPackages, + Map<String, Export> exportedPackages) { return new HashSet<>(ImportPackages.calculateImports(referencedPackages, implementedPackages, exportedPackages).values()); } |