Package proguard.io

Class JarWriter

  • All Implemented Interfaces:
    java.lang.AutoCloseable, DataEntryWriter
    Direct Known Subclasses:
    SignedJarWriter

    public class JarWriter
    extends java.lang.Object
    implements DataEntryWriter
    This DataEntryWriter sends data entries to another given data entry writer, automatically adding a manifest file.

    You'll typically wrap a ZipWriter or one of its extensions:

         new JarWriter(new ZipWriter(...))
     
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      protected static class  JarWriter.MyMultiDigestOutputStream
      This FilterOutputStream automatically appends a file digest entry to a given manifest writer, when the stream is closed.
    • Constructor Summary

      Constructors 
      Constructor Description
      JarWriter​(java.lang.String[] digestAlgorithms, java.lang.String creator, java.lang.String manifestFileName, StringFunction manifestEntryNameFunction, DataEntryWriter zipEntryWriter, DataEntryWriter manifestEntryWriter)
      Creates a new JarWriter.
      JarWriter​(java.lang.String[] digestAlgorithms, java.lang.String creator, DataEntryWriter zipEntryWriter)
      Creates a new JarWriter wth default manifest file name "META-INF/MANIFEST.MF".
      JarWriter​(java.lang.String[] digestAlgorithms, DataEntryWriter zipEntryWriter)
      Creates a new JarWriter wth default manifest file name "META-INF/MANIFEST.MF".
      JarWriter​(DataEntryWriter zipEntryWriter)
      Creates a new JarWriter wth default manifest digest "SHA-256" and manifest file name "META-INF/MANIFEST.MF".
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void close()
      Finishes writing all data entries.
      boolean createDirectory​(DataEntry dataEntry)
      Creates a directory.
      protected java.io.OutputStream createManifestOutputStream​(DataEntry manifestEntry)
      Creates an output stream for the specified manifest file.
      java.io.OutputStream createOutputStream​(DataEntry dataEntry)
      Creates a new output stream for writing data.
      protected void finish()
      Writes out the collected manifest file before closing the jar, if any.
      protected void finishIfNecessary​(DataEntry dataEntry)
      Writes out the collected manifest file for the current jar, if we're entering a new jar with this data entry.
      static void main​(java.lang.String[] args)
      Provides a simple test for this class, creating a signed apk file (only v1) with the given name and a few aligned/compressed/uncompressed zip entries.
      protected void openManifestFiles()
      Prepares streams and writers for capturing digests of a parent entry.
      void println​(java.io.PrintWriter pw, java.lang.String prefix)
      Prints out the structure of the data entry writer.
      protected java.io.PrintWriter printWriter​(java.io.OutputStream outputStream)
      Creates a convenience writer.
      boolean sameOutputStream​(DataEntry dataEntry1, DataEntry dataEntry2)
      Returns whether the two given data entries would result in the same output stream.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • DEFAULT_DIGEST_ALGORITHM

        public static final java.lang.String DEFAULT_DIGEST_ALGORITHM
        See Also:
        Constant Field Values
      • digestAlgorithms

        protected final java.lang.String[] digestAlgorithms
      • creator

        protected final java.lang.String creator
      • currentManifestEntry

        protected DataEntry currentManifestEntry
    • Constructor Detail

      • JarWriter

        public JarWriter​(DataEntryWriter zipEntryWriter)
        Creates a new JarWriter wth default manifest digest "SHA-256" and manifest file name "META-INF/MANIFEST.MF".
        Parameters:
        zipEntryWriter - the data entry writer that can provide output streams for the jar entries.
      • JarWriter

        public JarWriter​(java.lang.String[] digestAlgorithms,
                         DataEntryWriter zipEntryWriter)
        Creates a new JarWriter wth default manifest file name "META-INF/MANIFEST.MF".
        Parameters:
        digestAlgorithms - the manifest digest algorithms, e.g. "SHA-256".
        zipEntryWriter - the data entry writer that can provide output streams for the jar entries.
      • JarWriter

        public JarWriter​(java.lang.String[] digestAlgorithms,
                         java.lang.String creator,
                         DataEntryWriter zipEntryWriter)
        Creates a new JarWriter wth default manifest file name "META-INF/MANIFEST.MF".
        Parameters:
        digestAlgorithms - the manifest digest algorithms, e.g. "SHA-256".
        creator - the creator to mention in the manifest file.
        zipEntryWriter - the data entry writer that can provide output streams for the jar entries.
      • JarWriter

        public JarWriter​(java.lang.String[] digestAlgorithms,
                         java.lang.String creator,
                         java.lang.String manifestFileName,
                         StringFunction manifestEntryNameFunction,
                         DataEntryWriter zipEntryWriter,
                         DataEntryWriter manifestEntryWriter)
        Creates a new JarWriter.
        Parameters:
        digestAlgorithms - the manifest digest algorithms, e.g. "SHA-256".
        creator - the creator to mention in the manifest file.
        manifestFileName - the manifest file name, e.g. "META-INF/MANIFEST.MF".
        manifestEntryNameFunction - the function to transform entry names in the manifest (not in the jar).
        zipEntryWriter - the data entry writer that can provide output streams for the jar entries.
        manifestEntryWriter - the data entry writer that can provide an output stream for the manifest file.
    • Method Detail

      • createDirectory

        public boolean createDirectory​(DataEntry dataEntry)
                                throws java.io.IOException
        Description copied from interface: DataEntryWriter
        Creates a directory.
        Specified by:
        createDirectory in interface DataEntryWriter
        Parameters:
        dataEntry - the data entry for which the directory is to be created.
        Returns:
        whether the directory has been created.
        Throws:
        java.io.IOException
      • sameOutputStream

        public boolean sameOutputStream​(DataEntry dataEntry1,
                                        DataEntry dataEntry2)
                                 throws java.io.IOException
        Description copied from interface: DataEntryWriter
        Returns whether the two given data entries would result in the same output stream.
        Specified by:
        sameOutputStream in interface DataEntryWriter
        Parameters:
        dataEntry1 - the first data entry.
        dataEntry2 - the second data entry.
        Throws:
        java.io.IOException
      • createOutputStream

        public java.io.OutputStream createOutputStream​(DataEntry dataEntry)
                                                throws java.io.IOException
        Description copied from interface: DataEntryWriter
        Creates a new output stream for writing data. The caller is responsible for closing the stream.
        Specified by:
        createOutputStream in interface DataEntryWriter
        Parameters:
        dataEntry - the data entry for which the output stream is to be created.
        Returns:
        the output stream. The stream may be null to indicate that the data entry should not be written.
        Throws:
        java.io.IOException
      • close

        public void close()
                   throws java.io.IOException
        Description copied from interface: DataEntryWriter
        Finishes writing all data entries.

        Implementations typically create graphs of writers that can split and merge again, possibly even with cycles.

        For splits and merges, implementations need to be idempotent; once closed, subsequent attempts to close a writer have no effect. If needed, the wrapper NonClosingDataEntryWriter can avoid closing a branch prematurely.

        For cycles, implementations must perform any custom behavior, then delegate DataEntryWriter.close() invocations, and only finally clean up. It is possible that delegates call DataEntryWriter.createOutputStream(DataEntry) while DataEntryWriter.close() is in progress.

        Specified by:
        close in interface java.lang.AutoCloseable
        Specified by:
        close in interface DataEntryWriter
        Throws:
        java.io.IOException
      • println

        public void println​(java.io.PrintWriter pw,
                            java.lang.String prefix)
        Description copied from interface: DataEntryWriter
        Prints out the structure of the data entry writer.
        Specified by:
        println in interface DataEntryWriter
        Parameters:
        pw - the print stream to which the structure should be printed.
        prefix - a prefix for every printed line.
      • openManifestFiles

        protected void openManifestFiles()
                                  throws java.io.IOException
        Prepares streams and writers for capturing digests of a parent entry.
        Throws:
        java.io.IOException
      • createManifestOutputStream

        protected java.io.OutputStream createManifestOutputStream​(DataEntry manifestEntry)
                                                           throws java.io.IOException
        Creates an output stream for the specified manifest file.
        Throws:
        java.io.IOException
      • finishIfNecessary

        protected void finishIfNecessary​(DataEntry dataEntry)
                                  throws java.io.IOException
        Writes out the collected manifest file for the current jar, if we're entering a new jar with this data entry.
        Throws:
        java.io.IOException
      • finish

        protected void finish()
                       throws java.io.IOException
        Writes out the collected manifest file before closing the jar, if any.
        Throws:
        java.io.IOException
      • printWriter

        protected java.io.PrintWriter printWriter​(java.io.OutputStream outputStream)
                                           throws java.io.IOException
        Creates a convenience writer.
        Parameters:
        outputStream - the underlying output stream.
        Throws:
        java.io.IOException
      • main

        public static void main​(java.lang.String[] args)
        Provides a simple test for this class, creating a signed apk file (only v1) with the given name and a few aligned/compressed/uncompressed zip entries. Arguments: jar_filename Verify the jar with: jarsigner -verify -verbose /tmp/test.jar