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 }