Save This Page
Home » activemq-parent-5.3.1-source-release » org.apache » activemq » console » [javadoc | source]
    1   /**
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   package org.apache.activemq.console;
   18   
   19   import java.io.File;
   20   import java.io.InputStream;
   21   import java.io.PrintStream;
   22   import java.lang.management.ManagementFactory;
   23   import java.lang.reflect.InvocationTargetException;
   24   import java.lang.reflect.Method;
   25   import java.net.JarURLConnection;
   26   import java.net.MalformedURLException;
   27   import java.net.URI;
   28   import java.net.URL;
   29   import java.net.URLClassLoader;
   30   import java.util.ArrayList;
   31   import java.util.Arrays;
   32   import java.util.Comparator;
   33   import java.util.HashSet;
   34   import java.util.Iterator;
   35   import java.util.LinkedList;
   36   import java.util.List;
   37   import java.util.Set;
   38   import java.util.StringTokenizer;
   39   
   40   /**
   41    * Main class that can bootstrap an ActiveMQ broker console. Handles command
   42    * line argument parsing to set up and run broker tasks.
   43    * 
   44    * @version $Revision$
   45    */
   46   public class Main {
   47   
   48       public static final String TASK_DEFAULT_CLASS = "org.apache.activemq.console.command.ShellCommand";
   49       private static boolean useDefExt = true;
   50   
   51       private File activeMQHome;
   52       private File activeMQBase;
   53       private ClassLoader classLoader;
   54       private Set<File> extensions = new HashSet<File>(5);
   55       private Set<File> activeMQClassPath = new HashSet<File>(5);
   56   
   57       public static void main(String[] args) {
   58           Main app = new Main();
   59   
   60           // Convert arguments to collection for easier management
   61           List<String> tokens = new LinkedList<String>(Arrays.asList(args));
   62           // Parse for extension directory option
   63           app.parseExtensions(tokens);
   64   
   65   		// lets add the conf directory first, to find the log4j.properties just in case its not 
   66   		// in the activemq.classpath system property or some jar incorrectly includes one
   67   		File confDir = new File(app.getActiveMQBase(), "conf");
   68   		app.addClassPath(confDir);
   69   
   70           // Add the following to the classpath:
   71           //
   72           // ${activemq.base}/conf
   73           // ${activemq.base}/lib/* (only if activemq.base != activemq.home)
   74           // ${activemq.home}/lib/*
   75           // ${activemq.base}/lib/optional/* (only if activemq.base !=
   76           // activemq.home)
   77           // ${activemq.home}/lib/optional/*
   78           // ${activemq.base}/lib/web/* (only if activemq.base != activemq.home)
   79           // ${activemq.home}/lib/web/*
   80           //
   81           if (useDefExt && app.canUseExtdir()) {
   82   
   83               boolean baseIsHome = app.getActiveMQBase().equals(app.getActiveMQHome());
   84   
   85               File baseLibDir = new File(app.getActiveMQBase(), "lib");
   86               File homeLibDir = new File(app.getActiveMQHome(), "lib");
   87   
   88               if (!baseIsHome) {
   89                   app.addExtensionDirectory(baseLibDir);
   90               }
   91               app.addExtensionDirectory(homeLibDir);
   92   
   93               if (!baseIsHome) {
   94                   app.addExtensionDirectory(new File(baseLibDir, "optional"));
   95                   app.addExtensionDirectory(new File(baseLibDir, "web"));
   96               }
   97               app.addExtensionDirectory(new File(homeLibDir, "optional"));
   98               app.addExtensionDirectory(new File(homeLibDir, "web"));
   99   
  100           }
  101   
  102           // Add any custom classpath specified from the system property
  103           // activemq.classpath
  104           app.addClassPathList(System.getProperty("activemq.classpath"));
  105   
  106           try {
  107               app.runTaskClass(tokens);
  108               System.exit(0);
  109           } catch (ClassNotFoundException e) {
  110               System.out.println("Could not load class: " + e.getMessage());
  111               try {
  112                   ClassLoader cl = app.getClassLoader();
  113                   if (cl != null) {
  114                       System.out.println("Class loader setup: ");
  115                       printClassLoaderTree(cl);
  116                   }
  117               } catch (MalformedURLException e1) {
  118               }
  119               System.exit(1);
  120           } catch (Throwable e) {
  121               System.out.println("Failed to execute main task. Reason: " + e);
  122               System.exit(1);
  123           }
  124       }
  125   
  126       /**
  127        * Print out what's in the classloader tree being used.
  128        * 
  129        * @param cl
  130        * @return depth
  131        */
  132       private static int printClassLoaderTree(ClassLoader cl) {
  133           int depth = 0;
  134           if (cl.getParent() != null) {
  135               depth = printClassLoaderTree(cl.getParent()) + 1;
  136           }
  137   
  138           StringBuffer indent = new StringBuffer();
  139           for (int i = 0; i < depth; i++) {
  140               indent.append("  ");
  141           }
  142   
  143           if (cl instanceof URLClassLoader) {
  144               URLClassLoader ucl = (URLClassLoader)cl;
  145               System.out.println(indent + cl.getClass().getName() + " {");
  146               URL[] urls = ucl.getURLs();
  147               for (int i = 0; i < urls.length; i++) {
  148                   System.out.println(indent + "  " + urls[i]);
  149               }
  150               System.out.println(indent + "}");
  151           } else {
  152               System.out.println(indent + cl.getClass().getName());
  153           }
  154           return depth;
  155       }
  156   
  157       public void parseExtensions(List<String> tokens) {
  158           if (tokens.isEmpty()) {
  159               return;
  160           }
  161   
  162           int count = tokens.size();
  163           int i = 0;
  164   
  165           // Parse for all --extdir and --noDefExt options
  166           while (i < count) {
  167               String token = tokens.get(i);
  168               // If token is an extension dir option
  169               if (token.equals("--extdir")) {
  170                   // Process token
  171                   count--;
  172                   tokens.remove(i);
  173   
  174                   // If no extension directory is specified, or next token is
  175                   // another option
  176                   if (i >= count || tokens.get(i).startsWith("-")) {
  177                       System.out.println("Extension directory not specified.");
  178                       System.out.println("Ignoring extension directory option.");
  179                       continue;
  180                   }
  181   
  182                   // Process extension dir token
  183                   count--;
  184                   File extDir = new File(tokens.remove(i));
  185   
  186                   if (!canUseExtdir()) {
  187                       System.out.println("Extension directory feature not available due to the system classpath being able to load: " + TASK_DEFAULT_CLASS);
  188                       System.out.println("Ignoring extension directory option.");
  189                       continue;
  190                   }
  191   
  192                   if (!extDir.isDirectory()) {
  193                       System.out.println("Extension directory specified is not valid directory: " + extDir);
  194                       System.out.println("Ignoring extension directory option.");
  195                       continue;
  196                   }
  197   
  198                   addExtensionDirectory(extDir);
  199               } else if (token.equals("--noDefExt")) { // If token is
  200                   // --noDefExt option
  201                   count--;
  202                   tokens.remove(i);
  203                   useDefExt = false;
  204               } else {
  205                   i++;
  206               }
  207           }
  208   
  209       }
  210   
  211       public void runTaskClass(List<String> tokens) throws Throwable {
  212   
  213           StringBuilder buffer = new StringBuilder();
  214           buffer.append(System.getProperty("java.vendor"));
  215           buffer.append(" ");
  216           buffer.append(System.getProperty("java.version"));
  217           buffer.append(" ");
  218           buffer.append(System.getProperty("java.home"));
  219           System.out.println("Java Runtime: " + buffer.toString());
  220   
  221           buffer = new StringBuilder();
  222           buffer.append("current="); 
  223           buffer.append(Runtime.getRuntime().totalMemory()/1024L); 
  224           buffer.append("k  free="); 
  225           buffer.append(Runtime.getRuntime().freeMemory()/1024L); 
  226           buffer.append("k  max="); 
  227           buffer.append(Runtime.getRuntime().maxMemory()/1024L); 
  228           buffer.append("k");
  229           System.out.println("  Heap sizes: " + buffer.toString());
  230   
  231           List jvmArgs = ManagementFactory.getRuntimeMXBean().getInputArguments();
  232           buffer = new StringBuilder(); 
  233           for (Object arg : jvmArgs) {
  234               buffer.append(" ").append(arg);
  235           }
  236           System.out.println("    JVM args:" + buffer.toString());
  237   
  238           System.out.println("ACTIVEMQ_HOME: " + getActiveMQHome());
  239           System.out.println("ACTIVEMQ_BASE: " + getActiveMQBase());
  240   
  241           ClassLoader cl = getClassLoader();
  242   		Thread.currentThread().setContextClassLoader(cl);
  243   
  244           // Use reflection to run the task.
  245           try {
  246               String[] args = tokens.toArray(new String[tokens.size()]);
  247               Class task = cl.loadClass(TASK_DEFAULT_CLASS);
  248               Method runTask = task.getMethod("main", new Class[] {
  249                   String[].class, InputStream.class, PrintStream.class
  250               });
  251               runTask.invoke(task.newInstance(), new Object[] {
  252                   args, System.in, System.out
  253               });
  254           } catch (InvocationTargetException e) {
  255               throw e.getCause();
  256           }
  257       }
  258   
  259       public void addExtensionDirectory(File directory) {
  260           extensions.add(directory);
  261       }
  262   
  263       public void addClassPathList(String fileList) {
  264           if (fileList != null && fileList.length() > 0) {
  265               StringTokenizer tokenizer = new StringTokenizer(fileList, ";");
  266               while (tokenizer.hasMoreTokens()) {
  267                   addClassPath(new File(tokenizer.nextToken()));
  268               }
  269           }
  270       }
  271   
  272       public void addClassPath(File classpath) {
  273           activeMQClassPath.add(classpath);
  274       }
  275   
  276       /**
  277        * The extension directory feature will not work if the broker factory is
  278        * already in the classpath since we have to load him from a child
  279        * ClassLoader we build for it to work correctly.
  280        * 
  281        * @return true, if extension dir can be used. false otherwise.
  282        */
  283       public boolean canUseExtdir() {
  284           try {
  285               Main.class.getClassLoader().loadClass(TASK_DEFAULT_CLASS);
  286               return false;
  287           } catch (ClassNotFoundException e) {
  288               return true;
  289           }
  290       }
  291   
  292       public ClassLoader getClassLoader() throws MalformedURLException {
  293           if (classLoader == null) {
  294               // Setup the ClassLoader
  295               classLoader = Main.class.getClassLoader();
  296               if (!extensions.isEmpty() || !activeMQClassPath.isEmpty()) {
  297   
  298                   ArrayList<URL> urls = new ArrayList<URL>();
  299   
  300                   for (Iterator<File> iter = activeMQClassPath.iterator(); iter.hasNext();) {
  301                       File dir = iter.next();
  302                       // try{ System.out.println("Adding to classpath: " +
  303                       // dir.getCanonicalPath()); }catch(Exception e){}
  304                       urls.add(dir.toURL());
  305                   }
  306   
  307                   for (Iterator<File> iter = extensions.iterator(); iter.hasNext();) {
  308                       File dir = iter.next();
  309                       if (dir.isDirectory()) {
  310                           File[] files = dir.listFiles();
  311                           if (files != null) {
  312   
  313                               // Sort the jars so that classpath built is
  314                               // consistently
  315                               // in the same order. Also allows us to use jar
  316                               // names to control
  317                               // classpath order.
  318                               Arrays.sort(files, new Comparator() {
  319                                   public int compare(Object o1, Object o2) {
  320                                       File f1 = (File)o1;
  321                                       File f2 = (File)o2;
  322                                       return f1.getName().compareTo(f2.getName());
  323                                   }
  324                               });
  325   
  326                               for (int j = 0; j < files.length; j++) {
  327                                   if (files[j].getName().endsWith(".zip") || files[j].getName().endsWith(".jar")) {
  328                                       // try{ System.out.println("Adding to
  329                                       // classpath: " +
  330                                       // files[j].getCanonicalPath());
  331                                       // }catch(Exception e){}
  332                                       urls.add(files[j].toURL());
  333                                   }
  334                               }
  335                           }
  336                       }
  337                   }
  338   
  339                   URL u[] = new URL[urls.size()];
  340                   urls.toArray(u);
  341                   classLoader = new URLClassLoader(u, classLoader);
  342               }
  343               Thread.currentThread().setContextClassLoader(classLoader);
  344           }
  345           return classLoader;
  346       }
  347   
  348       public void setActiveMQHome(File activeMQHome) {
  349           this.activeMQHome = activeMQHome;
  350       }
  351   
  352       public File getActiveMQHome() {
  353           if (activeMQHome == null) {
  354               if (System.getProperty("activemq.home") != null) {
  355                   activeMQHome = new File(System.getProperty("activemq.home"));
  356               }
  357   
  358               if (activeMQHome == null) {
  359                   // guess from the location of the jar
  360                   URL url = Main.class.getClassLoader().getResource("org/apache/activemq/console/Main.class");
  361                   if (url != null) {
  362                       try {
  363                           JarURLConnection jarConnection = (JarURLConnection)url.openConnection();
  364                           url = jarConnection.getJarFileURL();
  365                           URI baseURI = new URI(url.toString()).resolve("..");
  366                           activeMQHome = new File(baseURI).getCanonicalFile();
  367                           System.setProperty("activemq.home", activeMQHome.getAbsolutePath());
  368                       } catch (Exception ignored) {
  369                       }
  370                   }
  371               }
  372   
  373               if (activeMQHome == null) {
  374                   activeMQHome = new File("../.");
  375                   System.setProperty("activemq.home", activeMQHome.getAbsolutePath());
  376               }
  377           }
  378   
  379           return activeMQHome;
  380       }
  381   
  382       public File getActiveMQBase() {
  383           if (activeMQBase == null) {
  384               if (System.getProperty("activemq.base") != null) {
  385                   activeMQBase = new File(System.getProperty("activemq.base"));
  386               }
  387   
  388               if (activeMQBase == null) {
  389                   activeMQBase = getActiveMQHome();
  390                   System.setProperty("activemq.base", activeMQBase.getAbsolutePath());
  391               }
  392           }
  393   
  394           return activeMQBase;
  395       }
  396   }

Save This Page
Home » activemq-parent-5.3.1-source-release » org.apache » activemq » console » [javadoc | source]