Package org.springframework.boot.loader.jar

Source Code of org.springframework.boot.loader.jar.JarFileTests

/*
* Copyright 2012-2014 the original author or authors.
*
* 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 org.springframework.boot.loader.jar;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.springframework.boot.loader.TestJarCreator;
import org.springframework.boot.loader.data.RandomAccessDataFile;
import org.springframework.boot.loader.util.AsciiBytes;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StreamUtils;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

/**
* Tests for {@link JarFile}.
*
* @author Phillip Webb
* @author Martin Lau
*/
public class JarFileTests {

  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @Rule
  public TemporaryFolder temporaryFolder = new TemporaryFolder();

  private File rootJarFile;

  private JarFile jarFile;

  @Before
  public void setup() throws Exception {
    this.rootJarFile = this.temporaryFolder.newFile();
    TestJarCreator.createTestJar(this.rootJarFile);
    this.jarFile = new JarFile(this.rootJarFile);
  }

  @Test
  public void jdkJarFile() throws Exception {
    // Sanity checks to see how the default jar file operates
    java.util.jar.JarFile jarFile = new java.util.jar.JarFile(this.rootJarFile);
    Enumeration<java.util.jar.JarEntry> entries = jarFile.entries();
    assertThat(entries.nextElement().getName(), equalTo("META-INF/"));
    assertThat(entries.nextElement().getName(), equalTo("META-INF/MANIFEST.MF"));
    assertThat(entries.nextElement().getName(), equalTo("1.dat"));
    assertThat(entries.nextElement().getName(), equalTo("2.dat"));
    assertThat(entries.nextElement().getName(), equalTo("d/"));
    assertThat(entries.nextElement().getName(), equalTo("d/9.dat"));
    assertThat(entries.nextElement().getName(), equalTo("special/"));
    assertThat(entries.nextElement().getName(), equalTo("special/\u00EB.dat"));
    assertThat(entries.nextElement().getName(), equalTo("nested.jar"));
    assertThat(entries.hasMoreElements(), equalTo(false));
    URL jarUrl = new URL("jar:" + this.rootJarFile.toURI() + "!/");
    URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { jarUrl });
    assertThat(urlClassLoader.getResource("special/\u00EB.dat"), notNullValue());
    assertThat(urlClassLoader.getResource("d/9.dat"), notNullValue());
    jarFile.close();
    urlClassLoader.close();
  }

  @Test
  public void createFromFile() throws Exception {
    JarFile jarFile = new JarFile(this.rootJarFile);
    assertThat(jarFile.getName(), notNullValue(String.class));
    jarFile.close();
  }

  @Test
  public void getManifest() throws Exception {
    assertThat(this.jarFile.getManifest().getMainAttributes().getValue("Built-By"),
        equalTo("j1"));
  }

  @Test
  public void getManifestEntry() throws Exception {
    ZipEntry entry = this.jarFile.getJarEntry("META-INF/MANIFEST.MF");
    Manifest manifest = new Manifest(this.jarFile.getInputStream(entry));
    assertThat(manifest.getMainAttributes().getValue("Built-By"), equalTo("j1"));
  }

  @Test
  public void getEntries() throws Exception {
    Enumeration<java.util.jar.JarEntry> entries = this.jarFile.entries();
    assertThat(entries.nextElement().getName(), equalTo("META-INF/"));
    assertThat(entries.nextElement().getName(), equalTo("META-INF/MANIFEST.MF"));
    assertThat(entries.nextElement().getName(), equalTo("1.dat"));
    assertThat(entries.nextElement().getName(), equalTo("2.dat"));
    assertThat(entries.nextElement().getName(), equalTo("d/"));
    assertThat(entries.nextElement().getName(), equalTo("d/9.dat"));
    assertThat(entries.nextElement().getName(), equalTo("special/"));
    assertThat(entries.nextElement().getName(), equalTo("special/\u00EB.dat"));
    assertThat(entries.nextElement().getName(), equalTo("nested.jar"));
    assertThat(entries.hasMoreElements(), equalTo(false));
  }

  @Test
  public void getSpecialResourceViaClassLoader() throws Exception {
    URLClassLoader urlClassLoader = new URLClassLoader(
        new URL[] { this.jarFile.getUrl() });
    assertThat(urlClassLoader.getResource("special/\u00EB.dat"), notNullValue());
    urlClassLoader.close();
  }

  @Test
  public void getJarEntry() throws Exception {
    java.util.jar.JarEntry entry = this.jarFile.getJarEntry("1.dat");
    assertThat(entry, notNullValue(ZipEntry.class));
    assertThat(entry.getName(), equalTo("1.dat"));
  }

  @Test
  public void getInputStream() throws Exception {
    InputStream inputStream = this.jarFile.getInputStream(this.jarFile
        .getEntry("1.dat"));
    assertThat(inputStream.available(), equalTo(1));
    assertThat(inputStream.read(), equalTo(1));
    assertThat(inputStream.available(), equalTo(0));
    assertThat(inputStream.read(), equalTo(-1));
  }

  @Test
  public void getName() throws Exception {
    assertThat(this.jarFile.getName(), equalTo(this.rootJarFile.getPath()));
  }

  @Test
  public void getSize() throws Exception {
    assertThat(this.jarFile.size(), equalTo((int) this.rootJarFile.length()));
  }

  @Test
  public void close() throws Exception {
    RandomAccessDataFile randomAccessDataFile = spy(new RandomAccessDataFile(
        this.rootJarFile, 1));
    JarFile jarFile = new JarFile(randomAccessDataFile);
    jarFile.close();
    verify(randomAccessDataFile).close();
  }

  @Test
  public void getUrl() throws Exception {
    URL url = this.jarFile.getUrl();
    assertThat(url.toString(), equalTo("jar:" + this.rootJarFile.toURI() + "!/"));
    JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
    assertThat(jarURLConnection.getJarFile(), sameInstance(this.jarFile));
    assertThat(jarURLConnection.getJarEntry(), nullValue());
    assertThat(jarURLConnection.getContentLength(), greaterThan(1));
    assertThat(jarURLConnection.getContent(), sameInstance((Object) this.jarFile));
    assertThat(jarURLConnection.getContentType(), equalTo("x-java/jar"));
    assertThat(jarURLConnection.getJarFileURL().toURI(),
        equalTo(this.rootJarFile.toURI()));
  }

  @Test
  public void createEntryUrl() throws Exception {
    URL url = new URL(this.jarFile.getUrl(), "1.dat");
    assertThat(url.toString(), equalTo("jar:" + this.rootJarFile.toURI() + "!/1.dat"));
    JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
    assertThat(jarURLConnection.getJarFile(), sameInstance(this.jarFile));
    assertThat(jarURLConnection.getJarEntry(),
        sameInstance(this.jarFile.getJarEntry("1.dat")));
    assertThat(jarURLConnection.getContentLength(), equalTo(1));
    assertThat(jarURLConnection.getContent(), instanceOf(InputStream.class));
    assertThat(jarURLConnection.getContentType(), equalTo("content/unknown"));
  }

  @Test
  public void getMissingEntryUrl() throws Exception {
    URL url = new URL(this.jarFile.getUrl(), "missing.dat");
    assertThat(url.toString(), equalTo("jar:" + this.rootJarFile.toURI()
        + "!/missing.dat"));
    this.thrown.expect(FileNotFoundException.class);
    ((JarURLConnection) url.openConnection()).getJarEntry();
  }

  @Test
  public void getUrlStream() throws Exception {
    URL url = this.jarFile.getUrl();
    url.openConnection();
    this.thrown.expect(IOException.class);
    url.openStream();
  }

  @Test
  public void getEntryUrlStream() throws Exception {
    URL url = new URL(this.jarFile.getUrl(), "1.dat");
    url.openConnection();
    InputStream stream = url.openStream();
    assertThat(stream.read(), equalTo(1));
    assertThat(stream.read(), equalTo(-1));
  }

  @Test
  public void getNestedJarFile() throws Exception {
    JarFile nestedJarFile = this.jarFile.getNestedJarFile(this.jarFile
        .getEntry("nested.jar"));

    Enumeration<java.util.jar.JarEntry> entries = nestedJarFile.entries();
    assertThat(entries.nextElement().getName(), equalTo("META-INF/"));
    assertThat(entries.nextElement().getName(), equalTo("META-INF/MANIFEST.MF"));
    assertThat(entries.nextElement().getName(), equalTo("3.dat"));
    assertThat(entries.nextElement().getName(), equalTo("4.dat"));
    assertThat(entries.nextElement().getName(), equalTo("\u00E4.dat"));
    assertThat(entries.hasMoreElements(), equalTo(false));

    InputStream inputStream = nestedJarFile.getInputStream(nestedJarFile
        .getEntry("3.dat"));
    assertThat(inputStream.read(), equalTo(3));
    assertThat(inputStream.read(), equalTo(-1));

    URL url = nestedJarFile.getUrl();
    assertThat(url.toString(), equalTo("jar:" + this.rootJarFile.toURI()
        + "!/nested.jar!/"));
    JarURLConnection conn = (JarURLConnection) url.openConnection();
    assertThat(conn.getJarFile(), sameInstance(nestedJarFile));
    assertThat(conn.getJarFileURL().toString(),
        equalTo("jar:" + this.rootJarFile.toURI() + "!/nested.jar"));
  }

  @Test
  public void getNestedJarDirectory() throws Exception {
    JarFile nestedJarFile = this.jarFile
        .getNestedJarFile(this.jarFile.getEntry("d/"));

    Enumeration<java.util.jar.JarEntry> entries = nestedJarFile.entries();
    assertThat(entries.nextElement().getName(), equalTo("9.dat"));
    assertThat(entries.hasMoreElements(), equalTo(false));

    InputStream inputStream = nestedJarFile.getInputStream(nestedJarFile
        .getEntry("9.dat"));
    assertThat(inputStream.read(), equalTo(9));
    assertThat(inputStream.read(), equalTo(-1));

    URL url = nestedJarFile.getUrl();
    assertThat(url.toString(), equalTo("jar:" + this.rootJarFile.toURI() + "!/d!/"));
    assertThat(((JarURLConnection) url.openConnection()).getJarFile(),
        sameInstance(nestedJarFile));
  }

  @Test
  public void getNestJarEntryUrl() throws Exception {
    JarFile nestedJarFile = this.jarFile.getNestedJarFile(this.jarFile
        .getEntry("nested.jar"));
    URL url = nestedJarFile.getJarEntry("3.dat").getUrl();
    assertThat(url.toString(), equalTo("jar:" + this.rootJarFile.toURI()
        + "!/nested.jar!/3.dat"));
    InputStream inputStream = url.openStream();
    assertThat(inputStream, notNullValue());
    assertThat(inputStream.read(), equalTo(3));
  }

  @Test
  public void createUrlFromString() throws Exception {
    JarFile.registerUrlProtocolHandler();
    String spec = "jar:" + this.rootJarFile.toURI() + "!/nested.jar!/3.dat";
    URL url = new URL(spec);
    assertThat(url.toString(), equalTo(spec));
    InputStream inputStream = url.openStream();
    assertThat(inputStream, notNullValue());
    assertThat(inputStream.read(), equalTo(3));
    JarURLConnection connection = (JarURLConnection) url.openConnection();
    assertThat(connection.getURL().toString(), equalTo(spec));
    assertThat(connection.getJarFileURL().toString(), equalTo("jar:"
        + this.rootJarFile.toURI() + "!/nested.jar"));
    assertThat(connection.getEntryName(), equalTo("3.dat"));
  }

  @Test
  public void createNonNestedUrlFromString() throws Exception {
    JarFile.registerUrlProtocolHandler();
    String spec = "jar:" + this.rootJarFile.toURI() + "!/2.dat";
    URL url = new URL(spec);
    assertThat(url.toString(), equalTo(spec));
    InputStream inputStream = url.openStream();
    assertThat(inputStream, notNullValue());
    assertThat(inputStream.read(), equalTo(2));
    JarURLConnection connection = (JarURLConnection) url.openConnection();
    assertThat(connection.getURL().toString(), equalTo(spec));
    assertThat(connection.getJarFileURL().toURI(), equalTo(this.rootJarFile.toURI()));
    assertThat(connection.getEntryName(), equalTo("2.dat"));
  }

  @Test
  public void getDirectoryInputStream() throws Exception {
    InputStream inputStream = this.jarFile
        .getInputStream(this.jarFile.getEntry("d/"));
    assertThat(inputStream, notNullValue());
    assertThat(inputStream.read(), equalTo(-1));
  }

  @Test
  public void getDirectoryInputStreamWithoutSlash() throws Exception {
    InputStream inputStream = this.jarFile.getInputStream(this.jarFile.getEntry("d"));
    assertThat(inputStream, notNullValue());
    assertThat(inputStream.read(), equalTo(-1));
  }

  @Test
  public void getFilteredJarFile() throws Exception {
    JarFile filteredJarFile = this.jarFile.getFilteredJarFile(new JarEntryFilter() {
      @Override
      public AsciiBytes apply(AsciiBytes entryName, JarEntryData entry) {
        if (entryName.toString().equals("1.dat")) {
          return new AsciiBytes("x.dat");
        }
        return null;
      }
    });
    Enumeration<java.util.jar.JarEntry> entries = filteredJarFile.entries();
    assertThat(entries.nextElement().getName(), equalTo("x.dat"));
    assertThat(entries.hasMoreElements(), equalTo(false));

    InputStream inputStream = filteredJarFile.getInputStream(filteredJarFile
        .getEntry("x.dat"));
    assertThat(inputStream.read(), equalTo(1));
    assertThat(inputStream.read(), equalTo(-1));
  }

  @Test
  public void sensibleToString() throws Exception {
    assertThat(this.jarFile.toString(), equalTo(this.rootJarFile.getPath()));
    assertThat(this.jarFile.getNestedJarFile(this.jarFile.getEntry("nested.jar"))
        .toString(), equalTo(this.rootJarFile.getPath() + "!/nested.jar"));
  }

  @Test
  public void verifySignedJar() throws Exception {
    String classpath = System.getProperty("java.class.path");
    String[] entries = classpath.split(System.getProperty("path.separator"));
    String signedJarFile = null;
    for (String entry : entries) {
      if (entry.contains("bcprov")) {
        signedJarFile = entry;
      }
    }
    assertNotNull(signedJarFile);
    java.util.jar.JarFile jarFile = new JarFile(new File(signedJarFile));
    jarFile.getManifest();
    Enumeration<JarEntry> jarEntries = jarFile.entries();
    while (jarEntries.hasMoreElements()) {
      JarEntry jarEntry = jarEntries.nextElement();
      InputStream inputStream = jarFile.getInputStream(jarEntry);
      inputStream.skip(Long.MAX_VALUE);
      inputStream.close();
      if (!jarEntry.getName().startsWith("META-INF") && !jarEntry.isDirectory()
          && !jarEntry.getName().endsWith("TigerDigest.class")) {
        assertNotNull("Missing cert " + jarEntry.getName(),
            jarEntry.getCertificates());
      }
    }
    jarFile.close();
  }

  @Test
  public void jarFileWithScriptAtTheStart() throws Exception {
    File file = this.temporaryFolder.newFile();
    InputStream sourceJarContent = new FileInputStream(this.rootJarFile);
    FileOutputStream outputStream = new FileOutputStream(file);
    StreamUtils.copy("#/bin/bash", Charset.defaultCharset(), outputStream);
    FileCopyUtils.copy(sourceJarContent, outputStream);
    this.rootJarFile = file;
    this.jarFile = new JarFile(file);
    // Call some other tests to verify
    getEntries();
    getNestedJarFile();
  }

  @Test
  public void cannotLoadMissingJar() throws Exception {
    // relates to gh-1070
    JarFile nestedJarFile = this.jarFile.getNestedJarFile(this.jarFile
        .getEntry("nested.jar"));
    URL nestedUrl = nestedJarFile.getUrl();
    URL url = new URL(nestedUrl, nestedJarFile.getUrl() + "missing.jar!/3.dat");
    this.thrown.expect(FileNotFoundException.class);
    url.openConnection().getInputStream();
  }

}
TOP

Related Classes of org.springframework.boot.loader.jar.JarFileTests

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.