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.impl.CRaSH; 030 import org.crsh.term.BaseTerm; 031 import org.crsh.term.Term; 032 import org.crsh.term.processor.Processor; 033 import org.crsh.term.spi.net.TermIOClient; 034 import org.slf4j.Logger; 035 import org.slf4j.LoggerFactory; 036 037 import java.io.Closeable; 038 import java.io.File; 039 import java.lang.instrument.Instrumentation; 040 import java.util.Collections; 041 import java.util.List; 042 import java.util.Map; 043 import java.util.Properties; 044 045 /** 046 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> 047 */ 048 public class Agent { 049 050 /** . */ 051 private static Logger log = LoggerFactory.getLogger(Agent.class); 052 053 public static void agentmain(final String agentArgs, final Instrumentation inst) throws Exception { 054 log.info("CRaSH agent loaded"); 055 056 // 057 Thread t = new Thread() { 058 @Override 059 public void run() { 060 try { 061 ClassDescriptor<Agent> c = CommandFactory.create(Agent.class); 062 Matcher<Agent> matcher = Matcher.createMatcher("main", c); 063 CommandMatch<Agent, ?, ?> match = matcher.match(agentArgs); 064 match.invoke(new InvocationContext(), new Agent(inst)); 065 } catch (Exception e) { 066 e.printStackTrace(); 067 } 068 } 069 }; 070 071 // 072 t.start(); 073 log.info("Spawned CRaSH thread " + t.getId() + " for further processing"); 074 } 075 076 /** . */ 077 private final Instrumentation instrumentation; 078 079 public Agent(Instrumentation instrumentation) { 080 this.instrumentation = instrumentation; 081 } 082 083 @Command 084 public void main( 085 @Option(names={"j","jar"}) 086 List<String> jars, 087 @Option(names={"c","cmd"}) 088 List<String> cmds, 089 @Option(names={"conf"}) 090 List<String> confs, 091 @Option(names={"p","property"}) 092 List<String> properties, 093 @Argument(name = "port") 094 Integer port) throws Exception { 095 096 // 097 Bootstrap bootstrap = new Bootstrap(Thread.currentThread().getContextClassLoader()); 098 099 // 100 if (cmds != null) { 101 for (String cmd : cmds) { 102 File cmdPath = new File(cmd); 103 bootstrap.addCmdPath(cmdPath); 104 } 105 } 106 107 // 108 if (confs != null) { 109 for (String conf : confs) { 110 File confPath = new File(conf); 111 bootstrap.addConfPath(confPath); 112 } 113 } 114 115 // 116 if (jars != null) { 117 for (String jar : jars) { 118 File jarFile = new File(jar); 119 bootstrap.addJarPath(jarFile); 120 } 121 } 122 123 // 124 if (properties != null) { 125 Properties config = new Properties(); 126 for (String property : properties) { 127 int index = property.indexOf('='); 128 if (index == -1) { 129 config.setProperty(property, ""); 130 } else { 131 config.setProperty(property.substring(0, index), property.substring(index + 1)); 132 } 133 } 134 bootstrap.setConfig(config); 135 } 136 137 // Set the instrumentation available as an attribute 138 Map<String, Object> attributes = Collections.<String, Object>singletonMap("instrumentation", instrumentation); 139 bootstrap.setAttributes(attributes); 140 141 // Do bootstrap 142 bootstrap.bootstrap(); 143 144 // 145 try { 146 final TermIOClient client = new TermIOClient(port); 147 log.info("Callback back remote on port " + port); 148 client.connect(); 149 150 // Do stuff 151 Term term = new BaseTerm(client); 152 CRaSH crash = new CRaSH(bootstrap.getContext()); 153 Processor processor = new Processor(term, crash.createSession(null)); 154 processor.addListener(new Closeable() { 155 public void close() { 156 client.close(); 157 } 158 }); 159 160 // Run 161 processor.run(); 162 } 163 finally { 164 bootstrap.shutdown(); 165 } 166 } 167 }