1 /* 2 * Copyright (c) 2002, 2013, 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 25 package sun.jvm.hotspot.tools.jcore; 26 27 import java.io.*; 28 import java.lang.reflect.Constructor; 29 import java.util.jar.JarOutputStream; 30 import java.util.jar.JarEntry; 31 import java.util.jar.Manifest; 32 import sun.jvm.hotspot.memory.*; 33 import sun.jvm.hotspot.oops.*; 34 import sun.jvm.hotspot.debugger.*; 35 import sun.jvm.hotspot.runtime.*; 36 import sun.jvm.hotspot.tools.*; 37 38 public class ClassDump extends Tool { 39 private ClassFilter classFilter; 40 private String outputDirectory; 41 private JarOutputStream jarStream; 42 private String pkgList; 43 44 public ClassDump() { 45 super(); 46 } 47 48 public ClassDump(JVMDebugger d, String pkgList) { 49 super(d); 50 this.pkgList = pkgList; 51 } 52 53 public void setClassFilter(ClassFilter cf) { 54 classFilter = cf; 55 } 56 57 public void setOutputDirectory(String od) { 58 outputDirectory = od; 59 if (jarStream != null) { 60 try { 61 jarStream.close(); 62 } catch (IOException ioe) { 63 ioe.printStackTrace(); 64 } 65 } 66 jarStream = null; 67 } 68 69 public void setJarOutput(String jarFileName) throws IOException { 70 jarStream = new JarOutputStream(new FileOutputStream(jarFileName), new Manifest()); 71 outputDirectory = null; 72 } 73 74 public void run() { 75 // Ready to go with the database... 76 try { 77 if (classFilter == null) { 78 // If not already set, the name of the filter comes from a System property. 79 // If we have a pkgList, pass it, otherwise let the filter read 80 // its own System property for the list of classes. 81 String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter", 82 "sun.jvm.hotspot.tools.jcore.PackageNameFilter"); 83 try { 84 Class filterClass = Class.forName(filterClassName); 85 if (pkgList == null) { 86 classFilter = (ClassFilter) filterClass.newInstance(); 87 } else { 88 Constructor con = filterClass.getConstructor(String.class); 89 classFilter = (ClassFilter) con.newInstance(pkgList); 90 } 91 } catch(Exception exp) { 92 System.err.println("Warning: Can not create class filter!"); 93 } 94 } 95 96 // outputDirectory and jarStream are alternatives: setting one closes the other. 97 // If neither is set, use outputDirectory from the System property: 98 if (outputDirectory == null && jarStream == null) { 99 String dirName = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir", "."); 100 setOutputDirectory(dirName); 101 } 102 103 // walk through the system dictionary 104 SystemDictionary dict = VM.getVM().getSystemDictionary(); 105 dict.classesDo(new SystemDictionary.ClassVisitor() { 106 public void visit(Klass k) { 107 if (k instanceof InstanceKlass) { 108 try { 109 dumpKlass((InstanceKlass) k); 110 } catch (Exception e) { 111 System.out.println(k.getName().asString()); 112 e.printStackTrace(); 113 } 114 } 115 } 116 }); 117 } 118 catch (AddressException e) { 119 System.err.println("Error accessing address 0x" 120 + Long.toHexString(e.getAddress())); 121 e.printStackTrace(); 122 } 123 if (jarStream != null) { 124 try { 125 jarStream.close(); 126 } catch (IOException ioe) { 127 ioe.printStackTrace(); 128 } 129 jarStream = null; 130 } 131 } 132 133 public String getName() { 134 return "jcore"; 135 } 136 137 private void dumpKlass(InstanceKlass kls) { 138 if (classFilter != null && ! classFilter.canInclude(kls) ) { 139 return; 140 } 141 142 String klassName = kls.getName().asString(); 143 klassName = klassName.replace('/', File.separatorChar); 144 try { 145 OutputStream os = null; 146 if (jarStream != null) { 147 jarStream.putNextEntry(new JarEntry(klassName + ".class")); 148 os = jarStream; 149 } else { 150 int index = klassName.lastIndexOf(File.separatorChar); 151 File dir = null; 152 if (index != -1) { 153 String dirName = klassName.substring(0, index); 154 dir = new File(outputDirectory, dirName); 155 } else { 156 dir = new File(outputDirectory); 157 } 158 159 dir.mkdirs(); 160 File f = new File(dir, klassName.substring(index + 1) + ".class"); 161 f.createNewFile(); 162 os = new BufferedOutputStream(new FileOutputStream(f)); 163 } 164 try { 165 ClassWriter cw = new ClassWriter(kls, os); 166 cw.write(); 167 } finally { 168 if (os != jarStream) { 169 os.close(); 170 } 171 } 172 } catch(IOException exp) { 173 exp.printStackTrace(); 174 } 175 } 176 177 public static void main(String[] args) { 178 179 ClassDump cd = new ClassDump(); 180 cd.execute(args); 181 } 182 }