1 /*
2  * Copyright (c) 2005, 2017, 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.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package com.sun.management.internal;
26 
27 import java.io.IOException;
28 import java.util.ArrayList;
29 import java.util.List;
30 import javax.management.ObjectName;
31 
32 import com.sun.management.HotSpotDiagnosticMXBean;
33 import com.sun.management.VMOption;
34 import java.security.AccessController;
35 import java.security.PrivilegedAction;
36 import sun.management.Util;
37 
38 /**
39  * Implementation of the diagnostic MBean for Hotspot VM.
40  */
41 public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean {
HotSpotDiagnostic()42     public HotSpotDiagnostic() {
43     }
44 
45     @Override
dumpHeap(String outputFile, boolean live)46     public void dumpHeap(String outputFile, boolean live) throws IOException {
47 
48         String propertyName = "jdk.management.heapdump.allowAnyFileSuffix";
49         PrivilegedAction<Boolean> pa = () -> Boolean.parseBoolean(System.getProperty(propertyName, "false"));
50         boolean allowAnyFileSuffix = AccessController.doPrivileged(pa);
51         if (!allowAnyFileSuffix && !outputFile.endsWith(".hprof")) {
52             throw new IllegalArgumentException("heapdump file must have .hprof extention");
53         }
54 
55         SecurityManager security = System.getSecurityManager();
56         if (security != null) {
57             security.checkWrite(outputFile);
58             Util.checkControlAccess();
59         }
60 
61         dumpHeap0(outputFile, live);
62     }
63 
dumpHeap0(String outputFile, boolean live)64     private native void dumpHeap0(String outputFile, boolean live) throws IOException;
65 
66     @Override
getDiagnosticOptions()67     public List<VMOption> getDiagnosticOptions() {
68         List<Flag> allFlags = Flag.getAllFlags();
69         List<VMOption> result = new ArrayList<>();
70         for (Flag flag : allFlags) {
71             if (flag.isWriteable() && flag.isExternal()) {
72                 result.add(flag.getVMOption());
73             }
74         }
75         return result;
76     }
77 
78     @Override
getVMOption(String name)79     public VMOption getVMOption(String name) {
80         if (name == null) {
81             throw new NullPointerException("name cannot be null");
82         }
83 
84         Flag f = Flag.getFlag(name);
85         if (f == null) {
86             throw new IllegalArgumentException("VM option \"" +
87                 name + "\" does not exist");
88         }
89         return f.getVMOption();
90     }
91 
92     @Override
setVMOption(String name, String value)93     public void setVMOption(String name, String value) {
94         if (name == null) {
95             throw new NullPointerException("name cannot be null");
96         }
97         if (value == null) {
98             throw new NullPointerException("value cannot be null");
99         }
100 
101         Util.checkControlAccess();
102         Flag flag = Flag.getFlag(name);
103         if (flag == null) {
104             throw new IllegalArgumentException("VM option \"" +
105                 name + "\" does not exist");
106         }
107         if (!flag.isWriteable()){
108             throw new IllegalArgumentException("VM Option \"" +
109                 name + "\" is not writeable");
110         }
111 
112         // Check the type of the value
113         Object v = flag.getValue();
114         if (v instanceof Long) {
115             try {
116                 long l = Long.parseLong(value);
117                 Flag.setLongValue(name, l);
118             } catch (NumberFormatException e) {
119                 throw new IllegalArgumentException("Invalid value:" +
120                         " VM Option \"" + name + "\"" +
121                         " expects numeric value", e);
122             }
123         } else if (v instanceof Double) {
124             try {
125                 double d = Double.parseDouble(value);
126                 Flag.setDoubleValue(name, d);
127             } catch (NumberFormatException e) {
128                 throw new IllegalArgumentException("Invalid value:" +
129                         " VM Option \"" + name + "\"" +
130                         " expects numeric value", e);
131             }
132         } else if (v instanceof Boolean) {
133             if (!value.equalsIgnoreCase("true") &&
134                 !value.equalsIgnoreCase("false")) {
135                 throw new IllegalArgumentException("Invalid value:" +
136                     " VM Option \"" + name + "\"" +
137                     " expects \"true\" or \"false\".");
138             }
139             Flag.setBooleanValue(name, Boolean.parseBoolean(value));
140         } else if (v instanceof String) {
141             Flag.setStringValue(name, value);
142         } else {
143             throw new IllegalArgumentException("VM Option \"" +
144                 name + "\" is of an unsupported type: " +
145                 v.getClass().getName());
146         }
147     }
148 
149     @Override
getObjectName()150     public ObjectName getObjectName() {
151         return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic");
152     }
153 }
154