1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.io.IOException;
  25 import java.io.BufferedReader;
  26 import java.io.FileReader;
  27 import java.io.FileNotFoundException;
  28 import java.io.IOException;
  29 import com.oracle.java.testlibrary.*;
  30 
  31 
  32 /*
  33  * @test ClassListExerciser
  34  * @summary Exercise loading of classes from the classlist, make sure 
  35  *          no crashes or exceptions occur
  36  * @library /testlibrary 
  37  * @run main/othervm ClassListExerciser createSharedArchive
  38  * @run main/othervm ClassListExerciser $JAVA_HOME/jre/lib/classlist
  39  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=./test.jsa -Xshare:auto ClassListExerciser $JAVA_HOME/jre/lib/classlist 
  40  */
  41 
  42 /* What this class does: 
  43  *     - read the boot classlist
  44  *     - for each class in a classlist: 
  45  *       - load it
  46  *      - instantiate it (if default constructor exists)
  47  */
  48 public class ClassListExerciser {
  49     private final static boolean DIAGNOSTIC_MODE = false;
  50 
  51     public static void main(String[] args) throws Exception {
  52         String firstArg = args[0];
  53         
  54         if (args[0].equals("createSharedArchive")) {
  55             createSharedArchive();
  56         } else {
  57             String classListPath = args[0].replace("$JAVA_HOME", 
  58                                         System.getProperty("test.jdk"));
  59             ClassListExerciser cle = new ClassListExerciser();
  60             ClassLoader classLoader = cle.getClassLoader();
  61             cle.exercise(classListPath, classLoader);
  62         }
  63     }
  64     
  65     private static void createSharedArchive() throws Exception {
  66         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
  67             "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./test.jsa", 
  68             "-Xshare:dump");
  69         OutputAnalyzer output = new OutputAnalyzer(pb.start());
  70         output.shouldContain("Loading classes to share");
  71         output.shouldHaveExitValue(0);
  72     }
  73     
  74     // This method is used to get the class loader for use in this test
  75     // Ideally, the bootstrap class loader should be used. However, it is 
  76     // not accessible via Java API. Using system or application class loader is
  77     // fine in this case, since since by design such class loaders will 
  78     // delegate loading of bootstrap classes to the bootstrap class loader. 
  79     private ClassLoader getClassLoader() {
  80         return ClassLoader.getSystemClassLoader();
  81     }
  82     
  83     private String getClassName(String lineFromClassList) {
  84         return lineFromClassList.split("\\.class")[0].replace('/', '.');
  85     }
  86     
  87     // A filter to skip a given class, which has known problems loading
  88     // Returns true for skipping
  89     private boolean skipClass(String className) {
  90         if ( className.startsWith("sun.awt.X11.XErrorHandler") || 
  91              (className.charAt(0) == '#') ) {
  92             return true;
  93         }
  94 
  95         // java.lang.ClassNotFoundException: javax.swing.text.AbstractDocument$InsertStringResult
  96         // on Windows only        
  97         if (Platform.isWindows() && 
  98             className.equals("javax.swing.text.AbstractDocument$InsertStringResult") ) {
  99             return true;
 100         }
 101 
 102         // java.lang.ClassNotFoundException: java.lang.invoke.MagicLambdaImpl
 103         // on Mac OSX only
 104         if (Platform.isOSX() &&
 105             (className.equals("java.lang.invoke.MagicLambdaImpl") ||
 106              className.equals("sun.lwawt.macosx.LWCToolkit$5")  )    ) {
 107             return true;
 108         }
 109 
 110         return false;
 111     } 
 112     
 113     public void exercise(String classListName, ClassLoader classLoader) 
 114         throws RuntimeException, FileNotFoundException, IOException, 
 115                 ClassNotFoundException {
 116 
 117         BufferedReader reader = new BufferedReader(new FileReader(classListName));
 118         String line = null;
 119         int nrOfLoadedClasses = 0;
 120         
 121         try {
 122             while ((line = reader.readLine()) != null) {
 123                 
 124                 String className = getClassName(line);
 125                 
 126                 if (DIAGNOSTIC_MODE) 
 127                     System.out.println(className);
 128                 
 129                 if (skipClass(className))
 130                     continue;
 131 
 132                 Class<?> c = classLoader.loadClass(className);
 133                 nrOfLoadedClasses++;
 134              }
 135          } finally {
 136             reader.close();
 137          }
 138          
 139          System.out.println("Number of loaded classes is " + nrOfLoadedClasses); 
 140     }
 141     
 142 }