Example usage for java.util.jar Manifest Manifest

List of usage examples for java.util.jar Manifest Manifest

Introduction

In this page you can find the example usage for java.util.jar Manifest Manifest.

Prototype

public Manifest() 

Source Link

Document

Constructs a new, empty Manifest.

Usage

From source file:com.taobao.android.builder.tools.sign.LocalSignedJarBuilder.java

/**
 * Writes a .SF file with a digest to the manifest.
 *///  w  w w  . ja v  a2 s. co m
private void writeSignatureFile(OutputStream out) throws IOException, GeneralSecurityException {
    Manifest sf = new Manifest();
    Attributes main = sf.getMainAttributes();
    main.putValue("Signature-Version", "1.0");
    main.putValue("Created-By", "1.0 (Android)");

    MessageDigest md = MessageDigest.getInstance(DIGEST_ALGORITHM);
    PrintStream print = new PrintStream(new DigestOutputStream(new ByteArrayOutputStream(), md), true,
            SdkConstants.UTF_8);

    // Digest of the entire manifest
    mManifest.write(print);
    print.flush();
    main.putValue(DIGEST_MANIFEST_ATTR, new String(Base64.encode(md.digest()), "ASCII"));

    Map<String, Attributes> entries = mManifest.getEntries();
    for (Map.Entry<String, Attributes> entry : entries.entrySet()) {
        // Digest of the manifest stanza for this entry.
        print.print("Name: " + entry.getKey() + "\r\n");
        for (Map.Entry<Object, Object> att : entry.getValue().entrySet()) {
            print.print(att.getKey() + ": " + att.getValue() + "\r\n");
        }
        print.print("\r\n");
        print.flush();

        Attributes sfAttr = new Attributes();
        sfAttr.putValue(DIGEST_ATTR, new String(Base64.encode(md.digest()), "ASCII"));
        sf.getEntries().put(entry.getKey(), sfAttr);
    }
    CountOutputStream cout = new CountOutputStream(out);
    sf.write(cout);

    // A bug in the java.util.jar implementation of Android platforms
    // up to version 1.6 will cause a spurious IOException to be thrown
    // if the length of the signature file is a multiple of 1024 bytes.
    // As a workaround, add an extra CRLF in this case.
    if ((cout.size() % 1024) == 0) {
        cout.write('\r');
        cout.write('\n');
    }
}

From source file:net.hasor.maven.ExecMojo.java

/**
 * Create a jar with just a manifest containing a Main-Class entry for SurefireBooter and a Class-Path entry for all
 * classpath elements. Copied from surefire (ForkConfiguration#createJar())
 *
 * @param classPath List&lt;String> of all classpath elements.
 * @return//from  w ww  . java  2s. co m
 * @throws IOException
 */
private File createJar(List<String> classPath, String mainClass) throws IOException {
    File file = File.createTempFile("maven-exec", ".jar");
    file.deleteOnExit();
    FileOutputStream fos = new FileOutputStream(file);
    JarOutputStream jos = new JarOutputStream(fos);
    jos.setLevel(JarOutputStream.STORED);
    JarEntry je = new JarEntry("META-INF/MANIFEST.MF");
    jos.putNextEntry(je);
    Manifest man = new Manifest();
    // we can't use StringUtils.join here since we need to add a '/' to
    // the end of directory entries - otherwise the jvm will ignore them.
    StringBuilder cp = new StringBuilder();
    for (String el : classPath) {
        // NOTE: if File points to a directory, this entry MUST end in '/'.
        cp.append(new URL(new File(el).toURI().toASCIIString()).toExternalForm() + " ");
    }
    man.getMainAttributes().putValue("Manifest-Version", "1.0");
    man.getMainAttributes().putValue("Class-Path", cp.toString().trim());
    man.getMainAttributes().putValue("Main-Class", mainClass);
    man.write(jos);
    jos.close();
    return file;
}

From source file:kr.motd.maven.exec.ExecMojo.java

/**
 * Create a jar with just a manifest containing a Main-Class entry for SurefireBooter and a Class-Path entry for all
 * classpath elements. Copied from surefire (ForkConfiguration#createJar())
 *
 * @param classPath List&lt;String> of all classpath elements.
 * @return//from  w w  w.j  av a 2  s  .  c o  m
 * @throws IOException
 */
private File createJar(List<String> classPath, String mainClass) throws IOException {
    File file = File.createTempFile("maven-exec", ".jar");
    file.deleteOnExit();
    FileOutputStream fos = new FileOutputStream(file);
    JarOutputStream jos = new JarOutputStream(fos);
    jos.setLevel(JarOutputStream.STORED);
    JarEntry je = new JarEntry("META-INF/MANIFEST.MF");
    jos.putNextEntry(je);

    Manifest man = new Manifest();

    // we can't use StringUtils.join here since we need to add a '/' to
    // the end of directory entries - otherwise the jvm will ignore them.
    StringBuilder cp = new StringBuilder();
    for (String el : classPath) {
        // NOTE: if File points to a directory, this entry MUST end in '/'.
        cp.append(new URL(new File(el).toURI().toASCIIString()).toExternalForm() + " ");
    }

    man.getMainAttributes().putValue("Manifest-Version", "1.0");
    man.getMainAttributes().putValue("Class-Path", cp.toString().trim());
    man.getMainAttributes().putValue("Main-Class", mainClass);

    man.write(jos);
    jos.close();

    return file;
}

From source file:co.cask.cdap.internal.app.services.http.handlers.ArtifactHttpHandlerTest.java

@Test
public void testGetPlugins() throws Exception {
    // add an app for plugins to extend
    Id.Artifact wordCount1Id = Id.Artifact.from(Id.Namespace.DEFAULT, "wordcount", "1.0.0");
    Assert.assertEquals(HttpResponseStatus.OK.getCode(),
            addAppArtifact(wordCount1Id, WordCountApp.class).getStatusLine().getStatusCode());
    Id.Artifact wordCount2Id = Id.Artifact.from(Id.Namespace.DEFAULT, "wordcount", "2.0.0");
    Assert.assertEquals(HttpResponseStatus.OK.getCode(),
            addAppArtifact(wordCount2Id, WordCountApp.class).getStatusLine().getStatusCode());

    // add some plugins.
    // plugins-1.0.0 extends wordcount[1.0.0,2.0.0)
    Manifest manifest = new Manifest();
    manifest.getMainAttributes().put(ManifestFields.EXPORT_PACKAGE, Plugin1.class.getPackage().getName());
    Id.Artifact pluginsId1 = Id.Artifact.from(Id.Namespace.DEFAULT, "plugins", "1.0.0");
    Set<ArtifactRange> plugins1Parents = Sets.newHashSet(new ArtifactRange(Id.Namespace.DEFAULT, "wordcount",
            new ArtifactVersion("1.0.0"), new ArtifactVersion("2.0.0")));
    Assert.assertEquals(HttpResponseStatus.OK.getCode(),
            addPluginArtifact(pluginsId1, Plugin1.class, manifest, plugins1Parents).getStatusLine()
                    .getStatusCode());/*from   w  w w .j  av a2 s .c  om*/

    // plugin-2.0.0 extends wordcount[1.0.0,3.0.0)
    Id.Artifact pluginsId2 = Id.Artifact.from(Id.Namespace.DEFAULT, "plugins", "2.0.0");
    Set<ArtifactRange> plugins2Parents = Sets.newHashSet(new ArtifactRange(Id.Namespace.DEFAULT, "wordcount",
            new ArtifactVersion("1.0.0"), new ArtifactVersion("3.0.0")));
    Assert.assertEquals(HttpResponseStatus.OK.getCode(),
            addPluginArtifact(pluginsId2, Plugin1.class, manifest, plugins2Parents).getStatusLine()
                    .getStatusCode());

    ArtifactSummary plugins1Artifact = new ArtifactSummary("plugins", "1.0.0");
    ArtifactSummary plugins2Artifact = new ArtifactSummary("plugins", "2.0.0");

    // get plugin types, should be the same for both
    Set<String> expectedTypes = Sets.newHashSet("dummy", "callable");
    Set<String> actualTypes = getPluginTypes(wordCount1Id);
    Assert.assertEquals(expectedTypes, actualTypes);
    actualTypes = getPluginTypes(wordCount2Id);
    Assert.assertEquals(expectedTypes, actualTypes);

    // get plugin summaries. wordcount1 should see plugins from both plugin artifacts
    Set<PluginSummary> expectedSummaries = Sets.newHashSet(
            new PluginSummary("Plugin1", "dummy", "This is plugin1", Plugin1.class.getName(), plugins1Artifact),
            new PluginSummary("Plugin1", "dummy", "This is plugin1", Plugin1.class.getName(),
                    plugins2Artifact));
    Set<PluginSummary> actualSummaries = getPluginSummaries(wordCount1Id, "dummy");
    Assert.assertEquals(expectedSummaries, actualSummaries);

    expectedSummaries = Sets.newHashSet(
            new PluginSummary("Plugin2", "callable", "Just returns the configured integer",
                    Plugin2.class.getName(), plugins1Artifact),
            new PluginSummary("Plugin2", "callable", "Just returns the configured integer",
                    Plugin2.class.getName(), plugins2Artifact));
    actualSummaries = getPluginSummaries(wordCount1Id, "callable");
    Assert.assertEquals(expectedSummaries, actualSummaries);

    // wordcount2 should only see plugins from plugins2 artifact
    expectedSummaries = Sets.newHashSet(new PluginSummary("Plugin1", "dummy", "This is plugin1",
            Plugin1.class.getName(), plugins2Artifact));
    actualSummaries = getPluginSummaries(wordCount2Id, "dummy");
    Assert.assertEquals(expectedSummaries, actualSummaries);

    expectedSummaries = Sets.newHashSet(new PluginSummary("Plugin2", "callable",
            "Just returns the configured integer", Plugin2.class.getName(), plugins2Artifact));
    actualSummaries = getPluginSummaries(wordCount2Id, "callable");
    Assert.assertEquals(expectedSummaries, actualSummaries);

    // get plugin info. Again, wordcount1 should see plugins from both artifacts
    Map<String, PluginPropertyField> p1Properties = ImmutableMap.of("x",
            new PluginPropertyField("x", "", "int", true), "stuff",
            new PluginPropertyField("stuff", "", "string", true));
    Map<String, PluginPropertyField> p2Properties = ImmutableMap.of("v",
            new PluginPropertyField("v", "value to return when called", "int", true));

    Set<PluginInfo> expectedInfos = Sets.newHashSet(
            new PluginInfo("Plugin1", "dummy", "This is plugin1", Plugin1.class.getName(), plugins1Artifact,
                    p1Properties, new HashSet<String>()),
            new PluginInfo("Plugin1", "dummy", "This is plugin1", Plugin1.class.getName(), plugins2Artifact,
                    p1Properties, new HashSet<String>()));
    Assert.assertEquals(expectedInfos, getPluginInfos(wordCount1Id, "dummy", "Plugin1"));

    expectedInfos = Sets.newHashSet(
            new PluginInfo("Plugin2", "callable", "Just returns the configured integer",
                    Plugin2.class.getName(), plugins1Artifact, p2Properties, new HashSet<String>()),
            new PluginInfo("Plugin2", "callable", "Just returns the configured integer",
                    Plugin2.class.getName(), plugins2Artifact, p2Properties, new HashSet<String>()));
    Assert.assertEquals(expectedInfos, getPluginInfos(wordCount1Id, "callable", "Plugin2"));

    // while wordcount2 should only see plugins from plugins2 artifact
    expectedInfos = Sets.newHashSet(new PluginInfo("Plugin1", "dummy", "This is plugin1",
            Plugin1.class.getName(), plugins2Artifact, p1Properties, new HashSet<String>()));
    Assert.assertEquals(expectedInfos, getPluginInfos(wordCount2Id, "dummy", "Plugin1"));

    expectedInfos = Sets.newHashSet(new PluginInfo("Plugin2", "callable", "Just returns the configured integer",
            Plugin2.class.getName(), plugins2Artifact, p2Properties, new HashSet<String>()));
    Assert.assertEquals(expectedInfos, getPluginInfos(wordCount2Id, "callable", "Plugin2"));
}

From source file:org.eclipse.birt.build.mavenrepogen.RepoGen.java

private void createJar(final File jarFile, final File[] files) throws IOException {
    final Manifest manifest = new Manifest();
    final Attributes attributes = manifest.getMainAttributes();
    attributes.putValue("Manifest-Version", "1.0");
    attributes.putValue("Created-By", "RepoGen 1.0.0");
    final FileOutputStream fos = new FileOutputStream(jarFile);
    final JarOutputStream jos = new JarOutputStream(fos, manifest);
    for (final File file : files) {
        final ZipEntry entry = new ZipEntry(file.getName());
        jos.putNextEntry(entry);/* w ww .  java 2s  .  c o m*/
        final FileInputStream fis = new FileInputStream(file);
        pipeStream(fis, jos);
        fis.close();
    }
    jos.close();
}

From source file:co.cask.cdap.internal.app.services.http.AppFabricTestBase.java

protected File buildAppArtifact(Class<?> cls, String name) throws IOException {
    return buildAppArtifact(cls, name, new Manifest());
}

From source file:com.taobao.android.tools.TPatchTool.java

/**
 * create manifest for patch file//  w w  w  . ja va  2s  .  co m
 *
 * @return
 */
private Manifest createManifest() {
    Manifest manifest = new Manifest();
    Attributes main = manifest.getMainAttributes();
    main.putValue("Manifest-Version", "1.0");
    main.putValue("Created-By", "1.0 (DexPatch)");
    main.putValue("Created-Time", new Date(System.currentTimeMillis()).toGMTString());
    return manifest;
}

From source file:test.BuilderTest.java

/**
 * Test where the version comes from: Manifest or packageinfo
 * // w  ww. ja  va2 s.  c  o  m
 * @throws Exception
 */
public static void testExportVersionSource() throws Exception {
    Manifest manifest = new Manifest();
    manifest.getMainAttributes().putValue("Export-Package", "org.osgi.service.event;version=100");

    // Remove packageinfo
    Jar manifestOnly = new Jar(IO.getFile("jar/osgi.jar"));
    try {
        manifestOnly.remove("org/osgi/service/event/packageinfo");
        manifestOnly.setManifest(manifest);

        // Remove manifest
        Jar packageInfoOnly = new Jar(IO.getFile("jar/osgi.jar"));
        packageInfoOnly.setManifest(new Manifest());

        Jar both = new Jar(IO.getFile("jar/osgi.jar"));
        both.setManifest(manifest);

        // Only version in manifest
        Builder bms = new Builder();
        try {
            bms.addClasspath(manifestOnly);
            bms.setProperty("Export-Package", "org.osgi.service.event");
            bms.build();
            assertTrue(bms.check());

            String s = bms.getExports().getByFQN("org.osgi.service.event").get("version");
            assertEquals("100", s);

            // Only version in packageinfo
            Builder bpinfos = new Builder();
            bpinfos.addClasspath(packageInfoOnly);
            bpinfos.setProperty("Export-Package", "org.osgi.service.event");
            bpinfos.build();
            assertTrue(bpinfos.check());

            s = bpinfos.getExports().getByFQN("org.osgi.service.event").get("version");
            assertEquals("1.0.1", s);
        } finally {
            bms.close();
        }
    } finally {
        manifestOnly.close();
    }

}

From source file:com.buaa.cfs.utils.FileUtil.java

/**
 * Create a jar file at the given path, containing a manifest with a classpath that references all specified
 * entries./*from   w  ww.j  a va 2  s  .co  m*/
 * <p>
 * Some platforms may have an upper limit on command line length.  For example, the maximum command line length on
 * Windows is 8191 characters, but the length of the classpath may exceed this.  To work around this limitation, use
 * this method to create a small intermediate jar with a manifest that contains the full classpath.  It returns the
 * absolute path to the new jar, which the caller may set as the classpath for a new process.
 * <p>
 * Environment variable evaluation is not supported within a jar manifest, so this method expands environment
 * variables before inserting classpath entries to the manifest.  The method parses environment variables according
 * to platform-specific syntax (%VAR% on Windows, or $VAR otherwise).  On Windows, environment variables are
 * case-insensitive.  For example, %VAR% and %var% evaluate to the same value.
 * <p>
 * Specifying the classpath in a jar manifest does not support wildcards, so this method expands wildcards
 * internally.  Any classpath entry that ends with * is translated to all files at that path with extension .jar or
 * .JAR.
 *
 * @param inputClassPath String input classpath to bundle into the jar manifest
 * @param pwd            Path to working directory to save jar
 * @param targetDir      path to where the jar execution will have its working dir
 * @param callerEnv      Map<String, String> caller's environment variables to use for expansion
 *
 * @return String[] with absolute path to new jar in position 0 and unexpanded wild card entry path in position 1
 *
 * @throws IOException if there is an I/O error while writing the jar file
 */
public static String[] createJarWithClassPath(String inputClassPath, Path pwd, Path targetDir,
        Map<String, String> callerEnv) throws IOException {
    // Replace environment variables, case-insensitive on Windows
    @SuppressWarnings("unchecked")
    Map<String, String> env = Shell.WINDOWS ? new CaseInsensitiveMap(callerEnv) : callerEnv;
    String[] classPathEntries = inputClassPath.split(File.pathSeparator);
    for (int i = 0; i < classPathEntries.length; ++i) {
        classPathEntries[i] = StringUtils.replaceTokens(classPathEntries[i], StringUtils.ENV_VAR_PATTERN, env);
    }
    File workingDir = new File(pwd.toString());
    if (!workingDir.mkdirs()) {
        // If mkdirs returns false because the working directory already exists,
        // then this is acceptable.  If it returns false due to some other I/O
        // error, then this method will fail later with an IOException while saving
        // the jar.
        LOG.debug("mkdirs false for " + workingDir + ", execution will continue");
    }

    StringBuilder unexpandedWildcardClasspath = new StringBuilder();
    // Append all entries
    List<String> classPathEntryList = new ArrayList<String>(classPathEntries.length);
    for (String classPathEntry : classPathEntries) {
        if (classPathEntry.length() == 0) {
            continue;
        }
        if (classPathEntry.endsWith("*")) {
            boolean foundWildCardJar = false;
            // Append all jars that match the wildcard
            Path globPath = new Path(classPathEntry).suffix("{.jar,.JAR}");
            FileStatus[] wildcardJars = FileContext.getLocalFSFileContext().util().globStatus(globPath);
            if (wildcardJars != null) {
                for (FileStatus wildcardJar : wildcardJars) {
                    foundWildCardJar = true;
                    classPathEntryList.add(wildcardJar.getPath().toUri().toURL().toExternalForm());
                }
            }
            if (!foundWildCardJar) {
                unexpandedWildcardClasspath.append(File.pathSeparator);
                unexpandedWildcardClasspath.append(classPathEntry);
            }
        } else {
            // Append just this entry
            File fileCpEntry = null;
            if (!new Path(classPathEntry).isAbsolute()) {
                fileCpEntry = new File(targetDir.toString(), classPathEntry);
            } else {
                fileCpEntry = new File(classPathEntry);
            }
            String classPathEntryUrl = fileCpEntry.toURI().toURL().toExternalForm();

            // File.toURI only appends trailing '/' if it can determine that it is a
            // directory that already exists.  (See JavaDocs.)  If this entry had a
            // trailing '/' specified by the caller, then guarantee that the
            // classpath entry in the manifest has a trailing '/', and thus refers to
            // a directory instead of a file.  This can happen if the caller is
            // creating a classpath jar referencing a directory that hasn't been
            // created yet, but will definitely be created before running.
            if (classPathEntry.endsWith(Path.SEPARATOR) && !classPathEntryUrl.endsWith(Path.SEPARATOR)) {
                classPathEntryUrl = classPathEntryUrl + Path.SEPARATOR;
            }
            classPathEntryList.add(classPathEntryUrl);
        }
    }
    String jarClassPath = StringUtils.join(" ", classPathEntryList);

    // Create the manifest
    Manifest jarManifest = new Manifest();
    jarManifest.getMainAttributes().putValue(Attributes.Name.MANIFEST_VERSION.toString(), "1.0");
    jarManifest.getMainAttributes().putValue(Attributes.Name.CLASS_PATH.toString(), jarClassPath);

    // Write the manifest to output JAR file
    File classPathJar = File.createTempFile("classpath-", ".jar", workingDir);
    FileOutputStream fos = null;
    BufferedOutputStream bos = null;
    JarOutputStream jos = null;
    try {
        fos = new FileOutputStream(classPathJar);
        bos = new BufferedOutputStream(fos);
        jos = new JarOutputStream(bos, jarManifest);
    } finally {
        IOUtils.cleanup(LOG, jos, bos, fos);
    }
    String[] jarCp = { classPathJar.getCanonicalPath(), unexpandedWildcardClasspath.toString() };
    return jarCp;
}

From source file:test.BuilderTest.java

/**
 * Test where the version comes from: Manifest or packageinfo
 * /*from   w w  w. j a  v a 2  s . co m*/
 * @throws Exception
 */
public static void testImportVersionSource() throws Exception {
    Jar fromManifest = new Jar("manifestsource");
    Jar fromPackageInfo = new Jar("packageinfosource");
    Jar fromBoth = new Jar("both");
    try {
        Manifest mms = new Manifest();
        mms.getMainAttributes().putValue("Export-Package", "org.osgi.service.event; version=100");
        fromManifest.setManifest(mms);

        fromPackageInfo.putResource("org/osgi/service/event/packageinfo",
                new EmbeddedResource("version 99".getBytes(), 0));

        Manifest mboth = new Manifest();
        mboth.getMainAttributes().putValue("Export-Package", "org.osgi.service.event; version=101");
        fromBoth.putResource("org/osgi/service/event/packageinfo",
                new EmbeddedResource("version 199".getBytes(), 0));
        fromBoth.setManifest(mboth);

        // Only version in manifest
        Builder bms = new Builder();
        try {
            bms.addClasspath(fromManifest);
            bms.setProperty("Import-Package", "org.osgi.service.event");
            bms.build();
            assertTrue(bms.check("The JAR is empty"));
            String s = bms.getImports().getByFQN("org.osgi.service.event").get("version");
            assertEquals("[100.0,101)", s);
            // Only version in packageinfo
            Builder bpinfos = new Builder();
            try {
                bpinfos.addClasspath(fromPackageInfo);
                bpinfos.setProperty("Import-Package", "org.osgi.service.event");
                bpinfos.build();
                assertTrue(bms.check());
                s = bpinfos.getImports().getByFQN("org.osgi.service.event").get("version");
                assertEquals("[99.0,100)", s);

                // Version in manifest + packageinfo
                Builder bboth = new Builder();
                try {
                    bboth.addClasspath(fromBoth);
                    bboth.setProperty("Import-Package", "org.osgi.service.event");
                    bboth.build();
                    assertTrue(bms.check());
                    s = bboth.getImports().getByFQN("org.osgi.service.event").get("version");
                    assertEquals("[101.0,102)", s);
                } finally {
                    bboth.close();
                }
            } finally {
                bpinfos.close();
            }
        } finally {
            bms.close();
        }

    } finally {
        fromManifest.close();
        fromPackageInfo.close();
        fromBoth.close();
    }
}