View Javadoc

    1   /*
    2    * $Id: Main.java 471756 2006-11-06 15:01:43Z husted $
    3    *
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
    10   * with the License.  You may obtain a copy of the License at
    11   *
    12   *  http://www.apache.org/licenses/LICENSE-2.0
    13   *
    14   * Unless required by applicable law or agreed to in writing,
    15   * software distributed under the License is distributed on an
    16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    17   * KIND, either express or implied.  See the License for the
    18   * specific language governing permissions and limitations
    19   * under the License.
    20   */
    21  package org.apache.struts2;
    22
    23  import java.io.File;
    24  import java.io.FilenameFilter;
    25  import java.lang.reflect.Method;
    26  import java.net.MalformedURLException;
    27  import java.net.URL;
    28  import java.net.URLClassLoader;
    29  import java.util.ArrayList;
    30  import java.util.Collections;
    31  import java.util.List;
    32
    33  /***
    34   * <!-- START SNIPPET: javadoc -->
    35   *
    36   * Struts comes with various related tools included in the struts-core-VERSION.jar file. You can access these
    37   * tools by simply unpacking the Struts distribution and running <b>java -jar struts-core-VERSION.jar</b>.
    38   * Struts will automatically include all jars in the same directory as the struts-core-VERSION.jar file as well as all
    39   * jars in the <i>lib</i> directory. This means you can invoke these tools either from within the standard directory
    40   * structure found in the Struts distribution, or from within your WEB-INF/lib directory.
    41   *
    42   * <p/> You can access the help information for these tools by simply running the jar without any arguments.
    43   *
    44   * <!-- END SNIPPET: javadoc -->
    45   */
    46  public class Main {
    47      public static void main(String[] args) {
    48          if (args.length == 0) {
    49              System.out.println("Usage:");
    50              System.out.println("  java -jar struts-toolbox.jar [command] (optional command args)");
    51              System.out.println("");
    52              System.out.println("Where [command] is one of the following:");
    53              System.out.println("  sitegraph");
    54              System.out.println("  sitegraph:xxx");
    55              System.out.println("");
    56              System.out.println("Execute the commands for additional usage instructions.");
    57              System.out.println("Note: the *:xxx commands are just shortcuts for ");
    58              System.out.println("      running the command on a webapp in the apps dir.");
    59              return;
    60          }
    61
    62          // check the JDK version
    63          String version = System.getProperty("java.version");
    64          boolean jdk15 = version.indexOf("1.5") != -1;
    65
    66          String javaHome = System.getProperty("java.home");
    67          ArrayList<URL> urls = new ArrayList<URL>();
    68          try {
    69              findJars(new File("lib"), urls);
    70
    71              // use all the jars in the current that aren't the src jar
    72              File wd = new File(".");
    73              File[] jars = wd.listFiles(new FilenameFilter() {
    74                  public boolean accept(File dir, String name) {
    75                      return name.endsWith(".jar") && name.indexOf("-src.") == -1;
    76                  }
    77              });
    78              for (int i = 0; i < jars.length; i++) {
    79                  File jar = jars[i];
    80                  urls.add(jar.toURL());
    81              }
    82
    83              // ... but there might not be any (ie: we're in development in IDEA), so use this as backup
    84              urls.add(new File(System.getProperty("struts.classes", "build/java")).toURL());
    85              urls.add(new File(System.getProperty("xwork.classes", "../xwork/build/java/")).toURL());
    86
    87              // load tools.jar from JAVA_HOME
    88              File tools = new File(javaHome, "lib/tools.jar");
    89              if (!tools.exists()) {
    90                  // hmm, not there, how about java.home?
    91                  tools = new File(javaHome, "../lib/tools.jar");
    92              }
    93              if (!tools.exists()) {
    94                  // try the OS X common path
    95                  tools = new File(javaHome, "../Classes/classes.jar");
    96              }
    97              if (!tools.exists()) {
    98                  // try the other OS X common path
    99                  tools = new File(javaHome, "../Classes/classes.jar");
    100             }
    101             if (!tools.exists()) {
    102                 // did the user specify it by hand?
    103                 String prop = System.getProperty("tools");
    104                 if (prop != null) {
    105                     tools = new File(prop);
    106                 }
    107             }
    108             if (!tools.exists()) {
    109                 System.out.println("Error: Could not find tools.jar! Please do one of the following: ");
    110                 System.out.println("");
    111                 System.out.println("        - Use the JDK's JVM (ie: c://jdk1.5.0//bin//java)");
    112                 System.out.println("        - Specify JAVA_HOME to point to your JDK 1.5 home");
    113                 System.out.println("        - Specify a direct path to tools.jar via, as shown below:");
    114                 System.out.println("");
    115                 System.out.println("       java -Dtools=/path/to/tools.jar -jar struts.jar ...");
    116                 return;
    117             }
    118
    119             // finally, add the verified tools.jar
    120             urls.add(tools.toURL());
    121         } catch (MalformedURLException e) {
    122             e.printStackTrace();
    123             System.out.println("Could not find URLs -- see stack trace.");
    124         }
    125
    126         String command = args[0];
    127         String[] programArgs = new String[args.length - 1];
    128         System.arraycopy(args, 1, programArgs, 0, programArgs.length);
    129
    130         if (command.startsWith("sitegraph:")) {
    131             command = "sitegraph";
    132             String name = checkWebAppArgs(args);
    133             programArgs = new String[]{"-config", "apps/" + name + "/src/webapp/WEB-INF/classes",
    134                     "-views", "apps/" + name + "/src/webapp",
    135                     "-output", "."};
    136         }
    137
    138         if ("sitegraph".equals(command)) {
    139             launch("org.apache.struts2.sitegraph.SiteGraph", programArgs, urls);
    140         }
    141     }
    142
    143     private static String checkWebAppArgs(String[] args) {
    144         int colon = args[0].indexOf(':');
    145         String name = null;
    146         try {
    147             name = args[0].substring(colon + 1);
    148         } catch (Exception e) {
    149             //this is OK to skip
    150         }
    151         if (name == null || name.equals("")) {
    152             System.out.println("Error: you must specify the webapp you wish");
    153             System.out.println("       to deploy. The webapp name must be the");
    154             System.out.println("       name of the directory found in apps/.");
    155             System.out.println("");
    156             System.out.println("Example: java -jar struts-core-VERSION.jar quickstart:sandbox");
    157             System.exit(1);
    158         }
    159
    160         return name;
    161     }
    162
    163     private static void launch(String program, String[] programArgs, List<URL> urls) {
    164         Collections.reverse(urls);
    165         URL[] urlArray = urls.toArray(new URL[urls.size()]);
    166         URLClassLoader cl = new MainClassLoader(urlArray);
    167         Thread.currentThread().setContextClassLoader(cl);
    168         try {
    169             Class clazz = cl.loadClass(program);
    170             Method main = clazz.getDeclaredMethod("main", new Class[]{String[].class});
    171             main.invoke(null, new Object[]{programArgs});
    172         } catch (Exception e) {
    173             e.printStackTrace();
    174         }
    175     }
    176
    177     private static void findJars(File file, ArrayList<URL> urls) throws MalformedURLException {
    178         File[] files = file.listFiles();
    179         if (files == null) {
    180             return;
    181         }
    182
    183         for (int i = 0; i < files.length; i++) {
    184             File f = files[i];
    185             if (f.isDirectory()) {
    186                 findJars(f, urls);
    187             } else if (f.getName().endsWith(".jar")) {
    188                 if (isValid(f.getName())) {
    189                     urls.add(f.toURL());
    190                 }
    191             }
    192         }
    193     }
    194
    195     private static boolean isValid(String name) {
    196         return !"dom.jar".equals(name);
    197     }
    198
    199     /***
    200      * Reverses the typical order of classloading to defer only to the parent if the current class loader can't be
    201      * found. This is required to allow for the launcher to be embedded within struts.jar (otherwise the dependencies
    202      * wouldn't be found by the system ClassLoader when invoking using "java -jar struts-core-VERSION.jar ...").
    203      */
    204     public static class MainClassLoader extends URLClassLoader {
    205         public MainClassLoader(URL[] urls) {
    206             super(urls);
    207         }
    208
    209         public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    210             if (name.startsWith("org.xml.") || name.startsWith("org.w3c.")
    211                     || name.startsWith("java.") || name.startsWith("javax.")
    212                     || name.startsWith("sun.") || name.startsWith("com.sun.")) {
    213                 return super.loadClass(name, resolve);
    214             }
    215
    216             ClassLoader parent = getParent();
    217             // First, check if the class has already been loaded
    218             Class c = findLoadedClass(name);
    219             if (c == null) {
    220                 try {
    221                     c = findClass(name);
    222                 } catch (Throwable t) {
    223                     // If still not found, only then ask the parent
    224                     c = parent.loadClass(name);
    225                 }
    226             }
    227             if (resolve) {
    228                 resolveClass(c);
    229             }
    230
    231             return c;
    232         }
    233     }
    234 }