Search in sources :

Example 51 with JarInputStream

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();
    }
}
Also used : JarInputStream(java.util.jar.JarInputStream) FileOutputStream(java.io.FileOutputStream) JarOutputStream(java.util.jar.JarOutputStream) JarEntry(java.util.jar.JarEntry) File(java.io.File) ApplicationBundler(org.apache.twill.internal.ApplicationBundler) FileInputStream(java.io.FileInputStream)

Example 52 with JarInputStream

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);
        }
    };
}
Also used : FilterInputStream(java.io.FilterInputStream) JarInputStream(java.util.jar.JarInputStream) ZipEntry(java.util.zip.ZipEntry) IOException(java.io.IOException) JarFile(java.util.jar.JarFile) JarEntry(java.util.jar.JarEntry) URI(java.net.URI) JarFile(java.util.jar.JarFile) File(java.io.File) InputSupplier(com.google.common.io.InputSupplier)

Example 53 with JarInputStream

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;
}
Also used : JarInputStream(java.util.jar.JarInputStream) BufferedInputStream(java.io.BufferedInputStream) JarFile(java.util.jar.JarFile) Manifest(java.util.jar.Manifest) JarEntry(java.util.jar.JarEntry) JarFile(java.util.jar.JarFile) File(java.io.File) Nullable(javax.annotation.Nullable)

Example 54 with JarInputStream

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;
}
Also used : JarInputStream(java.util.jar.JarInputStream) JarOutputStream(java.util.jar.JarOutputStream) Manifest(java.util.jar.Manifest) JarEntry(java.util.jar.JarEntry) ApplicationBundler(org.apache.twill.internal.ApplicationBundler) File(java.io.File) Location(org.apache.twill.filesystem.Location) HashSet(java.util.HashSet)

Example 55 with JarInputStream

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();
        }
    }
}
Also used : BufferedInputStream(java.io.BufferedInputStream) JarInputStream(java.util.jar.JarInputStream)

Aggregations

JarInputStream (java.util.jar.JarInputStream)185 JarEntry (java.util.jar.JarEntry)82 IOException (java.io.IOException)73 FileInputStream (java.io.FileInputStream)66 Manifest (java.util.jar.Manifest)56 File (java.io.File)48 InputStream (java.io.InputStream)45 ZipEntry (java.util.zip.ZipEntry)34 JarOutputStream (java.util.jar.JarOutputStream)29 Test (org.junit.Test)29 FileOutputStream (java.io.FileOutputStream)26 ByteArrayInputStream (java.io.ByteArrayInputStream)24 URL (java.net.URL)20 ArrayList (java.util.ArrayList)15 ByteArrayOutputStream (java.io.ByteArrayOutputStream)14 OutputStream (java.io.OutputStream)14 JarFile (java.util.jar.JarFile)14 BufferedInputStream (java.io.BufferedInputStream)11 Attributes (java.util.jar.Attributes)11 HashSet (java.util.HashSet)9