001 /* 002 * Copyright (C) 2011 eXo Platform SAS. 003 * 004 * This is free software; you can redistribute it and/or modify it 005 * under the terms of the GNU Lesser General Public License as 006 * published by the Free Software Foundation; either version 2.1 of 007 * the License, or (at your option) any later version. 008 * 009 * This software is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public 015 * License along with this software; if not, write to the Free 016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 018 */ 019 package org.crsh.standalone; 020 021 import org.crsh.cmdline.ClassDescriptor; 022 import org.crsh.cmdline.CommandFactory; 023 import org.crsh.cmdline.annotations.Argument; 024 import org.crsh.cmdline.annotations.Command; 025 import org.crsh.cmdline.annotations.Option; 026 import org.crsh.cmdline.matcher.CommandMatch; 027 import org.crsh.cmdline.matcher.InvocationContext; 028 import org.crsh.cmdline.matcher.Matcher; 029 import org.crsh.shell.Shell; 030 import org.crsh.shell.impl.async.AsyncShell; 031 import org.crsh.shell.impl.command.CRaSH; 032 import org.crsh.shell.impl.remoting.RemoteClient; 033 import org.slf4j.Logger; 034 import org.slf4j.LoggerFactory; 035 036 import java.io.File; 037 import java.lang.instrument.Instrumentation; 038 import java.util.Collections; 039 import java.util.List; 040 import java.util.Map; 041 import java.util.Properties; 042 043 /** 044 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> 045 */ 046 public class Agent { 047 048 /** . */ 049 private static Logger log = LoggerFactory.getLogger(Agent.class); 050 051 public static void agentmain(final String agentArgs, final Instrumentation inst) throws Exception { 052 log.info("CRaSH agent loaded"); 053 054 // 055 Thread t = new Thread() { 056 @Override 057 public void run() { 058 try { 059 ClassDescriptor<Agent> c = CommandFactory.create(Agent.class); 060 Matcher<Agent> matcher = Matcher.createMatcher("main", c); 061 CommandMatch<Agent, ?, ?> match = matcher.match(agentArgs); 062 match.invoke(new InvocationContext(), new Agent(inst)); 063 } catch (Exception e) { 064 e.printStackTrace(); 065 } 066 } 067 }; 068 069 // 070 t.start(); 071 log.info("Spawned CRaSH thread " + t.getId() + " for further processing"); 072 } 073 074 /** . */ 075 private final Instrumentation instrumentation; 076 077 public Agent(Instrumentation instrumentation) { 078 this.instrumentation = instrumentation; 079 } 080 081 @Command 082 public void main( 083 @Option(names={"j","jar"}) 084 List<String> jars, 085 @Option(names={"c","cmd"}) 086 List<String> cmds, 087 @Option(names={"conf"}) 088 List<String> confs, 089 @Option(names={"p","property"}) 090 List<String> properties, 091 @Argument(name = "port") 092 Integer port) throws Exception { 093 094 // 095 Bootstrap bootstrap = new Bootstrap(Thread.currentThread().getContextClassLoader()); 096 097 // 098 if (cmds != null) { 099 for (String cmd : cmds) { 100 File cmdPath = new File(cmd); 101 bootstrap.addCmdPath(cmdPath); 102 } 103 } 104 105 // 106 if (confs != null) { 107 for (String conf : confs) { 108 File confPath = new File(conf); 109 bootstrap.addConfPath(confPath); 110 } 111 } 112 113 // 114 if (jars != null) { 115 for (String jar : jars) { 116 File jarFile = new File(jar); 117 bootstrap.addJarPath(jarFile); 118 } 119 } 120 121 // 122 if (properties != null) { 123 Properties config = new Properties(); 124 for (String property : properties) { 125 int index = property.indexOf('='); 126 if (index == -1) { 127 config.setProperty(property, ""); 128 } else { 129 config.setProperty(property.substring(0, index), property.substring(index + 1)); 130 } 131 } 132 bootstrap.setConfig(config); 133 } 134 135 // Set the instrumentation available as an attribute 136 Map<String, Object> attributes = Collections.<String, Object>singletonMap("instrumentation", instrumentation); 137 bootstrap.setAttributes(attributes); 138 139 // Do bootstrap 140 bootstrap.bootstrap(); 141 142 // 143 try { 144 CRaSH crash = new CRaSH(bootstrap.getContext()); 145 Shell shell = crash.createSession(null); 146 AsyncShell async = new AsyncShell(bootstrap.getContext().getExecutor(), shell); 147 RemoteClient client = new RemoteClient(port, async); 148 log.info("Callback back remote on port " + port); 149 client.connect(); 150 client.getRunnable().run(); 151 } 152 finally { 153 bootstrap.shutdown(); 154 } 155 } 156 }