1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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 }