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