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 javax.management.remote;
27
28
29 import com.sun.jmx.remote.util.ClassLogger;
30 import com.sun.jmx.remote.util.EnvHelp;
31
32 import java.io.IOException;
33 import java.net.MalformedURLException;
34 import java.util.Collections;
35 import java.util.HashMap;
36 import java.util.Iterator;
37 import java.util.Map;
38
39 import javax.management.MBeanServer;
40
41 /**
42 * <p>Factory to create JMX API connector servers. There
43 * are no instances of this class.</p>
44 *
45 * <p>Each connector server is created by an instance of {@link
46 * JMXConnectorServerProvider}. This instance is found as follows. Suppose
47 * the given {@link JMXServiceURL} looks like
48 * <code>"service:jmx:<em>protocol</em>:<em>remainder</em>"</code>.
49 * Then the factory will attempt to find the appropriate {@link
50 * JMXConnectorServerProvider} for <code><em>protocol</em></code>. Each
51 * occurrence of the character <code>+</code> or <code>-</code> in
52 * <code><em>protocol</em></code> is replaced by <code>.</code> or
53 * <code>_</code>, respectively.</p>
54 *
55 * <p>A <em>provider package list</em> is searched for as follows:</p>
56 *
57 * <ol>
58 *
59 * <li>If the <code>environment</code> parameter to {@link
188 /**
189 * <p>Name of the attribute that specifies the class
190 * loader for loading protocol providers.
191 * The value associated with this attribute is an instance
192 * of {@link ClassLoader}.</p>
193 */
194 public static final String PROTOCOL_PROVIDER_CLASS_LOADER =
195 "jmx.remote.protocol.provider.class.loader";
196
197 private static final String PROTOCOL_PROVIDER_DEFAULT_PACKAGE =
198 "com.sun.jmx.remote.protocol";
199
200 private static final ClassLogger logger =
201 new ClassLogger("javax.management.remote.misc","JMXConnectorServerFactory");
202
203 /** There are no instances of this class. */
204 private JMXConnectorServerFactory() {
205 }
206
207 private static JMXConnectorServer
208 getConnectorServerAsService(ClassLoader loader,
209 JMXServiceURL url,
210 Map<String, ?> map,
211 MBeanServer mbs)
212 throws IOException {
213 Iterator<JMXConnectorServerProvider> providers =
214 JMXConnectorFactory.
215 getProviderIterator(JMXConnectorServerProvider.class, loader);
216
217 IOException exception = null;
218 while (providers.hasNext()) {
219 try {
220 return providers.next().newJMXConnectorServer(url, map, mbs);
221 } catch (JMXProviderException e) {
222 throw e;
223 } catch (Exception e) {
224 if (logger.traceOn())
225 logger.trace("getConnectorAsService",
226 "URL[" + url +
227 "] Service provider exception: " + e);
228 if (!(e instanceof MalformedURLException)) {
229 if (exception == null) {
230 if (e instanceof IOException) {
231 exception = (IOException) e;
232 } else {
233 exception = EnvHelp.initCause(
234 new IOException(e.getMessage()), e);
235 }
236 }
237 }
238 continue;
239 }
240 }
241 if (exception == null)
242 return null;
243 else
244 throw exception;
245 }
246
247 /**
248 * <p>Creates a connector server at the given address. The
249 * resultant server is not started until its {@link
250 * JMXConnectorServer#start() start} method is called.</p>
251 *
252 * @param serviceURL the address of the new connector server. The
253 * actual address of the new connector server, as returned by its
254 * {@link JMXConnectorServer#getAddress() getAddress} method, will
255 * not necessarily be exactly the same. For example, it might
256 * include a port number if the original address did not.
257 *
258 * @param environment a set of attributes to control the new
259 * connector server's behavior. This parameter can be null.
260 * Keys in this map must be Strings. The appropriate type of each
261 * associated value depends on the attribute. The contents of
262 * <code>environment</code> are not changed by this call.
263 *
264 * @param mbeanServer the MBean server that this connector server
292 else {
293 EnvHelp.checkAttributes(environment);
294 envcopy = new HashMap<String, Object>(environment);
295 }
296
297 final Class<JMXConnectorServerProvider> targetInterface =
298 JMXConnectorServerProvider.class;
299 final ClassLoader loader =
300 JMXConnectorFactory.resolveClassLoader(envcopy);
301 final String protocol = serviceURL.getProtocol();
302 final String providerClassName = "ServerProvider";
303
304 JMXConnectorServerProvider provider =
305 JMXConnectorFactory.getProvider(serviceURL,
306 envcopy,
307 providerClassName,
308 targetInterface,
309 loader);
310
311 IOException exception = null;
312 if (provider == null) {
313 // Loader is null when context class loader is set to null
314 // and no loader has been provided in map.
315 // com.sun.jmx.remote.util.Service class extracted from j2se
316 // provider search algorithm doesn't handle well null classloader.
317 if (loader != null) {
318 try {
319 JMXConnectorServer connection =
320 getConnectorServerAsService(loader,
321 serviceURL,
322 envcopy,
323 mbeanServer);
324 if (connection != null)
325 return connection;
326 } catch (JMXProviderException e) {
327 throw e;
328 } catch (IOException e) {
329 exception = e;
330 }
331 }
332 provider =
333 JMXConnectorFactory.getProvider(
334 protocol,
335 PROTOCOL_PROVIDER_DEFAULT_PACKAGE,
336 JMXConnectorFactory.class.getClassLoader(),
337 providerClassName,
338 targetInterface);
339 }
340
341 if (provider == null) {
342 MalformedURLException e =
343 new MalformedURLException("Unsupported protocol: " + protocol);
344 if (exception == null) {
345 throw e;
346 } else {
347 throw EnvHelp.initCause(e, exception);
348 }
349 }
350
351 envcopy = Collections.unmodifiableMap(envcopy);
352
353 return provider.newJMXConnectorServer(serviceURL,
354 envcopy,
355 mbeanServer);
356 }
357 }
|
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 javax.management.remote;
27
28
29 import com.sun.jmx.remote.util.ClassLogger;
30 import com.sun.jmx.remote.util.EnvHelp;
31
32 import java.io.IOException;
33 import java.io.UncheckedIOException;
34 import java.net.MalformedURLException;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.Map;
38 import java.util.ServiceLoader.Provider;
39 import java.util.function.Predicate;
40
41 import javax.management.MBeanServer;
42 import javax.management.remote.JMXConnectorFactory.ConnectorFactory;
43
44 /**
45 * <p>Factory to create JMX API connector servers. There
46 * are no instances of this class.</p>
47 *
48 * <p>Each connector server is created by an instance of {@link
49 * JMXConnectorServerProvider}. This instance is found as follows. Suppose
50 * the given {@link JMXServiceURL} looks like
51 * <code>"service:jmx:<em>protocol</em>:<em>remainder</em>"</code>.
52 * Then the factory will attempt to find the appropriate {@link
53 * JMXConnectorServerProvider} for <code><em>protocol</em></code>. Each
54 * occurrence of the character <code>+</code> or <code>-</code> in
55 * <code><em>protocol</em></code> is replaced by <code>.</code> or
56 * <code>_</code>, respectively.</p>
57 *
58 * <p>A <em>provider package list</em> is searched for as follows:</p>
59 *
60 * <ol>
61 *
62 * <li>If the <code>environment</code> parameter to {@link
191 /**
192 * <p>Name of the attribute that specifies the class
193 * loader for loading protocol providers.
194 * The value associated with this attribute is an instance
195 * of {@link ClassLoader}.</p>
196 */
197 public static final String PROTOCOL_PROVIDER_CLASS_LOADER =
198 "jmx.remote.protocol.provider.class.loader";
199
200 private static final String PROTOCOL_PROVIDER_DEFAULT_PACKAGE =
201 "com.sun.jmx.remote.protocol";
202
203 private static final ClassLogger logger =
204 new ClassLogger("javax.management.remote.misc","JMXConnectorServerFactory");
205
206 /** There are no instances of this class. */
207 private JMXConnectorServerFactory() {
208 }
209
210 private static JMXConnectorServer
211 getConnectorServerAsService(ClassLoader loader, JMXServiceURL url,
212 Map<String, ?> map, MBeanServer mbs,
213 Predicate<Provider<?>> filter)
214 throws IOException {
215 final ConnectorFactory<JMXConnectorServerProvider,JMXConnectorServer>
216 factory = (p) -> p.newJMXConnectorServer(url, map, mbs);
217 return JMXConnectorFactory.getConnectorAsService(
218 JMXConnectorServerProvider.class,
219 loader, url, filter, factory);
220 }
221
222 /**
223 * <p>Creates a connector server at the given address. The
224 * resultant server is not started until its {@link
225 * JMXConnectorServer#start() start} method is called.</p>
226 *
227 * @param serviceURL the address of the new connector server. The
228 * actual address of the new connector server, as returned by its
229 * {@link JMXConnectorServer#getAddress() getAddress} method, will
230 * not necessarily be exactly the same. For example, it might
231 * include a port number if the original address did not.
232 *
233 * @param environment a set of attributes to control the new
234 * connector server's behavior. This parameter can be null.
235 * Keys in this map must be Strings. The appropriate type of each
236 * associated value depends on the attribute. The contents of
237 * <code>environment</code> are not changed by this call.
238 *
239 * @param mbeanServer the MBean server that this connector server
267 else {
268 EnvHelp.checkAttributes(environment);
269 envcopy = new HashMap<String, Object>(environment);
270 }
271
272 final Class<JMXConnectorServerProvider> targetInterface =
273 JMXConnectorServerProvider.class;
274 final ClassLoader loader =
275 JMXConnectorFactory.resolveClassLoader(envcopy);
276 final String protocol = serviceURL.getProtocol();
277 final String providerClassName = "ServerProvider";
278
279 JMXConnectorServerProvider provider =
280 JMXConnectorFactory.getProvider(serviceURL,
281 envcopy,
282 providerClassName,
283 targetInterface,
284 loader);
285
286 IOException exception = null;
287 JMXConnectorServer connection = null;
288 if (provider == null) {
289 Predicate<Provider<?>> systemProvider =
290 JMXConnectorFactory::isSystemProvider;
291 // Loader is null when context class loader is set to null
292 // and no loader has been provided in map.
293 // com.sun.jmx.remote.util.Service class extracted from j2se
294 // provider search algorithm doesn't handle well null classloader.
295 if (loader != null) {
296 try {
297 connection =
298 getConnectorServerAsService(loader,
299 serviceURL,
300 envcopy,
301 mbeanServer,
302 systemProvider.negate());
303 if (connection != null)
304 return connection;
305 } catch (JMXProviderException e) {
306 throw e;
307 } catch (IOException e) {
308 exception = e;
309 }
310 }
311 connection = getConnectorServerAsService(
312 JMXConnectorFactory.class.getClassLoader(),
313 serviceURL,
314 Collections.unmodifiableMap(envcopy),
315 mbeanServer,
316 systemProvider);
317 if (connection != null) return connection;
318 }
319
320 if (provider == null) {
321 MalformedURLException e =
322 new MalformedURLException("Unsupported protocol: " + protocol);
323 if (exception == null) {
324 throw e;
325 } else {
326 throw EnvHelp.initCause(e, exception);
327 }
328 }
329
330 envcopy = Collections.unmodifiableMap(envcopy);
331
332 return provider.newJMXConnectorServer(serviceURL,
333 envcopy,
334 mbeanServer);
335 }
336 }
|