View Javadoc

1   package org.codehaus.classworlds.uberjar.boot;
2   
3   /*
4    $Id: Bootstrapper.java,v 1.1.1.1 2004/07/01 13:59:19 jvanzyl Exp $
5   
6    Copyright 2002 (C) The Werken Company. All Rights Reserved.
7    
8    Redistribution and use of this software and associated documentation
9    ("Software"), with or without modification, are permitted provided
10   that the following conditions are met:
11  
12   1. Redistributions of source code must retain copyright
13      statements and notices.  Redistributions must also contain a
14      copy of this document.
15   
16   2. Redistributions in binary form must reproduce the
17      above copyright notice, this list of conditions and the
18      following disclaimer in the documentation and/or other
19      materials provided with the distribution.
20   
21   3. The name "classworlds" must not be used to endorse or promote
22      products derived from this Software without prior written
23      permission of The Werken Company.  For written permission,
24      please contact bob@werken.com.
25   
26   4. Products derived from this Software may not be called "classworlds"
27      nor may "classworlds" appear in their names without prior written
28      permission of The Werken Company. "classworlds" is a registered
29      trademark of The Werken Company.
30   
31   5. Due credit should be given to The Werken Company.
32      (http://classworlds.werken.com/).
33   
34   THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS
35   ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
36   NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
37   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
38   THE WERKEN COMPANY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
39   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
41   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
43   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
44   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
45   OF THE POSSIBILITY OF SUCH DAMAGE.
46   
47   */
48  
49  import java.lang.reflect.Method;
50  import java.lang.reflect.Modifier;
51  
52  /***
53   * Bootstrapping entry-point.
54   * <p/>
55   * <p/>
56   * The <code>Bootstrapper</code> is to be used for standalone jars
57   * which carry all dependency jars within them.  The layout for
58   * the dependency jar should be similar to:
59   * </p>
60   * <p/>
61   * <pre>
62   *    myjar/
63   *          classworlds.conf
64   *          org/
65   *              codehaus/
66   *                     classworlds/
67   *                                 boot/
68   *                                 protocol/
69   *          lib/
70   *              myapp.jar
71   *              depOne.jar
72   *              depTwo.jar
73   *  </pre>
74   *
75   * @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a>
76   * @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a>
77   * @version $Id: Bootstrapper.java,v 1.1.1.1 2004/07/01 13:59:19 jvanzyl Exp $
78   */
79  public class Bootstrapper
80  {
81      // ----------------------------------------------------------------------
82      //     Constants
83      // ----------------------------------------------------------------------
84  
85      /***
86       * Main classworlds entry class.
87       */
88      public static final String LAUNCHER_CLASS_NAME = "org.codehaus.classworlds.Launcher";
89  
90      // ----------------------------------------------------------------------
91      //     Instance members
92      // ----------------------------------------------------------------------
93  
94      /***
95       * Command-line args.
96       */
97      private String[] args;
98  
99      /***
100      * Initial bootstrapping classloader.
101      */
102     private InitialClassLoader classLoader;
103 
104     // ----------------------------------------------------------------------
105     //     Class methods
106     // ----------------------------------------------------------------------
107 
108     /***
109      * Main entry-point.
110      *
111      * @param args Command-line arguments.
112      * @throws Exception If an error occurs.
113      */
114     public static void main( String[] args )
115         throws Exception
116     {
117         System.setProperty( "java.protocol.handler.pkgs",
118                             "org.codehaus.classworlds.uberjar.protocol" );
119 
120         Bootstrapper bootstrapper = new Bootstrapper( args );
121 
122         bootstrapper.bootstrap();
123     }
124 
125     // ----------------------------------------------------------------------
126     //     Constructors
127     // ----------------------------------------------------------------------
128 
129     /***
130      * Construct.
131      *
132      * @param args Command-line arguments.
133      * @throws Exception If an error occurs attempting to perform
134      *                   bootstrap initialization.
135      */
136     public Bootstrapper( String[] args )
137         throws Exception
138     {
139         this.args = args;
140         this.classLoader = new InitialClassLoader();
141     }
142 
143     // ----------------------------------------------------------------------
144     //     Instance methods
145     // ----------------------------------------------------------------------
146 
147     /***
148      * Retrieve the initial bootstrapping <code>ClassLoader</code>.
149      *
150      * @return The classloader.
151      */
152     protected ClassLoader getInitialClassLoader()
153     {
154         return this.classLoader;
155     }
156 
157     /***
158      * Perform bootstrap.
159      *
160      * @throws Exception If an error occurs while bootstrapping.
161      */
162     public void bootstrap()
163         throws Exception
164     {
165         ClassLoader cl = getInitialClassLoader();
166 
167         Class launcherClass = cl.loadClass( LAUNCHER_CLASS_NAME );
168 
169         Method[] methods = launcherClass.getMethods();
170         Method mainMethod = null;
171 
172         for ( int i = 0; i < methods.length; ++i )
173         {
174             if ( !"main".equals( methods[i].getName() ) )
175             {
176                 continue;
177             }
178 
179             int modifiers = methods[i].getModifiers();
180 
181             if ( !( Modifier.isStatic( modifiers )
182                 &&
183                 Modifier.isPublic( modifiers ) ) )
184             {
185                 continue;
186             }
187 
188             if ( methods[i].getReturnType() != Void.TYPE )
189             {
190                 continue;
191             }
192 
193             Class[] paramTypes = methods[i].getParameterTypes();
194 
195             if ( paramTypes.length != 1 )
196             {
197                 continue;
198             }
199 
200             if ( paramTypes[0] != String[].class )
201             {
202                 continue;
203             }
204 
205             mainMethod = methods[i];
206             break;
207         }
208 
209         if ( mainMethod == null )
210         {
211             throw new NoSuchMethodException( LAUNCHER_CLASS_NAME + "::main(String[] args)" );
212         }
213 
214         System.setProperty( "classworlds.bootstrapped",
215                             "true" );
216 
217         mainMethod.invoke( launcherClass,
218                            new Object[]{this.args} );
219     }
220 }