/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with this * work for additional information regarding copyright ownership. The ASF * licenses this file to You 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.apache.harmony.archive.tests.java.util.jar; import dalvik.annotation.KnownFailure; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import dalvik.annotation.TestTargetNew; import static tests.support.Support_Exec.execAndGetOutput; import static tests.support.Support_Exec.javaProcessBuilder; import tests.support.resource.Support_Resources; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; /** * * tests for various cases of java -jar ... execution * */ @TestTargetClass(JarOutputStream.class) public class JarExecTest extends junit.framework.TestCase { /** * regression test for HARMONY-1562 issue * */ @TestTargetNew( level = TestLevel.ADDITIONAL, notes = "Regression functional test. Exception checking missed.", method = "putNextEntry", args = {java.util.zip.ZipEntry.class} ) @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).") public void test_1562() throws Exception { // create the manifest Manifest man = new Manifest(); Attributes att = man.getMainAttributes(); att.put(Attributes.Name.MANIFEST_VERSION, "1.0"); att.put(Attributes.Name.MAIN_CLASS, "foo.bar.execjartest.Foo"); File outputJar = File.createTempFile("hyts_", ".jar"); outputJar.deleteOnExit(); JarOutputStream jout = new JarOutputStream(new FileOutputStream( outputJar), man); File resources = Support_Resources.createTempFolder(); for (String jarClass : new String[] {"Foo", "Bar"}) { jout.putNextEntry(new JarEntry("foo/bar/execjartest/" + jarClass + ".class")); jout.write(getResource(resources, "hyts_" + jarClass + ".ser")); } jout.close(); // execute the JAR and read the result ProcessBuilder builder = javaProcessBuilder(); builder.command().add("-jar"); builder.command().add(outputJar.getAbsolutePath()); assertTrue("Error executing JAR", execAndGetOutput(builder).startsWith("FOOBAR")); } /** * tests Class-Path entry in manifest * * @throws Exception in case of troubles */ @TestTargetNew( level = TestLevel.ADDITIONAL, notes = "Functional test.", method = "JarOutputStream", args = {java.io.OutputStream.class, java.util.jar.Manifest.class} ) @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).") public void test_jar_class_path() throws Exception { File fooJar = File.createTempFile("hyts_", ".jar"); File barJar = File.createTempFile("hyts_", ".jar"); fooJar.deleteOnExit(); barJar.deleteOnExit(); // create the manifest Manifest man = new Manifest(); Attributes att = man.getMainAttributes(); att.put(Attributes.Name.MANIFEST_VERSION, "1.0"); att.put(Attributes.Name.MAIN_CLASS, "foo.bar.execjartest.Foo"); att.put(Attributes.Name.CLASS_PATH, barJar.getName()); File resources = Support_Resources.createTempFolder(); JarOutputStream joutFoo = new JarOutputStream(new FileOutputStream( fooJar), man); joutFoo.putNextEntry(new JarEntry("foo/bar/execjartest/Foo.class")); joutFoo.write(getResource(resources, "hyts_Foo.ser")); joutFoo.close(); JarOutputStream joutBar = new JarOutputStream(new FileOutputStream( barJar)); joutBar.putNextEntry(new JarEntry("foo/bar/execjartest/Bar.class")); joutBar.write(getResource(resources, "hyts_Bar.ser")); joutBar.close(); // execute the JAR and read the result ProcessBuilder builder = javaProcessBuilder(); builder.command().add("-jar"); builder.command().add(fooJar.getAbsolutePath()); assertTrue("Error executing JAR", execAndGetOutput(builder).startsWith("FOOBAR")); // rewrite manifest so it contains not only reference to bar but useless // entries as well att.put(Attributes.Name.CLASS_PATH, "xx yy zz " + barJar.getName()); joutFoo = new JarOutputStream(new FileOutputStream(fooJar), man); joutFoo.putNextEntry(new JarEntry("foo/bar/execjartest/Foo.class")); joutFoo.write(getResource(resources, "hyts_Foo.ser")); joutFoo.close(); // execute the JAR and read the result assertTrue("Error executing JAR", execAndGetOutput(builder).startsWith( "FOOBAR")); // play with relative file names - put relative path as ../<parent dir // name>/xx.jar att.put(Attributes.Name.CLASS_PATH, ".." + File.separator + barJar.getParentFile().getName() + File.separator + barJar.getName()); joutFoo = new JarOutputStream(new FileOutputStream(fooJar), man); joutFoo.putNextEntry(new JarEntry("foo/bar/execjartest/Foo.class")); joutFoo.write(getResource(resources, "hyts_Foo.ser")); joutFoo.close(); // execute the JAR and read the result assertTrue("Error executing JAR", execAndGetOutput(builder).startsWith( "FOOBAR")); } /** * tests case when Main-Class is not in the jar launched but in another jar * referenced by Class-Path * * @throws Exception in case of troubles */ @TestTargetNew( level = TestLevel.ADDITIONAL, notes = "Functional test.", method = "JarOutputStream", args = {java.io.OutputStream.class, java.util.jar.Manifest.class} ) @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).") public void test_main_class_in_another_jar() throws Exception { File fooJar = File.createTempFile("hyts_", ".jar"); File barJar = File.createTempFile("hyts_", ".jar"); fooJar.deleteOnExit(); barJar.deleteOnExit(); // create the manifest Manifest man = new Manifest(); Attributes att = man.getMainAttributes(); att.put(Attributes.Name.MANIFEST_VERSION, "1.0"); att.put(Attributes.Name.MAIN_CLASS, "foo.bar.execjartest.Foo"); att.put(Attributes.Name.CLASS_PATH, fooJar.getName()); File resources = Support_Resources.createTempFolder(); JarOutputStream joutFoo = new JarOutputStream(new FileOutputStream( fooJar)); joutFoo.putNextEntry(new JarEntry("foo/bar/execjartest/Foo.class")); joutFoo.write(getResource(resources, "hyts_Foo.ser")); joutFoo.close(); JarOutputStream joutBar = new JarOutputStream(new FileOutputStream( barJar), man); joutBar.putNextEntry(new JarEntry("foo/bar/execjartest/Bar.class")); joutBar.write(getResource(resources, "hyts_Bar.ser")); joutBar.close(); // execute the JAR and read the result ProcessBuilder builder = javaProcessBuilder(); builder.command().add("-jar"); builder.command().add(barJar.getAbsolutePath()); assertTrue("Error executing JAR", execAndGetOutput(builder).startsWith("FOOBAR")); } @TestTargetNew( level = TestLevel.ADDITIONAL, notes = "Functional test.", method = "JarOutputStream", args = {java.io.OutputStream.class, java.util.jar.Manifest.class} ) @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).") public void test_classpath() throws Exception { File resources = Support_Resources.createTempFolder(); File fooJar = File.createTempFile("hyts_", ".jar"); fooJar.deleteOnExit(); JarOutputStream joutFoo = new JarOutputStream(new FileOutputStream( fooJar)); joutFoo.putNextEntry(new JarEntry("foo/bar/execjartest/Foo.class")); joutFoo.write(getResource(resources, "hyts_Foo.ser")); joutFoo.putNextEntry(new JarEntry("foo/bar/execjartest/Bar.class")); joutFoo.write(getResource(resources, "hyts_Bar.ser")); joutFoo.close(); // execute the JAR and read the result ProcessBuilder builder = javaProcessBuilder(); builder.environment().put("CLASSPATH", fooJar.getAbsolutePath()); builder.command().add("foo.bar.execjartest.Foo"); assertTrue("Error executing class from ClassPath", execAndGetOutput(builder).startsWith("FOOBAR")); // ok - next try - add -cp to path - it should override env File booJar = File.createTempFile("hyts_", ".jar"); booJar.deleteOnExit(); JarOutputStream joutBoo = new JarOutputStream(new FileOutputStream( booJar)); joutBoo.putNextEntry(new JarEntry("foo/bar/execjartest/Foo.class")); String booBody = new String(getResource(resources, "hyts_Foo.ser"), "iso-8859-1"); booBody = booBody.replaceFirst("FOO", "BOO"); joutBoo.write(booBody.getBytes("iso-8859-1")); joutBoo.putNextEntry(new JarEntry("foo/bar/execjartest/Bar.class")); String farBody = new String(getResource(resources, "hyts_Bar.ser"), "iso-8859-1"); farBody = farBody.replaceFirst("BAR", "FAR"); joutBoo.write(farBody.getBytes("iso-8859-1")); joutBoo.close(); builder = javaProcessBuilder(); builder.environment().put("CLASSPATH", fooJar.getAbsolutePath()); builder.command().add("-cp"); builder.command().add(booJar.getAbsolutePath()); builder.command().add("foo.bar.execjartest.Foo"); assertTrue("Error executing class specified by -cp", execAndGetOutput(builder).startsWith("BOOFAR")); // now add -jar option - it should override env and classpath Manifest man = new Manifest(); Attributes att = man.getMainAttributes(); att.put(Attributes.Name.MANIFEST_VERSION, "1.0"); att.put(Attributes.Name.MAIN_CLASS, "foo.bar.execjartest.Foo"); File zooJar = File.createTempFile("hyts_", ".jar"); zooJar.deleteOnExit(); JarOutputStream joutZoo = new JarOutputStream(new FileOutputStream( zooJar), man); joutZoo.putNextEntry(new JarEntry("foo/bar/execjartest/Foo.class")); String zooBody = new String(getResource(resources, "hyts_Foo.ser"), "iso-8859-1"); zooBody = zooBody.replaceFirst("FOO", "ZOO"); joutZoo.write(zooBody.getBytes("iso-8859-1")); joutZoo.putNextEntry(new JarEntry("foo/bar/execjartest/Bar.class")); String zarBody = new String(getResource(resources, "hyts_Bar.ser"), "iso-8859-1"); zarBody = zarBody.replaceFirst("BAR", "ZAR"); joutZoo.write(zarBody.getBytes("iso-8859-1")); joutZoo.close(); builder = javaProcessBuilder(); builder.environment().put("CLASSPATH", fooJar.getAbsolutePath()); builder.command().add("-cp"); builder.command().add(booJar.getAbsolutePath()); builder.command().add("-jar"); builder.command().add(zooJar.getAbsolutePath()); assertTrue("Error executing class specified by -jar", execAndGetOutput(builder).startsWith("ZOOZAR")); } private static byte[] getResource(File tempDir, String resourceName) throws IOException { Support_Resources.copyFile(tempDir, null, resourceName); File resourceFile = new File(tempDir, resourceName); resourceFile.deleteOnExit(); // read whole resource data into memory byte[] resourceBody = new byte[(int) resourceFile.length()]; FileInputStream fis = new FileInputStream(resourceFile); fis.read(resourceBody); fis.close(); return resourceBody; } }