diff options
10 files changed, 198 insertions, 92 deletions
diff --git a/application/src/test/scala/com/yahoo/application/container/jersey/JerseyTest.scala b/application/src/test/scala/com/yahoo/application/container/jersey/JerseyTest.scala index a199c28a4b2..2aee68f254a 100644 --- a/application/src/test/scala/com/yahoo/application/container/jersey/JerseyTest.scala +++ b/application/src/test/scala/com/yahoo/application/container/jersey/JerseyTest.scala @@ -8,8 +8,8 @@ import com.yahoo.application.Networking import com.yahoo.application.container.JDiscTest._ import com.yahoo.container.test.jars.jersey.resources.TestResourceBase import com.yahoo.container.test.jars.jersey.{resources => jarResources} -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping +import com.yahoo.osgi.maven.ProjectBundleClassPaths +import com.yahoo.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping import org.apache.http.HttpResponse import org.apache.http.client.methods.HttpGet import org.apache.http.impl.client.HttpClientBuilder @@ -18,6 +18,7 @@ import org.hamcrest.CoreMatchers.is import org.junit.Assert._ import org.junit.Test +import scala.collection.JavaConverters._ import scala.io.Source /** @@ -51,11 +52,11 @@ class JerseyTest { @Test def jersey_resources_in_provided_dependencies_can_be_invoked_from_application(): Unit = { - val providedDependency = BundleClasspathMapping(bundleSymbolicName, List(testClassesDirectory)) + val providedDependency = new BundleClasspathMapping(bundleSymbolicName, List(testClassesDirectory).asJava) - save(ProjectBundleClassPaths( - mainBundle = BundleClasspathMapping("main", List()), - providedDependencies = List(providedDependency))) + save(new ProjectBundleClassPaths( + new BundleClasspathMapping("main", List().asJava), + List(providedDependency).asJava)) with_jersey_resources() { httpGetter => assertResourcesResponds(classPathResources, httpGetter) @@ -153,12 +154,12 @@ class JerseyTest { } def saveMainBundleClassPathMappings(classPathElement: String): Unit = { - val mainBundleClassPathMappings = BundleClasspathMapping(bundleSymbolicName, List(classPathElement)) - save(ProjectBundleClassPaths(mainBundleClassPathMappings, providedDependencies = List())) + val mainBundleClassPathMappings = new BundleClasspathMapping(bundleSymbolicName, List(classPathElement).asJava) + save(new ProjectBundleClassPaths(mainBundleClassPathMappings, List().asJava)) } def save(projectBundleClassPaths: ProjectBundleClassPaths): Unit = { - val path = Paths.get(testClassesDirectory).resolve(ProjectBundleClassPaths.classPathMappingsFileName) + val path = Paths.get(testClassesDirectory).resolve(ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME) ProjectBundleClassPaths.save(path, projectBundleClassPaths) } diff --git a/bundle-plugin-test/pom.xml b/bundle-plugin-test/pom.xml index ebc60f86b93..2112d616523 100644 --- a/bundle-plugin-test/pom.xml +++ b/bundle-plugin-test/pom.xml @@ -42,16 +42,6 @@ <artifactId>jrt</artifactId> <version>${project.version}</version> </dependency> - <dependency> - <groupId>org.scala-lang</groupId> - <artifactId>scala-library</artifactId> - </dependency> - <dependency> - <groupId>com.yahoo.vespa</groupId> - <artifactId>scalalib</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> </dependencies> <build> <plugins> 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 a7d27a449e6..f088007ebb7 100644 --- a/bundle-plugin-test/src/test/java/com/yahoo/BundleIT.java +++ b/bundle-plugin-test/src/test/java/com/yahoo/BundleIT.java @@ -1,11 +1,10 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo; -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths; +import com.yahoo.osgi.maven.ProjectBundleClassPaths; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import scala.collection.JavaConverters; import java.io.File; import java.io.FilenameFilter; @@ -132,18 +131,17 @@ public class BundleIT { @SuppressWarnings("unchecked") @Test - public void bundle_class_path_mappings_are_generated() throws URISyntaxException { - URL mappingsUrl = getClass().getResource("/" + ProjectBundleClassPaths.classPathMappingsFileName()); + public void bundle_class_path_mappings_are_generated() throws URISyntaxException, IOException { + URL mappingsUrl = getClass().getResource("/" + com.yahoo.osgi.maven.ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME); assertNotNull( - "Could not find " + ProjectBundleClassPaths.classPathMappingsFileName() + " in the test output directory", + "Could not find " + ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME + " in the test output directory", mappingsUrl); ProjectBundleClassPaths bundleClassPaths = ProjectBundleClassPaths.load(Paths.get(mappingsUrl.toURI())); - assertThat(bundleClassPaths.mainBundle().bundleSymbolicName(), is("bundle-plugin-test")); + assertThat(bundleClassPaths.mainBundle.bundleSymbolicName, is("bundle-plugin-test")); - Collection<String> mainBundleClassPaths = - JavaConverters.asJavaCollectionConverter(bundleClassPaths.mainBundle().classPathElements()).asJavaCollection(); + Collection<String> mainBundleClassPaths = bundleClassPaths.mainBundle.classPathElements; assertThat(mainBundleClassPaths, hasItems( diff --git a/bundle-plugin/pom.xml b/bundle-plugin/pom.xml index 31355ff21d2..60facd877ed 100644 --- a/bundle-plugin/pom.xml +++ b/bundle-plugin/pom.xml @@ -74,7 +74,7 @@ </dependency> <dependency> <groupId>com.yahoo.vespa</groupId> - <artifactId>scalalib</artifactId> + <artifactId>vespajlib</artifactId> <version>${project.version}</version> </dependency> <dependency> diff --git a/bundle-plugin/src/main/scala/com/yahoo/container/plugin/mojo/GenerateBundleClassPathMappingsMojo.scala b/bundle-plugin/src/main/scala/com/yahoo/container/plugin/mojo/GenerateBundleClassPathMappingsMojo.scala index cad91e00684..4f463e7b494 100644 --- a/bundle-plugin/src/main/scala/com/yahoo/container/plugin/mojo/GenerateBundleClassPathMappingsMojo.scala +++ b/bundle-plugin/src/main/scala/com/yahoo/container/plugin/mojo/GenerateBundleClassPathMappingsMojo.scala @@ -6,14 +6,15 @@ import java.nio.file.Paths import com.google.common.base.Preconditions import com.yahoo.container.plugin.bundle.AnalyzeBundle -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths -import ProjectBundleClassPaths.BundleClasspathMapping -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths +import com.yahoo.osgi.maven.ProjectBundleClassPaths +import com.yahoo.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping import org.apache.maven.artifact.Artifact import org.apache.maven.plugin.AbstractMojo -import org.apache.maven.plugins.annotations.{ResolutionScope, Mojo, Parameter} +import org.apache.maven.plugins.annotations.{Mojo, Parameter, ResolutionScope} import org.apache.maven.project.MavenProject +import scala.collection.JavaConverters._ + /** @@ -61,13 +62,12 @@ class GenerateBundleClassPathMappingsMojo extends AbstractMojo { val classPathElements = (outputDirectory +: embeddedArtifactsFiles).map(_.getAbsolutePath) - val classPathMappings = ProjectBundleClassPaths( - mainBundle = BundleClasspathMapping(bundleSymbolicName, classPathElements), - providedDependencies = providedJarArtifacts flatMap createDependencyClasspathMapping - ) + val classPathMappings = new ProjectBundleClassPaths( + new BundleClasspathMapping(bundleSymbolicName, classPathElements.asJava), + providedJarArtifacts.flatMap(createDependencyClasspathMapping).asJava) ProjectBundleClassPaths.save( - testOutputPath.resolve(ProjectBundleClassPaths.classPathMappingsFileName), + testOutputPath.resolve(ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME), classPathMappings) } @@ -82,7 +82,7 @@ class GenerateBundleClassPathMappingsMojo extends AbstractMojo { */ def createDependencyClasspathMapping(artifact: Artifact): Option[BundleClasspathMapping] = { for (bundleSymbolicName <- bundleSymbolicNameForArtifact(artifact)) - yield BundleClasspathMapping(bundleSymbolicName, classPathElements = List(artifact.getFile.getAbsolutePath)) + yield new BundleClasspathMapping(bundleSymbolicName, List(artifact.getFile.getAbsolutePath).asJava) } def bundleSymbolicNameForArtifact(artifact: Artifact): Option[String] = { diff --git a/container-di/src/main/scala/com/yahoo/container/di/osgi/OsgiUtil.scala b/container-di/src/main/scala/com/yahoo/container/di/osgi/OsgiUtil.scala index f2120786579..d119f7b0cd4 100644 --- a/container-di/src/main/scala/com/yahoo/container/di/osgi/OsgiUtil.scala +++ b/container-di/src/main/scala/com/yahoo/container/di/osgi/OsgiUtil.scala @@ -10,10 +10,10 @@ import java.util.stream.Collectors import com.google.common.io.Files.fileTreeTraverser import com.yahoo.component.ComponentSpecification import com.yahoo.container.di.Osgi.RelativePath +import com.yahoo.osgi.maven.ProjectBundleClassPaths +import com.yahoo.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping import com.yahoo.vespa.scalalib.arm.Using.using import com.yahoo.vespa.scalalib.java.function.FunctionConverters._ -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths -import com.yahoo.vespa.scalalib.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping import org.osgi.framework.Bundle import org.osgi.framework.wiring.BundleWiring @@ -46,7 +46,7 @@ object OsgiUtil { bundleSpec: ComponentSpecification, packagesToScan: Set[String]) = { classEntriesFrom( - bundleClassPathMapping(bundleSpec, classLoader).classPathElements, + bundleClassPathMapping(bundleSpec, classLoader).classPathElements.asScala.toList, packagesToScan) } @@ -59,7 +59,7 @@ object OsgiUtil { projectBundleClassPaths.mainBundle } else { log.log(Level.WARNING, s"Dependencies of the bundle $bundleSpec will not be scanned. Please file a feature request if you need this" ) - matchingBundleClassPathMapping(bundleSpec, projectBundleClassPaths.providedDependencies) + matchingBundleClassPathMapping(bundleSpec, projectBundleClassPaths.providedDependencies.asScala.toList) } } @@ -71,9 +71,9 @@ object OsgiUtil { } private def loadProjectBundleClassPaths(classLoader: ClassLoader): ProjectBundleClassPaths = { - val classPathMappingsFileLocation = classLoader.getResource(ProjectBundleClassPaths.classPathMappingsFileName) + val classPathMappingsFileLocation = classLoader.getResource(ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME) if (classPathMappingsFileLocation == null) - throw new RuntimeException(s"Couldn't find ${ProjectBundleClassPaths.classPathMappingsFileName} in the class path.") + throw new RuntimeException(s"Couldn't find ${ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME} in the class path.") ProjectBundleClassPaths.load(Paths.get(classPathMappingsFileLocation.toURI)) } diff --git a/scalalib/pom.xml b/scalalib/pom.xml index 78237211ac3..d4556d4648b 100644 --- a/scalalib/pom.xml +++ b/scalalib/pom.xml @@ -29,10 +29,6 @@ <artifactId>annotations</artifactId> <version>${project.version}</version> </dependency> - <dependency> - <groupId>org.json4s</groupId> - <artifactId>json4s-native_${scala.major-version}</artifactId> - </dependency> </dependencies> <build> <plugins> diff --git a/scalalib/src/main/scala/com/yahoo/vespa/scalalib/osgi/maven/ProjectBundleClassPaths.scala b/scalalib/src/main/scala/com/yahoo/vespa/scalalib/osgi/maven/ProjectBundleClassPaths.scala deleted file mode 100644 index 08b8f05b96f..00000000000 --- a/scalalib/src/main/scala/com/yahoo/vespa/scalalib/osgi/maven/ProjectBundleClassPaths.scala +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.scalalib.osgi.maven - -import java.nio.charset.StandardCharsets -import java.nio.file.{Files, Path} - -import org.json4s.NoTypeHints -import org.json4s.native.Serialization - -import ProjectBundleClassPaths._ - -/** - * Represents the bundles in a maven project and the classpath elements - * corresponding to code that would end up in the bundle. - * @author tonytv - */ -case class ProjectBundleClassPaths(mainBundle: BundleClasspathMapping, - providedDependencies: List[BundleClasspathMapping]) - - -object ProjectBundleClassPaths { - //Written by bundle-plugin in the test classes directory. - val classPathMappingsFileName = "bundle-plugin.bundle-classpath-mappings.json" - - case class BundleClasspathMapping(bundleSymbolicName: String, classPathElements: List[String]) - - //Used by Serialization.* methods. See https://github.com/json4s/json4s - private implicit val serializationFormat = Serialization.formats(NoTypeHints) - - def save(path: Path, mappings: ProjectBundleClassPaths) { - Files.createDirectories(path.getParent) - val outputFile = Files.newBufferedWriter(path, StandardCharsets.UTF_8) - try { - Serialization.write(mappings, outputFile) - } finally { - outputFile.close() - } - } - - def load(path: Path): ProjectBundleClassPaths = { - val inputFile = Files.newBufferedReader(path, StandardCharsets.UTF_8) - Serialization.read[ProjectBundleClassPaths](inputFile) - } -} diff --git a/vespajlib/src/main/java/com/yahoo/osgi/maven/ProjectBundleClassPaths.java b/vespajlib/src/main/java/com/yahoo/osgi/maven/ProjectBundleClassPaths.java new file mode 100644 index 00000000000..92ba8b79572 --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/osgi/maven/ProjectBundleClassPaths.java @@ -0,0 +1,130 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.osgi.maven; + +import com.yahoo.slime.Cursor; +import com.yahoo.slime.Inspector; +import com.yahoo.slime.JsonDecoder; +import com.yahoo.slime.JsonFormat; +import com.yahoo.slime.Slime; + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Represents the bundles in a maven project and the classpath elements + * corresponding to code that would end up in the bundle. + * + * @author tonytv + * @author bjorncs + */ + +public class ProjectBundleClassPaths { + public static final String CLASSPATH_MAPPINGS_FILENAME = "bundle-plugin.bundle-classpath-mappings.json"; + + public final BundleClasspathMapping mainBundle; + public final List<BundleClasspathMapping> providedDependencies; + + public ProjectBundleClassPaths(BundleClasspathMapping mainBundle, + List<BundleClasspathMapping> providedDependencies) { + this.mainBundle = mainBundle; + this.providedDependencies = providedDependencies; + } + + public static void save(Path path, ProjectBundleClassPaths mappings) throws IOException { + Files.createDirectories(path.getParent()); + try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(path))) { + save(out, mappings); + } + } + + static void save(OutputStream out, ProjectBundleClassPaths mappings) throws IOException { + Slime slime = new Slime(); + Cursor rootCursor = slime.setObject(); + Cursor mainBundleCursor = rootCursor.setObject("mainBundle"); + BundleClasspathMapping.save(mainBundleCursor, mappings.mainBundle); + Cursor dependenciesCursor = rootCursor.setArray("providedDependencies"); + mappings.providedDependencies + .forEach(d -> BundleClasspathMapping.save(dependenciesCursor.addObject(), d)); + new JsonFormat(false).encode(out, slime); + } + + public static ProjectBundleClassPaths load(Path path) throws IOException { + byte[] bytes = Files.readAllBytes(path); + return load(bytes); + } + + static ProjectBundleClassPaths load(byte[] bytes) { + Slime slime = new Slime(); + new JsonDecoder().decode(slime, bytes); + Inspector inspector = slime.get(); + BundleClasspathMapping mainBundle = BundleClasspathMapping.load(inspector.field("mainBundle")); + Inspector dependenciesInspector = inspector.field("providedDependencies"); + List<BundleClasspathMapping> providedDependencies = new ArrayList<>(); + for (int i = 0; i < dependenciesInspector.entries(); i++) { + providedDependencies.add(BundleClasspathMapping.load(dependenciesInspector.entry(i))); + } + return new ProjectBundleClassPaths(mainBundle, providedDependencies); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ProjectBundleClassPaths that = (ProjectBundleClassPaths) o; + return Objects.equals(mainBundle, that.mainBundle) && + Objects.equals(providedDependencies, that.providedDependencies); + } + + @Override + public int hashCode() { + return Objects.hash(mainBundle, providedDependencies); + } + + public static class BundleClasspathMapping { + public final String bundleSymbolicName; + public final List<String> classPathElements; + + public BundleClasspathMapping(String bundleSymbolicName, + List<String> classPathElements) { + this.bundleSymbolicName = bundleSymbolicName; + this.classPathElements = classPathElements; + } + + static void save(Cursor rootCursor, BundleClasspathMapping mapping) { + rootCursor.setString("bundleSymbolicName", mapping.bundleSymbolicName); + Cursor arrayCursor = rootCursor.setArray("classPathElements"); + mapping.classPathElements.forEach(arrayCursor::addString); + } + + static BundleClasspathMapping load(Inspector inspector) { + String bundleSymoblicName = inspector.field("bundleSymbolicName").asString(); + Inspector elementsInspector = inspector.field("classPathElements"); + List<String> classPathElements = new ArrayList<>(); + for (int i = 0; i < elementsInspector.entries(); i++) { + classPathElements.add(elementsInspector.entry(i).asString()); + } + return new BundleClasspathMapping(bundleSymoblicName, classPathElements); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BundleClasspathMapping that = (BundleClasspathMapping) o; + return Objects.equals(bundleSymbolicName, that.bundleSymbolicName) && + Objects.equals(classPathElements, that.classPathElements); + } + + @Override + public int hashCode() { + return Objects.hash(bundleSymbolicName, classPathElements); + } + } + +} diff --git a/vespajlib/src/test/java/com/yahoo/osgi/maven/ProjectBundleClassPathsTest.java b/vespajlib/src/test/java/com/yahoo/osgi/maven/ProjectBundleClassPathsTest.java new file mode 100644 index 00000000000..9bb66afd876 --- /dev/null +++ b/vespajlib/src/test/java/com/yahoo/osgi/maven/ProjectBundleClassPathsTest.java @@ -0,0 +1,35 @@ +package com.yahoo.osgi.maven; + +import com.yahoo.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; + +/** + * @author bjorncs + */ +public class ProjectBundleClassPathsTest { + + @Test + public void bundle_classpaths_serializes_correctly_to_json() throws IOException { + ProjectBundleClassPaths projectBundleClassPaths = + new ProjectBundleClassPaths( + new BundleClasspathMapping("main-bundle-name", asList("classpath-elem-0-1", "classpath-elem-0-2")), + asList( + new BundleClasspathMapping( + "main-bundle-dep1", + asList("classpath-elem-1-1", "classpath-elem-1-2")), + new BundleClasspathMapping( + "main-bundle-dep2", + asList("classpath-elem-2-1", "classpath-elem-2-2")))); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ProjectBundleClassPaths.save(out, projectBundleClassPaths); + ProjectBundleClassPaths deserialized = ProjectBundleClassPaths.load(out.toByteArray()); + assertEquals(projectBundleClassPaths, deserialized); + } + +} |