Home | History | Annotate | Download | only in io
      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  */
     17 
     18 package org.apache.harmony.luni.tests.java.io;
     19 
     20 import java.io.File;
     21 import java.io.FileInputStream;
     22 import java.io.FileNotFoundException;
     23 import java.io.IOException;
     24 import java.lang.reflect.Constructor;
     25 import java.lang.reflect.InvocationTargetException;
     26 import java.util.Vector;
     27 import java.util.zip.ZipEntry;
     28 import java.util.zip.ZipInputStream;
     29 
     30 @SuppressWarnings( { "serial", "unused" })
     31 public class SerializationStressTest5 extends SerializationStressTest {
     32 
     33 	transient Throwable current;
     34 
     35 	// Use this for retrieving a list of any Throwable Classes that did not get
     36 	// tested.
     37 	transient Vector<Class> missedV = new Vector<Class>();
     38 
     39 	transient Class[][] params = new Class[][] { { String.class },
     40 			{ Throwable.class }, { Exception.class },
     41 			{ String.class, Exception.class }, { String.class, int.class },
     42 			{ String.class, String.class, String.class },
     43 			{ String.class, Error.class },
     44 			{ int.class, boolean.class, boolean.class, int.class, int.class },
     45 			{} };
     46 
     47 	transient Object[][] args = new Object[][] {
     48 			{ "message" },
     49 			{ new Throwable() },
     50 			{ new Exception("exception") },
     51 			{ "message", new Exception("exception") },
     52 			{ "message", new Integer(5) },
     53 			{ "message", "message", "message" },
     54 			{ "message", new Error("error") },
     55 			{ new Integer(5), new Boolean(false), new Boolean(false),
     56 					new Integer(5), new Integer(5) }, {} };
     57 
     58 	public SerializationStressTest5(String name) {
     59 		super(name);
     60 	}
     61 
     62 	public void test_writeObject_Throwables() {
     63 		try {
     64 			oos.close();
     65 		} catch (IOException e) {
     66 		}
     67 
     68 		File javaDir = findJavaDir();
     69 
     70 		Vector<File> classFilesVector = new Vector<File>();
     71 		if (javaDir != null)
     72 			findClassFiles(javaDir, classFilesVector);
     73 		else
     74 			findClassFilesFromZip(classFilesVector);
     75 
     76 		if (classFilesVector.size() == 0) {
     77 			fail("No Class Files Found.");
     78 		}
     79 
     80 		File[] classFilesArray = new File[classFilesVector.size()];
     81 		classFilesVector.copyInto(classFilesArray);
     82 
     83 		Class[] throwableClasses = findThrowableClasses(classFilesArray);
     84 		findParam(throwableClasses);
     85 
     86 		// Use this to print out the list of Throwable classes that weren't
     87 		// tested.
     88 		/*
     89 		 * System.out.println(); Class[] temp = new Class[missedV.size()];
     90 		 * missedV.copyInto(temp); for (int i = 0; i < temp.length; i++)
     91 		 * System.out.println(i+1 + ": " + temp[i].getName());
     92 		 */
     93 	}
     94 
     95 	private File[] makeClassPathArray() {
     96 		String classPath;
     97 		if (System.getProperty("java.vendor").startsWith("IBM"))
     98 			classPath = System.getProperty("org.apache.harmony.boot.class.path");
     99 		else
    100 			classPath = System.getProperty("sun.boot.class.path");
    101 		int instanceOfSep = -1;
    102 		int nextInstance = classPath.indexOf(File.pathSeparatorChar,
    103 				instanceOfSep + 1);
    104 		Vector<File> elms = new Vector<File>();
    105 		while (nextInstance != -1) {
    106 			elms.add(new File(classPath.substring(instanceOfSep + 1,
    107 					nextInstance)));
    108 			instanceOfSep = nextInstance;
    109 			nextInstance = classPath.indexOf(File.pathSeparatorChar,
    110 					instanceOfSep + 1);
    111 		}
    112 		elms.add(new File(classPath.substring(instanceOfSep + 1)));
    113 		File[] result = new File[elms.size()];
    114 		elms.copyInto(result);
    115 		return result;
    116 	}
    117 
    118 	private File findJavaDir() {
    119 		File[] files = makeClassPathArray();
    120 		for (int i = 0; i < files.length; i++) {
    121 			if (files[i].isDirectory()) {
    122 				String[] tempFileNames = files[i].list();
    123 				for (int j = 0; j < tempFileNames.length; j++) {
    124 					File tempfile = new File(files[i], tempFileNames[j]);
    125 					if (tempfile.isDirectory()
    126 							&& tempFileNames[j].equals("java")) {
    127 						String[] subdirNames = tempfile.list();
    128 						for (int k = 0; k < subdirNames.length; k++) {
    129 							File subdir = new File(tempfile, subdirNames[k]);
    130 							if (subdir.isDirectory()
    131 									&& subdirNames[k].equals("lang")) {
    132 								return tempfile;
    133 							}
    134 						}
    135 					}
    136 				}
    137 			}
    138 		}
    139 		return null;
    140 	}
    141 
    142 	private void findClassFiles(File dir, Vector<File> v) {
    143 		String[] classFileNames = dir.list();
    144 		for (int i = 0; i < classFileNames.length; i++) {
    145 			File file = new File(dir, classFileNames[i]);
    146 			if (file.isDirectory())
    147 				findClassFiles(file, v);
    148 			else if (classFileNames[i].endsWith(".class"))
    149 				v.add(file);
    150 		}
    151 	}
    152 
    153 	private Class[] findThrowableClasses(File[] files) {
    154 		Class<Throwable> thrClass = Throwable.class;
    155 		Vector<Class> resultVector = new Vector<Class>();
    156 		String slash = System.getProperty("file.separator");
    157 		String begTarget = slash + "java" + slash;
    158 		String endTarget = ".class";
    159 		for (int i = 0; i < files.length; i++) {
    160 			String fileName = files[i].getPath();
    161 			int instOfBegTarget = fileName.indexOf(begTarget);
    162 			int instOfEndTarget = fileName.indexOf(endTarget);
    163 			fileName = fileName.substring(instOfBegTarget + 1, instOfEndTarget);
    164 			fileName = fileName.replace(slash.charAt(0), '.');
    165 			try {
    166 				Class theClass = Class.forName(fileName, false, ClassLoader
    167 						.getSystemClassLoader());
    168 				if (thrClass.isAssignableFrom(theClass)) {
    169 					// java.lang.VirtualMachineError is abstract.
    170 					// java.io.ObjectStreamException is abstract
    171 					// java.beans.PropertyVetoException needs a
    172 					// java.beans.PropertyChangeEvent as a parameter
    173 					if (!fileName.equals("java.lang.VirtualMachineError")
    174 							&& !fileName
    175 									.equals("java.io.ObjectStreamException")
    176 							&& !fileName
    177 									.equals("java.beans.PropertyVetoException"))
    178 						resultVector.add(theClass);
    179 				}
    180 			} catch (ClassNotFoundException e) {
    181 				fail("ClassNotFoundException : " + fileName);
    182 			}
    183 		}
    184 		Class[] result = new Class[resultVector.size()];
    185 		resultVector.copyInto(result);
    186 		return result;
    187 	}
    188 
    189 	private void initClass(Class thrC, int num) {
    190 		Constructor[] cons = thrC.getConstructors();
    191 		for (int i = 0; i < cons.length; i++) {
    192 			try {
    193 				Throwable obj = (Throwable) cons[i].newInstance(args[num]);
    194 				t_Class(obj, num);
    195 				break;
    196 			} catch (IllegalArgumentException e) {
    197 				// This error should be caught until the correct args is hit.
    198 			} catch (IllegalAccessException e) {
    199 				fail(
    200 						"IllegalAccessException while creating instance of: "
    201 								+ thrC.getName());
    202 			} catch (InstantiationException e) {
    203 				fail(
    204 						"InstantiationException while creating instance of: "
    205 								+ thrC.getName());
    206 			} catch (InvocationTargetException e) {
    207 				fail(
    208 						"InvocationTargetException while creating instance of: "
    209 								+ thrC.getName());
    210 			}
    211 			if (i == cons.length - 1) {
    212 				fail(
    213 						"Failed to create newInstance of: " + thrC.getName());
    214 			}
    215 		}
    216 	}
    217 
    218 	public String getDumpName() {
    219 		if (current == null) {
    220 			dumpCount++;
    221 			return getName();
    222 		}
    223 		return getName() + "_" + current.getClass().getName();
    224 	}
    225 
    226 	private void t_Class(Throwable objToSave, int argsNum) {
    227 		current = objToSave;
    228 		Object objLoaded = null;
    229 		try {
    230 			if (DEBUG)
    231 				System.out.println("Obj = " + objToSave);
    232 			try {
    233 				objLoaded = dumpAndReload(objToSave);
    234 			} catch (FileNotFoundException e) {
    235 				// Must be using xload, ignore missing Throwables
    236 				System.out.println("Ignoring: "
    237 						+ objToSave.getClass().getName());
    238 				return;
    239 			}
    240 
    241 			// Has to have worked
    242 			boolean equals;
    243 			equals = objToSave.getClass().equals(objLoaded.getClass());
    244 			assertTrue(MSG_TEST_FAILED + objToSave, equals);
    245 			if (argsNum == 0 || (argsNum >= 3 && argsNum <= 7)) {
    246 				equals = ((Throwable) objToSave).getMessage().equals(
    247 						((Throwable) objLoaded).getMessage());
    248 				assertTrue("Message Test: " + MSG_TEST_FAILED + objToSave,
    249 						equals);
    250 			} else {
    251 				// System.out.println(((Throwable)objToSave).getMessage());
    252 				equals = ((Throwable) objToSave).getMessage() == null;
    253 				assertTrue("Null Test 1: (args=" + argsNum + ") "
    254 						+ MSG_TEST_FAILED + objToSave, equals);
    255 				equals = ((Throwable) objLoaded).getMessage() == null;
    256 				assertTrue("Null Test 2: (args=" + argsNum + ") "
    257 						+ MSG_TEST_FAILED + objToSave, equals);
    258 			}
    259 		} catch (IOException e) {
    260 			fail("Unexpected IOException in checkIt() : " + e.getMessage());
    261 		} catch (ClassNotFoundException e) {
    262 			fail(e.toString() + " - testing " + objToSave.getClass().getName());
    263 		}
    264 	}
    265 
    266 	private void findParam(Class[] thrC) {
    267 		for (int i = 0; i < thrC.length; i++) {
    268 			Constructor con = null;
    269 			for (int j = 0; j < params.length; j++) {
    270 				try {
    271 					con = thrC[i].getConstructor(params[j]);
    272 				} catch (NoSuchMethodException e) {
    273 					// This Error will be caught until the right param is found.
    274 				}
    275 
    276 				if (con != null) {
    277 					// If the param was found, initialize the Class
    278 					initClass(thrC[i], j);
    279 					break;
    280 				}
    281 				// If the param not found then add to missed Vector.
    282 				if (j == params.length - 1)
    283 					missedV.add(thrC[i]);
    284 			}
    285 		}
    286 	}
    287 
    288 	private void findClassFilesFromZip(Vector<File> v) {
    289 		String slash = System.getProperty("file.separator");
    290 		String javaHome = System.getProperty("java.home");
    291 		if (!javaHome.endsWith(slash))
    292 			javaHome += slash;
    293 
    294 		String[] wanted = { "java" + slash + "io", "java" + slash + "lang",
    295 				"java" + slash + "math", "java" + slash + "net",
    296 				"java" + slash + "security", "java" + slash + "text",
    297 				"java" + slash + "util", "java" + slash + "beans",
    298 				"java" + slash + "rmi",
    299 				// One or more class files in awt make the VM hang after being
    300 				// loaded.
    301 				// "java" + slash + "awt",
    302 				"java" + slash + "sql",
    303 		// These are (possibly) all of the throwable classes in awt
    304 		/*
    305 		 * "java\\awt\\AWTError", "java\\awt\\AWTException",
    306 		 * "java\\awt\\color\\CMMException",
    307 		 * "java\\awt\\color\\ProfileDataException",
    308 		 * "java\\awt\\datatransfer\\MimeTypeParseException",
    309 		 * "java\\awt\\datatransfer\\UnsupportedFlavorException",
    310 		 * "java\\awt\\dnd\\InvalidDnDOperationException",
    311 		 * "java\\awt\\FontFormatException",
    312 		 * "java\\awt\\geom\\IllegalPathStateException",
    313 		 * "java\\awt\\geom\\NoninvertibleTransformException",
    314 		 * "java\\awt\\IllegalComponentStateException",
    315 		 * "java\\awt\\image\\ImagingOpException",
    316 		 * "java\\awt\\image\\RasterFormatException",
    317 		 * "java\\awt\\print\\PrinterAbortException",
    318 		 * "java\\awt\\print\\PrinterException",
    319 		 * "java\\awt\\print\\PrinterIOException"
    320 		 */
    321 		};
    322 
    323 		File[] files = makeClassPathArray();
    324 		FileInputStream fis = null;
    325 		ZipInputStream zis = null;
    326 		ZipEntry ze = null;
    327 		for (int i = 0; i < files.length; i++) {
    328 			String fileName = files[i].getPath();
    329 			if (files[i].exists() && files[i].isFile()
    330 					&& fileName.endsWith(".jar") || fileName.endsWith(".zip")) {
    331 				try {
    332 					fis = new FileInputStream(files[i].getPath());
    333 				} catch (FileNotFoundException e) {
    334 					fail("FileNotFoundException trying to open "
    335 							+ files[i].getPath());
    336 				}
    337 				zis = new ZipInputStream(fis);
    338 				while (true) {
    339 					try {
    340 						ze = zis.getNextEntry();
    341 					} catch (IOException e) {
    342 						fail("IOException while getting next zip entry: "
    343 								+ e);
    344 					}
    345 					if (ze == null)
    346 						break;
    347 					String zeName = ze.getName();
    348 					if (zeName.endsWith(".class")) {
    349 						zeName = zeName.replace('/', slash.charAt(0));
    350 						for (int j = 0; j < wanted.length; j++) {
    351 							if (zeName.startsWith(wanted[j])) {
    352 								// When finding class files from directories the
    353 								// program saves them as files.
    354 								// To stay consistent we will turn the ZipEntry
    355 								// classes into instances of files.
    356 								File tempF = new File(javaHome + zeName);
    357 								// Making sure that the same class is not added
    358 								// twice.
    359 								boolean duplicate = false;
    360 								for (int k = 0; k < v.size(); k++) {
    361 									if (v.get(k).equals(tempF))
    362 										duplicate = true;
    363 								}
    364 								if (!duplicate)
    365 									v.add(tempF);
    366 								break;
    367 							}
    368 						}
    369 					}
    370 				}
    371 				;
    372 				try {
    373 					zis.close();
    374 					fis.close();
    375 				} catch (IOException e) {
    376 					fail(
    377 							"IOException while trying to close InputStreams: "
    378 									+ e);
    379 				}
    380 			}
    381 		}
    382 	}
    383 }
    384