1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17package org.apache.harmony.archive.tests.java.util.jar;
18
19import java.io.File;
20import java.io.FileInputStream;
21import java.io.FileOutputStream;
22import java.io.IOException;
23import java.util.jar.Attributes;
24import java.util.jar.JarEntry;
25import java.util.jar.JarOutputStream;
26import java.util.jar.Manifest;
27import java.util.zip.ZipEntry;
28import java.util.zip.ZipOutputStream;
29
30import tests.support.Support_Exec;
31import tests.support.resource.Support_Resources;
32
33/**
34 *
35 * tests for various cases of java -jar ... execution with .zip files as args
36 * some tests are just copy of JarExecTest ones
37 */
38
39public class ZipExecTest extends junit.framework.TestCase {
40	public void test_1562() throws Exception {
41		Manifest man = new Manifest();
42		Attributes att = man.getMainAttributes();
43		att.put(Attributes.Name.MANIFEST_VERSION, "1.0");
44		att.put(Attributes.Name.MAIN_CLASS, "foo.bar.execjartest.Foo");
45
46		File outputZip = File.createTempFile("hyts_", ".zip");
47		outputZip.deleteOnExit();
48		ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(outputZip));
49		File resources = Support_Resources.createTempFolder();
50
51		for (String zipClass : new String[] {"Foo", "Bar"}) {
52			zout.putNextEntry(new ZipEntry("foo/bar/execjartest/" + zipClass + ".class"));
53			zout.write(getResource(resources, "hyts_" + zipClass + ".ser"));
54		}
55
56		zout.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
57		man.write(zout);
58		zout.close();
59
60
61		// set up the VM parameters
62		String[] args = new String[] {"-jar", outputZip.getAbsolutePath()};
63
64	    // execute the JAR and read the result
65		String	res = Support_Exec.execJava(args, null, false);
66
67		assertTrue("Error executing ZIP : result returned was incorrect.", res
68				.startsWith("FOOBAR"));
69	}
70
71	/**
72	 * tests Class-Path entry in manifest
73	 * @throws Exception in case of troubles
74	 */
75	public void test_zip_class_path() throws Exception {
76		File fooZip = File.createTempFile("hyts_", ".zip");
77		File barZip = File.createTempFile("hyts_", ".zip");
78		fooZip.deleteOnExit();
79		barZip.deleteOnExit();
80
81		// create the manifest
82		Manifest man = new Manifest();
83		Attributes att = man.getMainAttributes();
84		att.put(Attributes.Name.MANIFEST_VERSION, "1.0");
85		att.put(Attributes.Name.MAIN_CLASS, "foo.bar.execjartest.Foo");
86		att.put(Attributes.Name.CLASS_PATH, barZip.getName());
87
88		File resources = Support_Resources.createTempFolder();
89
90		ZipOutputStream zoutFoo = new ZipOutputStream(new FileOutputStream(fooZip));
91		zoutFoo.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
92		man.write(zoutFoo);
93		zoutFoo.putNextEntry(new ZipEntry("foo/bar/execjartest/Foo.class"));
94		zoutFoo.write(getResource(resources, "hyts_Foo.ser"));
95		zoutFoo.close();
96
97		ZipOutputStream zoutBar = new ZipOutputStream(new FileOutputStream(barZip));
98		zoutBar.putNextEntry(new ZipEntry("foo/bar/execjartest/Bar.class"));
99		zoutBar.write(getResource(resources, "hyts_Bar.ser"));
100		zoutBar.close();
101
102		String[] args = new String[] {"-jar", fooZip.getAbsolutePath()};
103
104	    // execute the JAR and read the result
105		String	res = Support_Exec.execJava(args, null, false);
106
107		assertTrue("Error executing JAR : result returned was incorrect.", res
108				.startsWith("FOOBAR"));
109
110		//rewrite manifest so it contains not only reference to bar but useless entries as well
111		att.put(Attributes.Name.CLASS_PATH, "xx yy zz " + barZip.getName());
112		zoutFoo = new ZipOutputStream(new FileOutputStream(fooZip));
113		zoutFoo.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
114		man.write(zoutFoo);
115		zoutFoo.putNextEntry(new ZipEntry("foo/bar/execjartest/Foo.class"));
116		zoutFoo.write(getResource(resources, "hyts_Foo.ser"));
117		zoutFoo.close();
118		// execute the JAR and read the result
119		res = Support_Exec.execJava(args, null, false);
120		assertTrue("Error executing JAR : result returned was incorrect.", res
121				.startsWith("FOOBAR"));
122
123
124		//play with relative file names - put relative path as ../<parent dir name>/xx.zip
125		att.put(Attributes.Name.CLASS_PATH, ".." + File.separator + barZip.getParentFile().getName() + File.separator + barZip.getName());
126		zoutFoo = new ZipOutputStream(new FileOutputStream(fooZip));
127		zoutFoo.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
128		man.write(zoutFoo);
129		zoutFoo.putNextEntry(new ZipEntry("foo/bar/execjartest/Foo.class"));
130		zoutFoo.write(getResource(resources, "hyts_Foo.ser"));
131		zoutFoo.close();
132		// execute the ZIP and read the result
133		res = Support_Exec.execJava(args, null, false);
134		assertTrue("Error executing JAR : result returned was incorrect.", res
135				.startsWith("FOOBAR"));
136	}
137
138
139	public void test_zip_jar_mix() throws Exception {
140		File fooJar = File.createTempFile("hyts_", ".jar");
141		File barZip = File.createTempFile("hyts_", ".zip");
142		fooJar.deleteOnExit();
143		barZip.deleteOnExit();
144
145		// create the manifest
146		Manifest man = new Manifest();
147		Attributes att = man.getMainAttributes();
148		att.put(Attributes.Name.MANIFEST_VERSION, "1.0");
149		att.put(Attributes.Name.MAIN_CLASS, "foo.bar.execjartest.Foo");
150		att.put(Attributes.Name.CLASS_PATH, barZip.getName());
151
152		File resources = Support_Resources.createTempFolder();
153
154		JarOutputStream joutFoo = new JarOutputStream(new FileOutputStream(fooJar), man);
155		joutFoo.putNextEntry(new JarEntry("foo/bar/execjartest/Foo.class"));
156		joutFoo.write(getResource(resources, "hyts_Foo.ser"));
157		joutFoo.close();
158
159		ZipOutputStream zoutBar = new ZipOutputStream(new FileOutputStream(barZip));
160		zoutBar.putNextEntry(new ZipEntry("foo/bar/execjartest/Bar.class"));
161		zoutBar.write(getResource(resources, "hyts_Bar.ser"));
162		zoutBar.close();
163
164		String[] args = new String[] {"-jar", fooJar.getAbsolutePath()};
165
166	    // execute the JAR and read the result
167		String	res = Support_Exec.execJava(args, null, false);
168
169		assertTrue("Error executing JAR : result returned was incorrect.", res
170				.startsWith("FOOBAR"));
171	}
172
173	public void test_zip_jar_mix_1() throws Exception {
174		File fooZip = File.createTempFile("hyts_", ".zip");
175		File barJar = File.createTempFile("hyts_", ".jar");
176		fooZip.deleteOnExit();
177		barJar.deleteOnExit();
178
179		// create the manifest
180		Manifest man = new Manifest();
181		Attributes att = man.getMainAttributes();
182		att.put(Attributes.Name.MANIFEST_VERSION, "1.0");
183		att.put(Attributes.Name.MAIN_CLASS, "foo.bar.execjartest.Foo");
184		att.put(Attributes.Name.CLASS_PATH, barJar.getName());
185
186		File resources = Support_Resources.createTempFolder();
187
188		ZipOutputStream zoutFoo = new ZipOutputStream(new FileOutputStream(fooZip));
189		zoutFoo.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
190		man.write(zoutFoo);
191		zoutFoo.putNextEntry(new ZipEntry("foo/bar/execjartest/Foo.class"));
192		zoutFoo.write(getResource(resources, "hyts_Foo.ser"));
193		zoutFoo.close();
194
195		JarOutputStream joutBar = new JarOutputStream(new FileOutputStream(barJar));
196		joutBar.putNextEntry(new ZipEntry("foo/bar/execjartest/Bar.class"));
197		joutBar.write(getResource(resources, "hyts_Bar.ser"));
198		joutBar.close();
199
200		String[] args = new String[] {"-jar", fooZip.getAbsolutePath()};
201
202	    // execute the JAR and read the result
203		String	res = Support_Exec.execJava(args, null, false);
204
205		assertTrue("Error executing ZIP : result returned was incorrect.", res
206				.startsWith("FOOBAR"));
207	}
208
209	/**
210	 * tests case when Main-Class is not in the zip launched but in another zip referenced by Class-Path
211	 * @throws Exception in case of troubles
212	 */
213	public void test_main_class_in_another_zip() throws Exception {
214		File fooZip = File.createTempFile("hyts_", ".zip");
215		File barZip = File.createTempFile("hyts_", ".zip");
216		fooZip.deleteOnExit();
217		barZip.deleteOnExit();
218
219		// create the manifest
220		Manifest man = new Manifest();
221		Attributes att = man.getMainAttributes();
222		att.put(Attributes.Name.MANIFEST_VERSION, "1.0");
223		att.put(Attributes.Name.MAIN_CLASS, "foo.bar.execjartest.Foo");
224		att.put(Attributes.Name.CLASS_PATH, fooZip.getName());
225
226		File resources = Support_Resources.createTempFolder();
227
228		ZipOutputStream zoutFoo = new ZipOutputStream(new FileOutputStream(fooZip));
229		zoutFoo.putNextEntry(new ZipEntry("foo/bar/execjartest/Foo.class"));
230		zoutFoo.write(getResource(resources, "hyts_Foo.ser"));
231		zoutFoo.close();
232
233		ZipOutputStream zoutBar = new ZipOutputStream(new FileOutputStream(barZip));
234		zoutBar.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
235		man.write(zoutBar);
236
237		zoutBar.putNextEntry(new ZipEntry("foo/bar/execjartest/Bar.class"));
238		zoutBar.write(getResource(resources, "hyts_Bar.ser"));
239		zoutBar.close();
240
241		String[] args = new String[] {"-jar", barZip.getAbsolutePath()};
242
243	    // execute the JAR and read the result
244		String	res = Support_Exec.execJava(args, null, false);
245
246		assertTrue("Error executing JAR : result returned was incorrect.", res
247				.startsWith("FOOBAR"));
248	}
249
250
251	private static byte[] getResource(File tempDir, String resourceName) throws IOException {
252		Support_Resources.copyFile(tempDir, null, resourceName);
253		File resourceFile = new File(tempDir, resourceName);
254		resourceFile.deleteOnExit();
255
256		//read whole resource data into memory
257		byte[] resourceBody = new byte[(int) resourceFile.length()];
258		FileInputStream fis = new FileInputStream(resourceFile);
259		fis.read(resourceBody);
260		fis.close();
261
262		return resourceBody;
263	}
264
265}
266