View Javadoc

1   /*
2    *   Copyright 2005 Alvaro Gonzalez de Paz (kortsoft)
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15  */
16  package kortsoft.kmx.bootstrap;
17  
18  import java.io.File;
19  import java.io.FileInputStream;
20  import java.io.FileNotFoundException;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.net.MalformedURLException;
24  import java.net.URL;
25  import java.net.URLClassLoader;
26  import java.util.ArrayList;
27  import java.util.Properties;
28  
29  
30  
31  
32  /***
33   * Class in charge of initial class loading.
34   * It takes a property configuration file (well from the 
35   * classpath in the same package as this class and name
36   * <i>kmxlauncher.properties</i>, well from the 
37   * filename passed as argument to the main function.
38   * <p>These are the properties expected:
39   * <ul>
40   * <li><i>lib.dir</i>: Load all the .jar files from
41   * that directory.</li>
42   * <li><i>resources.dir</i>: Load the directory in the classpath.</li>
43   * <li><i>main.class</i>: The name of the class that must implements
44   * <code>KmxMain</codde>.</li>
45   * </ul></p>
46   * <p>Before execute the Main Class, the Launcher adds a Shutdown Hook.
47   * This hook calls <code>closeServices()</code> on the KmxMain interface.</p>
48   * @author kortatu
49   *
50   */
51  public class KmxLauncher {
52  	public final static String PROP_FILE_NAME ="/kortsoft/kmx/bootstrap/kmxlauncher.properties";
53  	public final static String LIB_DIR_PARAM = "lib.dir";
54  	public final static String RESOURCES_DIR_PARAM = "resources.dir";
55  	public final static String MAIN_CLASS_PARAM = "main.class";
56  	private static KmxMain kmxMain; 
57  	protected static Finalizer finalizador;
58  
59  	protected static class Finalizer extends Thread {
60  		Finalizer() {
61  		}
62  		public void run() {
63  			kmxMain.closeServices();
64  		}
65  	}
66  
67  	/***
68  	 * 
69  	 */
70  	private KmxLauncher() {
71  		super();
72  	}
73  
74  	public static void main(String[] args) throws Exception{
75  		InputStream propIs=null;
76  		if (args.length==1){
77  			String propertiesName=args[0];
78  			File f=new File(propertiesName);
79  			if (!f.canRead()){
80  				System.out.println("Error:No se puede leer el fichero de propiedades "+propertiesName);
81  				System.exit(-1);
82  			}
83  			try {
84  				propIs=new FileInputStream(f);
85  			} catch (FileNotFoundException e1) {			
86  			}
87  		} else {
88  			URL propURL=KmxLauncher.class.getResource(PROP_FILE_NAME);			
89  			propIs=propURL.openStream();
90  		}		
91  		Properties prop=new Properties();
92  		try {			
93  			prop.load(propIs);
94  		} catch (IOException e) {
95  			System.out.println("Error:Al leer el fichero de propiedades : "+e.getLocalizedMessage());
96  		}		
97  		String libDir=prop.getProperty(LIB_DIR_PARAM);
98  		System.out.println("Lib dir= "+libDir);
99  		String resourcesDir=prop.getProperty(RESOURCES_DIR_PARAM);
100 		ClassLoader classLoader=buildClassLoader(libDir,resourcesDir);
101 		String mainClassName=prop.getProperty(MAIN_CLASS_PARAM);
102 		System.out.println("Main class= "+mainClassName);		
103 		try {		
104 			Class mainClass=classLoader.loadClass(mainClassName);
105 			startup(mainClass,prop);
106 		} catch (ClassNotFoundException e) {
107 			System.out.println("Clase principal ["+mainClassName+"] no encontrada en el classpath: "+e);
108 		} catch (Throwable t){
109 			System.out.println("Error al cargar la clase del KmxMain: "+t);
110 			return;
111 		} 
112 	}
113 
114 	/***
115 	 * @param mainClass
116 	 * @param prop
117 	 */
118 	private static void startup(Class mainClass, Properties prop) {
119 		try {
120 			kmxMain=(KmxMain)mainClass.newInstance();
121 		} catch (InstantiationException e) {
122 			System.out.println("Error al crear instancia de ["+mainClass.getName()+"]: "+e);
123 			return; 
124 		} catch (IllegalAccessException e) {
125 			System.out.println("La clase ["+mainClass.getName()+"] no tiene un constructor vac�o visible");
126 			return;
127 		} catch (ClassCastException e) {
128 			System.out.println("La clase ["+mainClass.getName()+"] no cumple el interfaz "+KmxMain.class);
129 			return;
130 		} catch (Throwable t){
131 			System.out.println("Error al iniciar el KmxMain: "+t);
132 			return;
133 		}
134 		finalizador=new Finalizer();
135 		Runtime.getRuntime().addShutdownHook(finalizador);
136 		kmxMain.startup(prop);
137 	}
138 
139 	/***
140 	 * @param libDir
141 	 */
142 	private static ClassLoader buildClassLoader(String libDir, String resourcesDir) {		
143 		URL[] urls;
144 		try {
145 			urls = getClassPath(new File(libDir),new File(resourcesDir));
146 			System.out.println("Urls: "+urls);
147 			URLClassLoader classLoader = new URLClassLoader(urls,KmxMain.class.getClassLoader());			
148 			//Setup context classloader
149 			Thread.currentThread().setContextClassLoader( classLoader );
150 			return classLoader;
151 		} catch (MalformedURLException e) {
152 			throw new RuntimeException(e);		
153 		}
154 		
155 	}
156 	
157 	/***
158 	 * Create a ClassPath for the server.
159 	 *
160 	 * @return the set of URLs that server uses to load
161 	 * @throws Exception if unable to aquire classpath
162 	 */
163 	private static URL[] getClassPath(File libDir,File resourcesDir) throws MalformedURLException {
164 		ArrayList<URL> urls = new ArrayList<URL>();
165 		File[] files = libDir.listFiles();
166 		if (files==null)
167 			return new URL[]{};
168 		for( int i = 0; i < files.length; i++ ) {
169 			File file = files[ i ];
170 			if( (file.getName().endsWith( ".jar" )) || (file.getName().endsWith( ".zip" ))) {
171 				System.out.println("Added new jar to classpath: "+file.getName());
172 				urls.add(file.toURL());
173 			}
174 		}
175 		urls.add(resourcesDir.toURL());
176 		return urls.toArray( new URL[ urls.size() ] );
177 	}
178 }