Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/management/DiagnosticCommandImpl.java
38827 views
1
/*
2
* Copyright (c) 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. 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
26
package sun.management;
27
28
import com.sun.management.DiagnosticCommandMBean;
29
import java.lang.reflect.Constructor;
30
import java.lang.reflect.InvocationTargetException;
31
import java.security.Permission;
32
import java.util.*;
33
import javax.management.*;
34
35
/**
36
* Implementation class for the diagnostic commands subsystem.
37
*
38
* @since 8
39
*/
40
class DiagnosticCommandImpl extends NotificationEmitterSupport
41
implements DiagnosticCommandMBean {
42
43
private final VMManagement jvm;
44
private volatile Map<String, Wrapper> wrappers = null;
45
private static final String strClassName = "".getClass().getName();
46
private static final String strArrayClassName = String[].class.getName();
47
private final boolean isSupported;
48
49
@Override
50
public Object getAttribute(String attribute) throws AttributeNotFoundException,
51
MBeanException, ReflectionException {
52
throw new AttributeNotFoundException(attribute);
53
}
54
55
@Override
56
public void setAttribute(Attribute attribute) throws AttributeNotFoundException,
57
InvalidAttributeValueException, MBeanException, ReflectionException {
58
throw new AttributeNotFoundException(attribute.getName());
59
}
60
61
@Override
62
public AttributeList getAttributes(String[] attributes) {
63
return new AttributeList();
64
}
65
66
@Override
67
public AttributeList setAttributes(AttributeList attributes) {
68
return new AttributeList();
69
}
70
71
private class Wrapper {
72
73
String name;
74
String cmd;
75
DiagnosticCommandInfo info;
76
Permission permission;
77
78
Wrapper(String name, String cmd, DiagnosticCommandInfo info)
79
throws InstantiationException {
80
this.name = name;
81
this.cmd = cmd;
82
this.info = info;
83
this.permission = null;
84
Exception cause = null;
85
if (info.getPermissionClass() != null) {
86
try {
87
Class c = Class.forName(info.getPermissionClass());
88
if (info.getPermissionAction() == null) {
89
try {
90
Constructor constructor = c.getConstructor(String.class);
91
permission = (Permission) constructor.newInstance(info.getPermissionName());
92
93
} catch (InstantiationException | IllegalAccessException
94
| IllegalArgumentException | InvocationTargetException
95
| NoSuchMethodException | SecurityException ex) {
96
cause = ex;
97
}
98
}
99
if (permission == null) {
100
try {
101
Constructor constructor = c.getConstructor(String.class, String.class);
102
permission = (Permission) constructor.newInstance(
103
info.getPermissionName(),
104
info.getPermissionAction());
105
} catch (InstantiationException | IllegalAccessException
106
| IllegalArgumentException | InvocationTargetException
107
| NoSuchMethodException | SecurityException ex) {
108
cause = ex;
109
}
110
}
111
} catch (ClassNotFoundException ex) { }
112
if (permission == null) {
113
InstantiationException iex =
114
new InstantiationException("Unable to instantiate required permission");
115
iex.initCause(cause);
116
}
117
}
118
}
119
120
public String execute(String[] args) {
121
if (permission != null) {
122
SecurityManager sm = System.getSecurityManager();
123
if (sm != null) {
124
sm.checkPermission(permission);
125
}
126
}
127
if(args == null) {
128
return executeDiagnosticCommand(cmd);
129
} else {
130
StringBuilder sb = new StringBuilder();
131
sb.append(cmd);
132
for(int i=0; i<args.length; i++) {
133
if(args[i] == null) {
134
throw new IllegalArgumentException("Invalid null argument");
135
}
136
sb.append(" ");
137
sb.append(args[i]);
138
}
139
return executeDiagnosticCommand(sb.toString());
140
}
141
}
142
}
143
144
DiagnosticCommandImpl(VMManagement jvm) {
145
this.jvm = jvm;
146
isSupported = jvm.isRemoteDiagnosticCommandsSupported();
147
}
148
149
private static class OperationInfoComparator implements Comparator<MBeanOperationInfo> {
150
@Override
151
public int compare(MBeanOperationInfo o1, MBeanOperationInfo o2) {
152
return o1.getName().compareTo(o2.getName());
153
}
154
}
155
156
@Override
157
public MBeanInfo getMBeanInfo() {
158
SortedSet<MBeanOperationInfo> operations = new TreeSet<>(new OperationInfoComparator());
159
Map<String, Wrapper> wrappersmap;
160
if (!isSupported) {
161
wrappersmap = (Map<String, Wrapper>) Collections.EMPTY_MAP;
162
} else {
163
try {
164
String[] command = getDiagnosticCommands();
165
DiagnosticCommandInfo[] info = getDiagnosticCommandInfo(command);
166
MBeanParameterInfo stringArgInfo[] = new MBeanParameterInfo[]{
167
new MBeanParameterInfo("arguments", strArrayClassName,
168
"Array of Diagnostic Commands Arguments and Options")
169
};
170
wrappersmap = new HashMap<>();
171
for (int i = 0; i < command.length; i++) {
172
String name = transform(command[i]);
173
try {
174
Wrapper w = new Wrapper(name, command[i], info[i]);
175
wrappersmap.put(name, w);
176
operations.add(new MBeanOperationInfo(
177
w.name,
178
w.info.getDescription(),
179
(w.info.getArgumentsInfo() == null
180
|| w.info.getArgumentsInfo().isEmpty())
181
? null : stringArgInfo,
182
strClassName,
183
MBeanOperationInfo.ACTION_INFO,
184
commandDescriptor(w)));
185
} catch (InstantiationException ex) {
186
// If for some reasons the creation of a diagnostic command
187
// wrappers fails, the diagnostic command is just ignored
188
// and won't appear in the DynamicMBean
189
}
190
}
191
} catch (IllegalArgumentException | UnsupportedOperationException e) {
192
wrappersmap = (Map<String, Wrapper>) Collections.EMPTY_MAP;
193
}
194
}
195
wrappers = Collections.unmodifiableMap(wrappersmap);
196
HashMap<String, Object> map = new HashMap<>();
197
map.put("immutableInfo", "false");
198
map.put("interfaceClassName","com.sun.management.DiagnosticCommandMBean");
199
map.put("mxbean", "false");
200
Descriptor desc = new ImmutableDescriptor(map);
201
return new MBeanInfo(
202
this.getClass().getName(),
203
"Diagnostic Commands",
204
null, // attributes
205
null, // constructors
206
operations.toArray(new MBeanOperationInfo[operations.size()]), // operations
207
getNotificationInfo(), // notifications
208
desc);
209
}
210
211
@Override
212
public Object invoke(String actionName, Object[] params, String[] signature)
213
throws MBeanException, ReflectionException {
214
if (!isSupported) {
215
throw new UnsupportedOperationException();
216
}
217
if (wrappers == null) {
218
getMBeanInfo();
219
}
220
Wrapper w = wrappers.get(actionName);
221
if (w != null) {
222
if (w.info.getArgumentsInfo().isEmpty()
223
&& (params == null || params.length == 0)
224
&& (signature == null || signature.length == 0)) {
225
return w.execute(null);
226
} else if((params != null && params.length == 1)
227
&& (signature != null && signature.length == 1
228
&& signature[0] != null
229
&& signature[0].compareTo(strArrayClassName) == 0)) {
230
return w.execute((String[]) params[0]);
231
}
232
}
233
throw new ReflectionException(new NoSuchMethodException(actionName));
234
}
235
236
private static String transform(String name) {
237
StringBuilder sb = new StringBuilder();
238
boolean toLower = true;
239
boolean toUpper = false;
240
for (int i = 0; i < name.length(); i++) {
241
char c = name.charAt(i);
242
if (c == '.' || c == '_') {
243
toLower = false;
244
toUpper = true;
245
} else {
246
if (toUpper) {
247
toUpper = false;
248
sb.append(Character.toUpperCase(c));
249
} else if(toLower) {
250
sb.append(Character.toLowerCase(c));
251
} else {
252
sb.append(c);
253
}
254
}
255
}
256
return sb.toString();
257
}
258
259
private Descriptor commandDescriptor(Wrapper w) throws IllegalArgumentException {
260
HashMap<String, Object> map = new HashMap<>();
261
map.put("dcmd.name", w.info.getName());
262
map.put("dcmd.description", w.info.getDescription());
263
map.put("dcmd.vmImpact", w.info.getImpact());
264
map.put("dcmd.permissionClass", w.info.getPermissionClass());
265
map.put("dcmd.permissionName", w.info.getPermissionName());
266
map.put("dcmd.permissionAction", w.info.getPermissionAction());
267
map.put("dcmd.enabled", w.info.isEnabled());
268
StringBuilder sb = new StringBuilder();
269
sb.append("help ");
270
sb.append(w.info.getName());
271
map.put("dcmd.help", executeDiagnosticCommand(sb.toString()));
272
if (w.info.getArgumentsInfo() != null && !w.info.getArgumentsInfo().isEmpty()) {
273
HashMap<String, Object> allargmap = new HashMap<>();
274
for (DiagnosticCommandArgumentInfo arginfo : w.info.getArgumentsInfo()) {
275
HashMap<String, Object> argmap = new HashMap<>();
276
argmap.put("dcmd.arg.name", arginfo.getName());
277
argmap.put("dcmd.arg.type", arginfo.getType());
278
argmap.put("dcmd.arg.description", arginfo.getDescription());
279
argmap.put("dcmd.arg.isMandatory", arginfo.isMandatory());
280
argmap.put("dcmd.arg.isMultiple", arginfo.isMultiple());
281
boolean isOption = arginfo.isOption();
282
argmap.put("dcmd.arg.isOption", isOption);
283
if(!isOption) {
284
argmap.put("dcmd.arg.position", arginfo.getPosition());
285
} else {
286
argmap.put("dcmd.arg.position", -1);
287
}
288
allargmap.put(arginfo.getName(), new ImmutableDescriptor(argmap));
289
}
290
map.put("dcmd.arguments", new ImmutableDescriptor(allargmap));
291
}
292
return new ImmutableDescriptor(map);
293
}
294
295
private final static String notifName =
296
"javax.management.Notification";
297
298
private final static String[] diagFramNotifTypes = {
299
"jmx.mbean.info.changed"
300
};
301
302
private MBeanNotificationInfo[] notifInfo = null;
303
304
@Override
305
public MBeanNotificationInfo[] getNotificationInfo() {
306
synchronized (this) {
307
if (notifInfo == null) {
308
notifInfo = new MBeanNotificationInfo[1];
309
notifInfo[0] =
310
new MBeanNotificationInfo(diagFramNotifTypes,
311
notifName,
312
"Diagnostic Framework Notification");
313
}
314
}
315
return notifInfo.clone();
316
}
317
318
private static long seqNumber = 0;
319
private static long getNextSeqNumber() {
320
return ++seqNumber;
321
}
322
323
private void createDiagnosticFrameworkNotification() {
324
325
if (!hasListeners()) {
326
return;
327
}
328
ObjectName on = null;
329
try {
330
on = ObjectName.getInstance(ManagementFactoryHelper.HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME);
331
} catch (MalformedObjectNameException e) { }
332
Notification notif = new Notification("jmx.mbean.info.changed",
333
on,
334
getNextSeqNumber());
335
notif.setUserData(getMBeanInfo());
336
sendNotification(notif);
337
}
338
339
@Override
340
public synchronized void addNotificationListener(NotificationListener listener,
341
NotificationFilter filter,
342
Object handback) {
343
boolean before = hasListeners();
344
super.addNotificationListener(listener, filter, handback);
345
boolean after = hasListeners();
346
if (!before && after) {
347
setNotificationEnabled(true);
348
}
349
}
350
351
@Override
352
public synchronized void removeNotificationListener(NotificationListener listener)
353
throws ListenerNotFoundException {
354
boolean before = hasListeners();
355
super.removeNotificationListener(listener);
356
boolean after = hasListeners();
357
if (before && !after) {
358
setNotificationEnabled(false);
359
}
360
}
361
362
@Override
363
public synchronized void removeNotificationListener(NotificationListener listener,
364
NotificationFilter filter,
365
Object handback)
366
throws ListenerNotFoundException {
367
boolean before = hasListeners();
368
super.removeNotificationListener(listener, filter, handback);
369
boolean after = hasListeners();
370
if (before && !after) {
371
setNotificationEnabled(false);
372
}
373
}
374
375
private native void setNotificationEnabled(boolean enabled);
376
private native String[] getDiagnosticCommands();
377
private native DiagnosticCommandInfo[] getDiagnosticCommandInfo(String[] commands);
378
private native String executeDiagnosticCommand(String command);
379
380
}
381
382