Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.management/share/classes/com/sun/jmx/mbeanserver/MXBeanLookup.java
41161 views
1
/*
2
* Copyright (c) 2005, 2021, 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 com.sun.jmx.mbeanserver;
27
28
import static com.sun.jmx.mbeanserver.Util.*;
29
import java.util.Map;
30
import java.lang.ref.WeakReference;
31
import java.lang.reflect.InvocationHandler;
32
import java.lang.reflect.Proxy;
33
import java.security.AccessController;
34
import javax.management.InstanceAlreadyExistsException;
35
import javax.management.JMX;
36
import javax.management.MBeanServerConnection;
37
import javax.management.MBeanServerInvocationHandler;
38
import javax.management.ObjectName;
39
import javax.management.openmbean.OpenDataException;
40
41
/**
42
* @since 1.6
43
*/
44
45
/*
46
* This class handles the mapping between MXBean references and
47
* ObjectNames. Consider an MXBean interface like this:
48
*
49
* public interface ModuleMXBean {
50
* ProductMXBean getProduct();
51
* void setProduct(ProductMXBean product);
52
* }
53
*
54
* This defines an attribute called "Product" whose originalType will
55
* be ProductMXBean and whose openType will be ObjectName. The
56
* mapping happens as follows.
57
*
58
* When the MXBean's getProduct method is called, it is supposed to
59
* return a reference to another MXBean, or a proxy for another
60
* MXBean. The MXBean layer has to convert this into an ObjectName.
61
* If it's a reference to another MXBean, it needs to be able to look
62
* up the name under which that MXBean has been registered in this
63
* MBeanServer; this is the purpose of the mxbeanToObjectName map. If
64
* it's a proxy, it can check that the MBeanServer matches and if so
65
* extract the ObjectName from the proxy.
66
*
67
* When the setProduct method is called on a proxy for this MXBean,
68
* the argument can be either an MXBean reference (only really logical
69
* if the proxy has a local MBeanServer) or another proxy. So the
70
* mapping logic is the same as for getProduct on the MXBean.
71
*
72
* When the MXBean's setProduct method is called, it needs to convert
73
* the ObjectName into an object implementing the ProductMXBean
74
* interface. We could have a lookup table that reverses
75
* mxbeanToObjectName, but this could violate the general JMX property
76
* that you cannot obtain a reference to an MBean object. So we
77
* always use a proxy for this. However we do have an
78
* objectNameToProxy map that allows us to reuse proxy instances.
79
*
80
* When the getProduct method is called on a proxy for this MXBean, it
81
* must convert the returned ObjectName into an instance of
82
* ProductMXBean. Again it can do this by making a proxy.
83
*
84
* From the above, it is clear that the logic for getX on an MXBean is
85
* the same as for setX on a proxy, and vice versa.
86
*/
87
public class MXBeanLookup {
88
private MXBeanLookup(MBeanServerConnection mbsc) {
89
this.mbsc = mbsc;
90
}
91
92
static MXBeanLookup lookupFor(MBeanServerConnection mbsc) {
93
synchronized (mbscToLookup) {
94
WeakReference<MXBeanLookup> weakLookup = mbscToLookup.get(mbsc);
95
MXBeanLookup lookup = (weakLookup == null) ? null : weakLookup.get();
96
if (lookup == null) {
97
lookup = new MXBeanLookup(mbsc);
98
mbscToLookup.put(mbsc, new WeakReference<MXBeanLookup>(lookup));
99
}
100
return lookup;
101
}
102
}
103
104
synchronized <T> T objectNameToMXBean(ObjectName name, Class<T> type) {
105
WeakReference<Object> wr = objectNameToProxy.get(name);
106
if (wr != null) {
107
Object proxy = wr.get();
108
if (type.isInstance(proxy))
109
return type.cast(proxy);
110
}
111
T proxy = JMX.newMXBeanProxy(mbsc, name, type);
112
objectNameToProxy.put(name, new WeakReference<Object>(proxy));
113
return proxy;
114
}
115
116
synchronized ObjectName mxbeanToObjectName(Object mxbean)
117
throws OpenDataException {
118
String wrong;
119
if (mxbean instanceof Proxy) {
120
InvocationHandler ih = Proxy.getInvocationHandler(mxbean);
121
if (ih instanceof MBeanServerInvocationHandler) {
122
MBeanServerInvocationHandler mbsih =
123
(MBeanServerInvocationHandler) ih;
124
if (mbsih.getMBeanServerConnection().equals(mbsc))
125
return mbsih.getObjectName();
126
else
127
wrong = "proxy for a different MBeanServer";
128
} else
129
wrong = "not a JMX proxy";
130
} else {
131
ObjectName name = mxbeanToObjectName.get(mxbean);
132
if (name != null)
133
return name;
134
wrong = "not an MXBean registered in this MBeanServer";
135
}
136
String s = (mxbean == null) ?
137
"null" : "object of type " + mxbean.getClass().getName();
138
throw new OpenDataException(
139
"Could not convert " + s + " to an ObjectName: " + wrong);
140
// Message will be strange if mxbean is null but it is not
141
// supposed to be.
142
}
143
144
synchronized void addReference(ObjectName name, Object mxbean)
145
throws InstanceAlreadyExistsException {
146
ObjectName existing = mxbeanToObjectName.get(mxbean);
147
if (existing != null) {
148
@SuppressWarnings("removal")
149
String multiname = AccessController.doPrivileged(
150
new GetPropertyAction("jmx.mxbean.multiname"));
151
if (!"true".equalsIgnoreCase(multiname)) {
152
throw new InstanceAlreadyExistsException(
153
"MXBean already registered with name " + existing);
154
}
155
}
156
mxbeanToObjectName.put(mxbean, name);
157
}
158
159
synchronized boolean removeReference(ObjectName name, Object mxbean) {
160
if (name.equals(mxbeanToObjectName.get(mxbean))) {
161
mxbeanToObjectName.remove(mxbean);
162
return true;
163
} else
164
return false;
165
/* removeReference can be called when the above condition fails,
166
* notably if you try to register the same MXBean twice.
167
*/
168
}
169
170
static MXBeanLookup getLookup() {
171
return currentLookup.get();
172
}
173
174
static void setLookup(MXBeanLookup lookup) {
175
currentLookup.set(lookup);
176
}
177
178
private static final ThreadLocal<MXBeanLookup> currentLookup =
179
new ThreadLocal<MXBeanLookup>();
180
181
private final MBeanServerConnection mbsc;
182
private final WeakIdentityHashMap<Object, ObjectName>
183
mxbeanToObjectName = WeakIdentityHashMap.make();
184
private final Map<ObjectName, WeakReference<Object>>
185
objectNameToProxy = newMap();
186
private static final WeakIdentityHashMap<MBeanServerConnection,
187
WeakReference<MXBeanLookup>>
188
mbscToLookup = WeakIdentityHashMap.make();
189
}
190
191