• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2006 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.inject.tools.jmx;
18 
19 import com.google.inject.Binding;
20 import com.google.inject.Guice;
21 import com.google.inject.Injector;
22 import com.google.inject.Key;
23 import com.google.inject.Module;
24 
25 import java.lang.annotation.Annotation;
26 import java.lang.management.ManagementFactory;
27 
28 import javax.management.MBeanServer;
29 import javax.management.MalformedObjectNameException;
30 import javax.management.ObjectName;
31 
32 /**
33  * Provides a JMX interface to Guice.
34  *
35  * @author crazybob@google.com (Bob Lee)
36  */
37 public class Manager {
38 
39   /**
40    * Registers all the bindings of an Injector with the platform MBean server.
41    * Consider using the name of your root {@link Module} class as the domain.
42    */
manage( String domain, Injector injector)43   public static void manage(
44       String domain,
45       Injector injector) {
46     manage(ManagementFactory.getPlatformMBeanServer(), domain, injector);
47   }
48 
49   /**
50    * Registers all the bindings of an Injector with the given MBean server.
51    * Consider using the name of your root {@link Module} class as the domain.
52    */
manage(MBeanServer server, String domain, Injector injector)53   public static void manage(MBeanServer server, String domain,
54       Injector injector) {
55     // Register each binding independently.
56     for (Binding<?> binding : injector.getBindings().values()) {
57       // Construct the name manually so we can ensure proper ordering of the
58       // key/value pairs.
59       StringBuilder name = new StringBuilder();
60       name.append(domain).append(":");
61       Key<?> key = binding.getKey();
62       name.append("type=").append(quote(key.getTypeLiteral().toString()));
63       Annotation annotation = key.getAnnotation();
64       if (annotation != null) {
65         name.append(",annotation=").append(quote(annotation.toString()));
66       }
67       else {
68         Class<? extends Annotation> annotationType = key.getAnnotationType();
69         if (annotationType != null) {
70           name.append(",annotation=")
71               .append(quote("@" + annotationType.getName()));
72         }
73       }
74 
75       try {
76         server.registerMBean(new ManagedBinding(binding),
77             new ObjectName(name.toString()));
78       }
79       catch (MalformedObjectNameException e) {
80         throw new RuntimeException("Bad object name: " + name, e);
81       }
82       catch (Exception e) {
83         throw new RuntimeException(e);
84       }
85     }
86   }
87 
quote(String value)88   static String quote(String value) {
89     // JMX seems to have a comma bug.
90     return ObjectName.quote(value).replace(',', ';');
91   }
92 
93   /**
94    * Run with no arguments for usage instructions.
95    */
main(String[] args)96   public static void main(String[] args) throws Exception {
97     if (args.length != 1) {
98       System.err.println("Usage: java -Dcom.sun.management.jmxremote "
99           + Manager.class.getName() + " [module class name]");
100       System.err.println("Then run 'jconsole' to connect.");
101       System.exit(1);
102     }
103 
104     Module module = (Module) Class.forName(args[0]).newInstance();
105     Injector injector = Guice.createInjector(module);
106 
107     manage(args[0], injector);
108 
109     System.out.println("Press Ctrl+C to exit...");
110 
111     // Sleep forever.
112     Thread.sleep(Long.MAX_VALUE);
113   }
114 }
115