
co.cask.cdap.internal.test.PluginJarHelper Maven / Gradle / Ivy
/*
* Copyright © 2015 Cask Data, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package co.cask.cdap.internal.test;
import co.cask.cdap.common.lang.ClassLoaders;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
import org.apache.twill.filesystem.Location;
import org.apache.twill.filesystem.LocationFactory;
import org.apache.twill.internal.ApplicationBundler;
import java.io.IOException;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
/**
* Helper class for building application template plugin jars.
*/
public final class PluginJarHelper {
private PluginJarHelper() {
// No-op
}
public static Location createPluginJar(LocationFactory locationFactory, Manifest manifest,
Class> clz, Class>... classes) throws IOException {
ApplicationBundler bundler = new ApplicationBundler(ImmutableList.of("co.cask.cdap.api",
"org.apache.hadoop",
"org.apache.hive",
"org.apache.spark"),
ImmutableList.of("org.apache.hadoop.hbase"));
Location jarLocation = locationFactory.create(clz.getName()).getTempFile(".jar");
ClassLoader oldClassLoader = ClassLoaders.setContextClassLoader(clz.getClassLoader());
try {
bundler.createBundle(jarLocation, clz, classes);
} finally {
ClassLoaders.setContextClassLoader(oldClassLoader);
}
Location deployJar = locationFactory.create(clz.getName()).getTempFile(".jar");
Manifest jarManifest = new Manifest(manifest);
jarManifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
// Create the program jar for deployment. It removes the "classes/" prefix as that's the convention taken
// by the ApplicationBundler inside Twill.
try (
JarOutputStream jarOutput = new JarOutputStream(deployJar.getOutputStream(), jarManifest);
JarInputStream jarInput = new JarInputStream(jarLocation.getInputStream())
) {
JarEntry jarEntry = jarInput.getNextJarEntry();
while (jarEntry != null) {
boolean isDir = jarEntry.isDirectory();
String entryName = jarEntry.getName();
if (!entryName.equals("classes/")) {
if (entryName.startsWith("classes/")) {
jarEntry = new JarEntry(entryName.substring("classes/".length()));
} else {
jarEntry = new JarEntry(entryName);
}
// TODO: this is due to manifest possibly already existing in the jar, but we also
// create a manifest programatically so it's possible to have a duplicate entry here
if ("META-INF/MANIFEST.MF".equalsIgnoreCase(jarEntry.getName())) {
jarEntry = jarInput.getNextJarEntry();
continue;
}
jarOutput.putNextEntry(jarEntry);
if (!isDir) {
ByteStreams.copy(jarInput, jarOutput);
}
}
jarEntry = jarInput.getNextJarEntry();
}
}
return deployJar;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy