aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgjoranv <gv@verizonmedia.com>2019-07-19 11:25:40 +0200
committerGitHub <noreply@github.com>2019-07-19 11:25:40 +0200
commit4b04f0b6da1c27f7be90e2a87f29aad10d70d5b8 (patch)
tree2c5d1396a3f3d14bcc3701fd428bc13f945e6624
parent65d7e907c52092fa9488f662aa7eded976d4bd2e (diff)
parent3a548ea896592654e8d0ebff204b5ac7f751220a (diff)
Merge pull request #10058 from vespa-engine/gjoranv/bundle-plugin-improvements
Gjoranv/bundle plugin improvements
-rw-r--r--bundle-plugin-test/src/test/java/com/yahoo/BundleIT.java5
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/bundle/AnalyzeBundle.java14
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageTally.java18
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/mojo/Artifacts.java14
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/mojo/GenerateOsgiManifestMojo.java122
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/osgi/ImportPackages.java5
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/util/JdkPackages.java39
-rw-r--r--bundle-plugin/src/test/java/com/yahoo/container/plugin/bundle/AnalyzeBundleTest.java9
-rw-r--r--bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/PackageTallyTest.java24
-rw-r--r--bundle-plugin/src/test/java/com/yahoo/container/plugin/osgi/ImportPackageTest.java5
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());
}