001 /* 002 * Copyright (C) 2012 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.cli.impl.descriptor.CommandDescriptorImpl; 022 import org.crsh.cli.Argument; 023 import org.crsh.cli.Command; 024 import org.crsh.cli.Option; 025 import org.crsh.cli.impl.lang.CommandFactory; 026 import org.crsh.cli.impl.invocation.InvocationMatch; 027 import org.crsh.cli.impl.invocation.InvocationMatcher; 028 import org.crsh.shell.Shell; 029 import org.crsh.shell.ShellFactory; 030 import org.crsh.shell.impl.remoting.RemoteClient; 031 032 import java.io.File; 033 import java.lang.instrument.Instrumentation; 034 import java.util.Collections; 035 import java.util.List; 036 import java.util.Map; 037 import java.util.Properties; 038 import java.util.logging.Level; 039 import java.util.logging.Logger; 040 041 public class Agent { 042 043 /** . */ 044 private static Logger log = Logger.getLogger(Agent.class.getName()); 045 046 public static void agentmain(final String agentArgs, final Instrumentation inst) throws Exception { 047 log.log(Level.INFO, "CRaSH agent loaded"); 048 049 // 050 Thread t = new Thread() { 051 @Override 052 public void run() { 053 try { 054 CommandDescriptorImpl<Agent> c = CommandFactory.DEFAULT.create(Agent.class); 055 InvocationMatcher<Agent> matcher = c.invoker("main"); 056 InvocationMatch<Agent> match = matcher.match(agentArgs); 057 match.invoke(new Agent(inst)); 058 } catch (Exception e) { 059 e.printStackTrace(); 060 } 061 } 062 }; 063 064 // 065 t.start(); 066 log.log(Level.INFO, "Spawned CRaSH thread " + t.getId() + " for further processing"); 067 } 068 069 /** . */ 070 private final Instrumentation instrumentation; 071 072 public Agent(Instrumentation instrumentation) { 073 this.instrumentation = instrumentation; 074 } 075 076 @Command 077 public void main( 078 @Option(names={"c","cmd"}) 079 List<String> cmds, 080 @Option(names={"conf"}) 081 List<String> confs, 082 @Option(names={"p","property"}) 083 List<String> properties, 084 @Argument(name = "port") 085 Integer port) throws Exception { 086 087 // 088 Bootstrap bootstrap = new Bootstrap(Thread.currentThread().getContextClassLoader()); 089 090 // 091 if (cmds != null) { 092 for (String cmd : cmds) { 093 File cmdPath = new File(cmd); 094 bootstrap.addToCmdPath(cmdPath); 095 } 096 } 097 098 // 099 if (confs != null) { 100 for (String conf : confs) { 101 File confPath = new File(conf); 102 bootstrap.addToConfPath(confPath); 103 } 104 } 105 106 // 107 if (properties != null) { 108 Properties config = new Properties(); 109 for (String property : properties) { 110 int index = property.indexOf('='); 111 if (index == -1) { 112 config.setProperty(property, ""); 113 } else { 114 config.setProperty(property.substring(0, index), property.substring(index + 1)); 115 } 116 } 117 bootstrap.setConfig(config); 118 } 119 120 // Set the instrumentation available as an attribute 121 Map<String, Object> attributes = Collections.<String, Object>singletonMap("instrumentation", instrumentation); 122 bootstrap.setAttributes(attributes); 123 124 // Do bootstrap 125 bootstrap.bootstrap(); 126 127 // 128 try { 129 ShellFactory factory = bootstrap.getContext().getPlugin(ShellFactory.class); 130 Shell shell = factory.create(null); 131 RemoteClient client = new RemoteClient(port, shell); 132 log.log(Level.INFO, "Callback back remote on port " + port); 133 client.connect(); 134 client.getRunnable().run(); 135 } 136 finally { 137 bootstrap.shutdown(); 138 } 139 } 140 }