use of java.util.jar.JarInputStream in project cdap by caskdata.
the class RemoteDatasetFramework method createDeploymentJar.
private Location createDeploymentJar(Class<?> clz) throws IOException {
File tempDir = new File(cConf.get(Constants.CFG_LOCAL_DATA_DIR), cConf.get(Constants.AppFabric.TEMP_DIR)).getAbsoluteFile();
tempDir.mkdirs();
File tempFile = File.createTempFile(clz.getName(), ".jar", tempDir);
try {
// Create a bundle jar in a temp location
ClassLoader remembered = ClassLoaders.setContextClassLoader(clz.getClassLoader());
try {
ApplicationBundler bundler = new ApplicationBundler(ImmutableList.of("co.cask.cdap.api", "org.apache.hadoop", "org.apache.hbase", "org.apache.hive"));
bundler.createBundle(Locations.toLocation(tempFile), clz);
} finally {
ClassLoaders.setContextClassLoader(remembered);
}
// Create the program jar for deployment. It removes the "classes/" prefix as that's the convention taken
// by the ApplicationBundler inside Twill.
File destination = File.createTempFile(clz.getName(), ".jar", tempDir);
try (JarOutputStream jarOutput = new JarOutputStream(new FileOutputStream(destination));
JarInputStream jarInput = new JarInputStream(new FileInputStream(tempFile))) {
Set<String> seen = Sets.newHashSet();
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);
}
if (seen.add(jarEntry.getName())) {
jarOutput.putNextEntry(jarEntry);
if (!isDir) {
ByteStreams.copy(jarInput, jarOutput);
}
}
}
jarEntry = jarInput.getNextJarEntry();
}
return Locations.toLocation(destination);
}
} finally {
tempFile.delete();
}
}
use of java.util.jar.JarInputStream in project cdap by caskdata.
the class BundleJarUtil method getEntry.
/**
* Returns an {@link InputSupplier} for a given entry. This avoids unjar the whole file to just get one entry.
* However, to get many entries, unjar would be more efficient. Also, the jar file is scanned every time the
* {@link InputSupplier#getInput()} is invoked.
*
* @param jarLocation Location of the jar file.
* @param entryName Name of the entry to fetch
* @return An {@link InputSupplier}.
*/
public static InputSupplier<InputStream> getEntry(final Location jarLocation, final String entryName) throws IOException {
Preconditions.checkArgument(jarLocation != null);
Preconditions.checkArgument(entryName != null);
final URI uri = jarLocation.toURI();
// Small optimization if the location is local
if ("file".equals(uri.getScheme())) {
return new InputSupplier<InputStream>() {
@Override
public InputStream getInput() throws IOException {
final JarFile jarFile = new JarFile(new File(uri));
ZipEntry entry = jarFile.getEntry(entryName);
if (entry == null) {
throw new IOException("Entry not found for " + entryName);
}
return new FilterInputStream(jarFile.getInputStream(entry)) {
@Override
public void close() throws IOException {
try {
super.close();
} finally {
jarFile.close();
}
}
};
}
};
}
// Otherwise, use JarInputStream
return new InputSupplier<InputStream>() {
@Override
public InputStream getInput() throws IOException {
JarInputStream is = new JarInputStream(jarLocation.getInputStream());
JarEntry entry = is.getNextJarEntry();
while (entry != null) {
if (entryName.equals(entry.getName())) {
return is;
}
entry = is.getNextJarEntry();
}
Closeables.closeQuietly(is);
throw new IOException("Entry not found for " + entryName);
}
};
}
use of java.util.jar.JarInputStream in project cdap by caskdata.
the class BundleJarUtil method getManifest.
/**
* Gets the manifest inside the jar located by the given URI.
*
* @param uri Location of the jar file.
* @param inputSupplier a {@link InputSupplier} to provide an {@link InputStream} for the given URI to read the
* jar file content.
* @return The manifest inside the jar file or {@code null} if no manifest inside the jar file.
* @throws IOException if failed to load the manifest.
*/
@Nullable
public static Manifest getManifest(URI uri, InputSupplier<? extends InputStream> inputSupplier) throws IOException {
// Small optimization if the location is local
if ("file".equals(uri.getScheme())) {
try (JarFile jarFile = new JarFile(new File(uri))) {
return jarFile.getManifest();
}
}
// Otherwise, need to search it with JarInputStream
try (JarInputStream is = new JarInputStream(new BufferedInputStream(inputSupplier.getInput()))) {
// This only looks at the first entry, which if is created with jar util, then it'll be there.
Manifest manifest = is.getManifest();
if (manifest != null) {
return manifest;
}
// Otherwise, slow path. Need to goes through the entries
JarEntry jarEntry = is.getNextJarEntry();
while (jarEntry != null) {
if (JarFile.MANIFEST_NAME.equals(jarEntry.getName())) {
return new Manifest(is);
}
jarEntry = is.getNextJarEntry();
}
}
return null;
}
use of java.util.jar.JarInputStream in project cdap by caskdata.
the class AppJarHelper method createDeploymentJar.
public static Location createDeploymentJar(LocationFactory locationFactory, Class<?> clz, Manifest manifest, ClassAcceptor classAcceptor, File... bundleEmbeddedJars) throws IOException {
// Exclude all classes that are visible form the system to the program classloader.
ApplicationBundler bundler = new ApplicationBundler(classAcceptor);
Location jarLocation = locationFactory.create(clz.getName()).getTempFile(".jar");
ClassLoader oldClassLoader = ClassLoaders.setContextClassLoader(clz.getClassLoader());
try {
bundler.createBundle(jarLocation, clz);
} 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");
jarManifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, clz.getName());
// Create the program jar for deployment. It removes the "classes/" prefix as that's the convention taken
// by the ApplicationBundler inside Twill.
Set<String> seenEntries = new HashSet<>();
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);
}
// create a manifest programmatically so it's possible to have a duplicate entry here
if ("META-INF/MANIFEST.MF".equalsIgnoreCase(jarEntry.getName())) {
jarEntry = jarInput.getNextJarEntry();
continue;
}
if (seenEntries.add(jarEntry.getName())) {
jarOutput.putNextEntry(jarEntry);
if (!isDir) {
ByteStreams.copy(jarInput, jarOutput);
}
}
}
jarEntry = jarInput.getNextJarEntry();
}
for (File embeddedJar : bundleEmbeddedJars) {
jarEntry = new JarEntry("lib/" + embeddedJar.getName());
if (seenEntries.add(jarEntry.getName())) {
jarOutput.putNextEntry(jarEntry);
Files.copy(embeddedJar, jarOutput);
}
}
}
return deployJar;
}
use of java.util.jar.JarInputStream in project jdk8u_jdk by JetBrains.
the class UnpackerImpl method unpack.
//Driver routines
// The unpack worker...
/**
* Takes a packed-stream InputStream, and writes to a JarOutputStream. Internally
* the entire buffer must be read, it may be more efficient to read the packed-stream
* to a file and pass the File object, in the alternate method described below.
* <p>
* Closes its input but not its output. (The output can accumulate more elements.)
*
* @param in an InputStream.
* @param out a JarOutputStream.
* @exception IOException if an error is encountered.
*/
public synchronized void unpack(InputStream in, JarOutputStream out) throws IOException {
if (in == null) {
throw new NullPointerException("null input");
}
if (out == null) {
throw new NullPointerException("null output");
}
assert (Utils.currentInstance.get() == null);
boolean needUTC = !props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE);
try {
Utils.currentInstance.set(this);
if (needUTC) {
Utils.changeDefaultTimeZoneToUtc();
}
final int verbose = props.getInteger(Utils.DEBUG_VERBOSE);
BufferedInputStream in0 = new BufferedInputStream(in);
if (Utils.isJarMagic(Utils.readMagic(in0))) {
if (verbose > 0) {
Utils.log.info("Copying unpacked JAR file...");
}
Utils.copyJarFile(new JarInputStream(in0), out);
} else if (props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) {
(new DoUnpack()).run(in0, out);
in0.close();
Utils.markJarFile(out);
} else {
try {
(new NativeUnpack(this)).run(in0, out);
} catch (UnsatisfiedLinkError | NoClassDefFoundError ex) {
// failover to java implementation
(new DoUnpack()).run(in0, out);
}
in0.close();
Utils.markJarFile(out);
}
} finally {
_nunp = null;
Utils.currentInstance.set(null);
if (needUTC) {
Utils.restoreDefaultTimeZone();
}
}
}
Aggregations