View Javadoc
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 }