KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > client > ClientContainer


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999-2005 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or 1any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: ClientContainer.java,v 1.36 2005/04/25 19:26:54 ashah Exp $
23  * --------------------------------------------------------------------------
24  */

25 package org.objectweb.jonas.client;
26
27 import java.io.File JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.lang.reflect.InvocationTargetException JavaDoc;
30 import java.lang.reflect.Method JavaDoc;
31 import java.net.MalformedURLException JavaDoc;
32 import java.net.URL JavaDoc;
33 import java.net.URLClassLoader JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.StringTokenizer JavaDoc;
39 import java.util.jar.Attributes JavaDoc;
40 import java.util.jar.JarFile JavaDoc;
41 import java.util.jar.Manifest JavaDoc;
42
43 import javax.naming.Context JavaDoc;
44 import javax.naming.LinkRef JavaDoc;
45 import javax.naming.NamingException JavaDoc;
46 import javax.naming.Reference JavaDoc;
47 import javax.naming.StringRefAddr JavaDoc;
48 import javax.security.auth.callback.CallbackHandler JavaDoc;
49 import javax.security.auth.login.LoginContext JavaDoc;
50
51 import org.objectweb.carol.util.configuration.CarolDefaultValues;
52 import org.objectweb.carol.util.configuration.ConfigurationRepository;
53
54
55 import org.objectweb.jonas_client.deployment.api.ClientContainerDeploymentDesc;
56 import org.objectweb.jonas_client.deployment.api.ClientContainerDeploymentDescException;
57 import org.objectweb.jonas_client.deployment.lib.ClientDeploymentDescManager;
58
59 import org.objectweb.jonas_ear.deployment.api.EarDeploymentDesc;
60 import org.objectweb.jonas_ear.deployment.api.EarDeploymentDescException;
61 import org.objectweb.jonas_ear.deployment.lib.EarDeploymentDescManager;
62 import org.objectweb.jonas_ear.deployment.xml.Web;
63
64 import org.objectweb.jonas_ejb.deployment.lib.EjbDeploymentDescManager;
65
66 import org.objectweb.jonas_lib.deployment.api.EjbRefDesc;
67 import org.objectweb.jonas_lib.deployment.api.EnvEntryDesc;
68 import org.objectweb.jonas_lib.deployment.api.MessageDestinationRefDesc;
69 import org.objectweb.jonas_lib.deployment.api.ResourceEnvRefDesc;
70 import org.objectweb.jonas_lib.deployment.api.ResourceRefDesc;
71 import org.objectweb.jonas_lib.deployment.work.EarFileManager;
72 import org.objectweb.jonas_lib.naming.ContainerNaming;
73
74 import org.objectweb.jonas_web.deployment.lib.WebDeploymentDescManager;
75
76 import org.objectweb.jonas_ws.deployment.api.ServiceRefDesc;
77
78 import org.objectweb.jonas.common.Log;
79 import org.objectweb.jonas.ear.lib.EarClassPathManager;
80 import org.objectweb.jonas.ear.lib.EarClassPathManagerException;
81 import org.objectweb.jonas.ear.lib.JarList;
82 import org.objectweb.jonas.ear.lib.JarListException;
83 import org.objectweb.jonas.naming.NamingManager;
84 import org.objectweb.jonas.security.auth.callback.NoInputCallbackHandler;
85 import org.objectweb.jonas.security.jacc.JPolicyUserRoleMapping;
86 import org.objectweb.jonas.ws.ClientJServiceFactoryFinder;
87 import org.objectweb.jonas.ws.JServiceFactory;
88
89 import org.objectweb.util.monolog.api.BasicLevel;
90 import org.objectweb.util.monolog.api.Logger;
91
92 /**
93  * Defines the class use for the client container This class analyze the ear or
94  * the jar client and launch the client
95  * @author Florent Benoit
96  */

97 public class ClientContainer {
98
99     /**
100      * Name of the carol file
101      */

102     private static final String JavaDoc CAROL_FILE = "carol.properties";
103
104     /**
105      * Main class to use to launch the application client
106      */

107     private String JavaDoc mainClass = null;
108
109     /**
110      * Temporary directory
111      */

112     private String JavaDoc tmpDir = null;
113
114     /**
115      * Jar client to use (if many)
116      */

117     private String JavaDoc jarClient = null;
118
119     /**
120      * Classpath for the application client
121      */

122     private String JavaDoc classpath = null;
123
124     /**
125      * trace.properties file to use instead of the default file.
126      */

127     private String JavaDoc clientTraceFile = null;
128
129     /**
130      * Reference on the NamingManager.
131      */

132     private ContainerNaming naming;
133
134     /**
135      * carol.properties file to use instead of the default file.
136      */

137     private String JavaDoc carolFile = null;
138
139     /**
140      * Arguments used by the client
141      */

142     private String JavaDoc[] args = null;
143
144     /**
145      * Class loader of the EAR
146      */

147     private URLClassLoader JavaDoc earClassLoader = null;
148
149     /**
150      * Extra Arguments
151      */

152     private ArrayList JavaDoc appArgs = null;
153
154     /**
155      * URLs resolved in the case of the extension mechanism in the Ear case
156      */

157     private URL JavaDoc[] extensionsURLs = null;
158
159     /**
160      * Logger to use
161      */

162     private Logger logger = null;
163
164     /**
165      * Constructor for a Client container
166      * @param args the arguments of the instance of the client container
167      */

168     private ClientContainer(String JavaDoc[] args) {
169         this.args = args;
170
171         appArgs = new ArrayList JavaDoc();
172     }
173
174     /**
175      * Call the Log class to instanciate the client container logger
176      */

177     private void initLogger() {
178         // Allow tracing ejb/jms code
179
Log.configure(clientTraceFile);
180         // init the logger
181
this.logger = Log.getLogger(Log.JONAS_CLIENT_PREFIX);
182     }
183
184     /**
185      * Main method of the Client container
186      * @param args the arguments of the client container
187      */

188     public static void main(String JavaDoc[] args) {
189         // Retrieve command line parameters
190
ClientContainer cc = new ClientContainer(args);
191
192         try {
193             cc.start();
194         } catch (InvocationTargetException JavaDoc ite) {
195             Throwable JavaDoc t = ite.getTargetException();
196             String JavaDoc message = t.getMessage();
197             if (t instanceof Error JavaDoc) {
198                 System.err.println("There was the following error : " + message);
199             } else if (t instanceof Exception JavaDoc) {
200                 System.err.println("There was the following exception : " + message);
201             }
202             t.printStackTrace(System.err);
203         } catch (Exception JavaDoc e) {
204             System.err.println("There was the following exception : " + e.getMessage());
205             e.printStackTrace();
206             System.exit(-1);
207         }
208     }
209
210     /**
211      * Start the client container
212      * @throws Exception if it fails
213      */

214     private void start() throws Exception JavaDoc {
215         analyzeArgs();
216
217         // Use the specified traceclient.properties
218
if (clientTraceFile != null) {
219             File JavaDoc tClient = new File JavaDoc(clientTraceFile);
220
221             if (!tClient.exists()) {
222                 throw new ClientContainerException("The file '" + clientTraceFile + "' was not found.");
223             }
224
225             if (!tClient.isFile()) {
226                 throw new ClientContainerException("The file '" + clientTraceFile
227                         + "' is not a valid file. Maybe a directory ?");
228             }
229
230             // Configure log
231
System.setProperty("jonas.client.trace.file", clientTraceFile);
232             Log.reset();
233         } else {
234             clientTraceFile = "traceclient";
235         }
236
237         initLogger();
238
239         // Get the filename
240
String JavaDoc userArg = null;
241         String JavaDoc fileName = null;
242         boolean fileMode = true;
243
244         try {
245             userArg = (String JavaDoc) appArgs.get(0);
246         } catch (IndexOutOfBoundsException JavaDoc ioobe) {
247             usage();
248             throw new ClientContainerException(
249                     "You haven't specify a jar, an ear file or class name as argument. See the Usage.");
250         }
251
252         String JavaDoc className = null;
253         // Test if this is an ear or a jar file else it must be a class name
254
if (!(userArg.toLowerCase().endsWith(".jar") || userArg.toLowerCase().endsWith(".ear"))) {
255             className = userArg;
256             fileMode = false;
257         } else {
258             fileMode = true;
259             fileName = userArg;
260         }
261
262         // Build file and test if it exists
263
File JavaDoc clientJarFile = null;
264         if (fileMode) {
265             File JavaDoc argFile = new File JavaDoc(fileName);
266
267             if (!argFile.exists()) {
268                 throw new ClientContainerException("The specified file '" + fileName + "' doesn't exists.");
269             }
270
271             // Unpack and analyze EAR file if it is an ear
272
if (fileName.toLowerCase().endsWith(".ear")) {
273                 clientJarFile = extractAndAnalyzeEar(argFile);
274             } else {
275                 //Client jar is the given file
276
clientJarFile = argFile;
277             }
278         }
279
280         // Carol initialisation (property)
281
System.setProperty("javax.rmi.CORBA.PortableRemoteObjectClass",
282                            "org.objectweb.carol.rmi.multi.MultiPRODelegate");
283         System.setProperty("java.naming.factory.initial", "org.objectweb.carol.jndi.spi.MultiOrbInitialContextFactory");
284         System.setProperty("org.omg.PortableInterceptor.ORBInitializerClass.org.objectweb.jotm.ots.OTSORBInitializer",
285                            "");
286         System.setProperty("org.omg.PortableInterceptor.ORBInitializerClass.org.objectweb.jonas.security.interceptors.iiop.SecurityInitializer",
287                            "");
288         System.setProperty("org.omg.CORBA.ORBClass" , "org.jacorb.orb.ORB");
289         System.setProperty("org.omg.CORBA.ORBSingletonClass", "org.jacorb.orb.ORBSingleton");
290         System.setProperty("org.omg.PortableInterceptor.ORBInitializerClass.standard_init" , "org.jacorb.orb.standardInterceptors.IORInterceptorInitializer");
291         System.setProperty("javax.rmi.CORBA.UtilClass" , "org.objectweb.carol.util.delegate.UtilDelegateImpl");
292
293         // force JAX-RPC 1.1 Axis compliance
294
System.setProperty("axis.jaxrpc11Compliance", "true");
295
296         // Build a classloader for the initialisation of carol
297
// Priority
298
// 1/ file as argument
299
// 2/ file in the jar client
300
// 3/ file in client.jar
301
URL JavaDoc urlCarolFile = null;
302
303         if (carolFile != null) {
304             File JavaDoc fCarol = new File JavaDoc(carolFile);
305
306             if (!fCarol.exists()) {
307                 throw new ClientContainerException("The file '" + carolFile + "' was not found.");
308             }
309
310             if (!fCarol.isFile()) {
311                 throw new ClientContainerException("The file '" + carolFile
312                         + "' is not a valid file. Maybe a directory ?");
313             }
314
315             if (!fCarol.getName().equals(CAROL_FILE)) {
316                 throw new ClientContainerException("The file '" + carolFile + "' must be named '" + CAROL_FILE + "'.");
317             }
318
319             try {
320                 urlCarolFile = fCarol.toURL();
321                 if (logger.isLoggable(BasicLevel.DEBUG)) {
322                     logger.log(BasicLevel.DEBUG, "Using carol.properties file specified by the user on command line");
323                 }
324             } catch (MalformedURLException JavaDoc mue) {
325                 throw new ClientContainerException("Error when building an URL for the file '" + fCarol + "'.", mue);
326             }
327         }
328
329         // carol.properties file in client jar, use it if this is the case ?
330
if (urlCarolFile == null && fileMode) {
331             URL JavaDoc tmpUrl = null;
332             try {
333                 tmpUrl = clientJarFile.toURL();
334             } catch (MalformedURLException JavaDoc mue) {
335                 throw new ClientContainerException("Error when building an URL for the file '" + clientJarFile + "'.", mue);
336             }
337             // Build classloader with null parent CL, to see if it is in the file.
338
ClassLoader JavaDoc tmpCl = new URLClassLoader JavaDoc(new URL JavaDoc[] {tmpUrl}, null);
339
340             urlCarolFile = tmpCl.getResource(CarolDefaultValues.CAROL_CONFIGURATION_FILE);
341             if (urlCarolFile != null) {
342                 if (logger.isLoggable(BasicLevel.DEBUG)) {
343                     logger.log(BasicLevel.DEBUG, "Using carol.properties file of the '" + clientJarFile + "' file.");
344                 }
345             }
346         }
347
348
349
350         if (urlCarolFile != null) {
351             if (logger.isLoggable(BasicLevel.DEBUG)) {
352                 logger.log(BasicLevel.DEBUG, "Init carol with URL '" + urlCarolFile + "'.");
353             }
354             ConfigurationRepository.init(urlCarolFile);
355         } else {
356             ConfigurationRepository.init();
357         }
358         // Add Csiv2 Interceptors
359
ConfigurationRepository.addInterceptors("iiop", "org.objectweb.jonas.security.iiop.Csiv2Initializer");
360
361
362         // Carol configuration is done
363
// Extract Main-Class to use in the jar from the manifest
364
if (fileMode) {
365             Manifest JavaDoc manifest = new JarFile JavaDoc(clientJarFile).getManifest();
366
367             if (manifest == null) {
368                 throw new ClientContainerException("No manifest was found inside the file" + clientJarFile);
369             }
370
371             // Extract attributes
372
Attributes JavaDoc attributes = manifest.getMainAttributes();
373
374             if (attributes == null) {
375                 throw new ClientContainerException("No attributes were found in the manifest of the file '"
376                         + clientJarFile + "'.");
377             }
378             mainClass = attributes.getValue(Attributes.Name.MAIN_CLASS);
379         } else {
380             mainClass = className;
381         }
382
383         // Invoke the client if there is no need of XML parsing
384
if (!fileMode) {
385             ClassLoader JavaDoc clientCL = new URLClassLoader JavaDoc(getUserClasspathUrls());
386             Thread.currentThread().setContextClassLoader(clientCL);
387             invokeClient();
388             return;
389         }
390
391         if (mainClass == null || mainClass.length() == 0) {
392             throw new ClientContainerException("No main class was found inside the Manifest of the file '"
393                     + clientJarFile + "'. This attribute is required to launch the application client.");
394         }
395
396         if (logger.isLoggable(BasicLevel.DEBUG)) {
397             logger.log(BasicLevel.DEBUG, "Using Main-Class :" + mainClass);
398         }
399
400         // Convert file to URL
401
URL JavaDoc clientJarURL = null;
402
403         try {
404             clientJarURL = clientJarFile.toURL();
405         } catch (MalformedURLException JavaDoc mue) {
406             throw new ClientContainerException("Error when building an URL with the file '" + clientJarFile + "'.", mue);
407         }
408
409         // Build the urls for the classloader
410
URL JavaDoc[] urlsClient = null;
411
412         // URLs for the classloader
413
if (extensionsURLs != null) {
414             // There were URLs with the extension mechanism in the EAR
415
urlsClient = new URL JavaDoc[extensionsURLs.length + 1];
416
417             for (int i = 0; i < extensionsURLs.length; i++) {
418                 urlsClient[i] = extensionsURLs[i];
419
420                 if (logger.isLoggable(BasicLevel.DEBUG)) {
421                     logger.log(BasicLevel.DEBUG, "Adding " + extensionsURLs[i] + " to the urls of the client");
422                 }
423             }
424
425             urlsClient[extensionsURLs.length] = clientJarURL;
426         } else {
427             if (logger.isLoggable(BasicLevel.DEBUG)) {
428                 logger.log(BasicLevel.DEBUG, "Only one url for urls of client");
429             }
430
431             // No extension or jar case.
432
urlsClient = new URL JavaDoc[1];
433             urlsClient[0] = clientJarURL;
434         }
435
436         // Build classloader
437
URLClassLoader JavaDoc clientClassloader = new URLClassLoader JavaDoc(urlsClient, Thread.currentThread()
438                 .getContextClassLoader());
439         Thread.currentThread().setContextClassLoader(clientClassloader);
440
441         // Get the deployment descriptor from file
442
ClientContainerDeploymentDesc clientDD = null;
443         if (extensionsURLs != null) {
444             EjbDeploymentDescManager.getInstance().addClassLoaderUrlMapping(clientClassloader, extensionsURLs);
445         }
446
447         try {
448             clientDD = ClientDeploymentDescManager.getInstance().getDeploymentDesc(clientJarURL, clientClassloader, earClassLoader);
449         } catch (ClientContainerDeploymentDescException e) {
450             String JavaDoc err = "Cannot read the deployment descriptors '" + clientJarURL + "'";
451             error(err);
452             throw new ClientContainerException(err, e);
453         }
454
455         // Populate the java:comp/env (ENC) environment.
456
try {
457             setClientEnvironment(clientDD);
458         } catch (Exception JavaDoc e) {
459             //populating environment failed.
460
String JavaDoc err = "Error when populating ";
461             error(err);
462             throw new ClientContainerException(err, e);
463         }
464
465         // JAAS
466
String JavaDoc jaasFile = clientDD.getJaasFile();
467         String JavaDoc jaasEntry = clientDD.getJaasEntry();
468         String JavaDoc username = clientDD.getUsername();
469         String JavaDoc password = clientDD.getPassword();
470
471         if (logger.isLoggable(BasicLevel.DEBUG)) {
472             logger.log(BasicLevel.DEBUG, "Using jaas file = " + jaasFile);
473         }
474
475         String JavaDoc jaasConfigFile = null;
476
477         if (jaasFile != null) {
478             // Use JAAS
479
jaasConfigFile = "jar:" + clientJarURL.toExternalForm() + "!/" + jaasFile;
480             System.setProperty("java.security.auth.login.config", jaasConfigFile);
481         }
482
483         CallbackHandler JavaDoc ch = null;
484
485         if ((username != null) && (password != null)) {
486             ch = new NoInputCallbackHandler(username, password);
487             info("Using the login/password specified in the jonas-client.xml file with a specific CallbackHandler");
488         } else {
489             // Is there a callbackHandler specified ?
490
String JavaDoc ddCallbackHandler = clientDD.getCallbackHandler();
491
492             if (ddCallbackHandler != null) {
493                 if (logger.isLoggable(BasicLevel.DEBUG)) {
494                     logger.log(BasicLevel.DEBUG, "Using '" + ddCallbackHandler + "' class as CallbackHandler.");
495                 }
496
497                 Class JavaDoc clazz = null;
498
499                 //try to invoke this class
500
try {
501                     clazz = clientClassloader.loadClass(ddCallbackHandler);
502                 } catch (Exception JavaDoc e) {
503                     throw new ClientContainerException("There was an error while trying to instantiate the class '"
504                             + ddCallbackHandler
505                             + "' which is specified in the application.xml as CallbackHandler class", e);
506                 }
507
508                 try {
509                     ch = (CallbackHandler JavaDoc) clazz.newInstance();
510                 } catch (Exception JavaDoc e) {
511                     throw new ClientContainerException(
512                             "Error while triyng to cast the class '"
513                                     + ddCallbackHandler
514                                     + "' to CallbackHandler interface, maybe the specified class doesn't implement this interface.",
515                             e);
516                 }
517             }
518         }
519
520         // Use JAAS
521
if (ch != null) {
522             if (jaasFile == null) {
523                 throw new ClientContainerException(
524                         "You have defined that you want use a CallbackHandler but you haven't specify the jaas file to use for the JAAS configuration.");
525             }
526
527             if (jaasEntry == null) {
528                 throw new ClientContainerException(
529                         "You have defined that you want use a CallbackHandler but you haven't specify the jaas entry to use from the jaas config file.");
530             }
531
532             info("Using JAAS loginContext '" + jaasEntry + "' from the file '" + jaasConfigFile + "'.");
533
534             try {
535                 LoginContext JavaDoc lc = new LoginContext JavaDoc(jaasEntry, ch);
536                 lc.login();
537             } catch (Exception JavaDoc e) {
538                 String JavaDoc err = "Can not use the JAAS authentication";
539                 error(err);
540                 throw new ClientContainerException(err, e);
541             }
542         }
543
544         // Start client
545
invokeClient();
546
547     }
548
549     /**
550      * Start the client on its main class with the thread class loader
551      * @throws ClassNotFoundException if class is not found
552      * @throws NoSuchMethodException if method (main) is not found
553      * @throws IllegalAccessException if access is illegal
554      * @throws InvocationTargetException if invocation failed
555      */

556     private void invokeClient() throws ClassNotFoundException JavaDoc, NoSuchMethodException JavaDoc, IllegalAccessException JavaDoc,
557             InvocationTargetException JavaDoc {
558         ClassLoader JavaDoc clientClassloader = Thread.currentThread().getContextClassLoader();
559
560         if (logger.isLoggable(BasicLevel.DEBUG)) {
561             if (clientClassloader instanceof URLClassLoader JavaDoc) {
562                 URLClassLoader JavaDoc urlClassLoader = (URLClassLoader JavaDoc) clientClassloader;
563                 URL JavaDoc[] urls = urlClassLoader.getURLs();
564                 logger.log(BasicLevel.DEBUG, "URLs of the classloader :");
565                 for (int u = 0; u < urls.length; u++) {
566                     logger.log(BasicLevel.DEBUG, "URL[" + u + "] = " + urls[u]);
567                 }
568             }
569         }
570
571         // Invoke client
572
// Launch the "class_to_run" by using our classloader.
573
Class JavaDoc clazz = clientClassloader.loadClass(mainClass);
574         Class JavaDoc[] argList = new Class JavaDoc[] {args.getClass()};
575         Method JavaDoc meth = clazz.getMethod("main", argList);
576
577         // Remove name of the file from arguments
578
String JavaDoc[] newArgs = new String JavaDoc[appArgs.size() - 1];
579         String JavaDoc txtArgs = "";
580
581         for (int i = 0; i < newArgs.length; i++) {
582             newArgs[i] = (String JavaDoc) appArgs.get(i + 1);
583             txtArgs += (newArgs[i] + " ");
584         }
585
586         if (logger.isLoggable(BasicLevel.DEBUG)) {
587             logger.log(BasicLevel.DEBUG, "Starting the application client with the arguments '" + txtArgs + "'.");
588         }
589
590         info("Starting client...");
591
592         meth.invoke(null, new Object JavaDoc[] {newArgs});
593
594         if (logger.isLoggable(BasicLevel.DEBUG)) {
595             logger.log(BasicLevel.DEBUG, "End of main method");
596         }
597
598     }
599
600     /**
601      * Set the environment of this client
602      * @param clientDD deployment descriptor used for build the environment
603      * @throws NamingException if the creation of the environment fails
604      */

605     private void setClientEnvironment(ClientContainerDeploymentDesc clientDD) throws NamingException JavaDoc {
606         if (logger.isLoggable(BasicLevel.DEBUG)) {
607             logger.log(BasicLevel.DEBUG, "");
608         }
609
610         //Init the naming manager
611
try {
612             naming = NamingManager.getInstance();
613         } catch (NamingException JavaDoc e) {
614             throw new ClientContainerException("Error when getting the reference to the Naming manager", e);
615         }
616
617         Context JavaDoc javaCtx = naming.createEnvironmentContext("ClientContainer");
618         naming.setClientContainerComponentContext(javaCtx);
619
620         Context JavaDoc envCtx = javaCtx.createSubcontext("comp/env");
621
622         // Bean Environment
623
EnvEntryDesc[] envt = clientDD.getEnvEntryDesc();
624
625         for (int i = 0; i < envt.length; i++) {
626             // get information in descriptor
627
String JavaDoc name = envt[i].getName();
628             Object JavaDoc obj = envt[i].getValue();
629
630             // register object in JNDI
631
if (logger.isLoggable(BasicLevel.DEBUG)) {
632                 logger.log(BasicLevel.DEBUG, "Binding object " + name + " -> " + obj);
633             }
634
635             envCtx.rebind(name, obj);
636         }
637
638         // Resource References
639
ResourceRefDesc[] resref = clientDD.getResourceRefDesc();
640
641         for (int i = 0; i < resref.length; i++) {
642             // get information in descriptor
643
String JavaDoc name = resref[i].getName();
644             String JavaDoc resname = resref[i].getJndiName();
645             String JavaDoc type = resref[i].getTypeName();
646
647             // build the LinkRef that will be registered:
648
// FactoryClassName = null, size = 1, refAddr = resname.
649
// register object in JNDI
650
if (logger.isLoggable(BasicLevel.DEBUG)) {
651                 logger.log(BasicLevel.DEBUG, "Linking resource " + name + " -> " + resname);
652             }
653
654             if (type.equalsIgnoreCase("java.net.URL")) {
655                 // Specify the factory to use with the right URL
656
Reference JavaDoc ref = new Reference JavaDoc("java.net.URL", "org.objectweb.jonas_lib.naming.factory.URLFactory", null);
657                 StringRefAddr JavaDoc refAddr = new StringRefAddr JavaDoc("url", resname);
658                 ref.add(refAddr);
659                 envCtx.rebind(name, ref);
660             } else {
661                 LinkRef JavaDoc lref = new LinkRef JavaDoc(resname);
662                 envCtx.rebind(name, lref);
663             }
664         }
665
666         // Resource Environment References
667
ResourceEnvRefDesc[] resEnvref = clientDD.getResourceEnvRefDesc();
668
669         for (int i = 0; i < resEnvref.length; i++) {
670             // get information in descriptor
671
String JavaDoc name = resEnvref[i].getName();
672             String JavaDoc resname = resEnvref[i].getJndiName();
673             LinkRef JavaDoc lref = new LinkRef JavaDoc(resname);
674
675             if (logger.isLoggable(BasicLevel.DEBUG)) {
676                 logger.log(BasicLevel.DEBUG, "Linking resource environment " + name + " -> " + resname);
677             }
678
679             envCtx.rebind(name, lref);
680         }
681
682         // EJB References
683
EjbRefDesc[] ejbref = clientDD.getEjbRefDesc();
684
685         for (int i = 0; i < ejbref.length; i++) {
686             // get information in descriptor
687
String JavaDoc name = ejbref[i].getEjbRefName();
688             String JavaDoc ejbname = null;
689             ejbname = ejbref[i].getJndiName();
690
691             LinkRef JavaDoc lref = new LinkRef JavaDoc(ejbname);
692
693             if (logger.isLoggable(BasicLevel.DEBUG)) {
694                 logger.log(BasicLevel.DEBUG, "Linking ejb " + name + " -> " + ejbname);
695             }
696
697             envCtx.rebind(name, lref);
698         }
699
700         // ServiceRef
701
ServiceRefDesc[] serviceRefs = clientDD.getServiceRefDesc();
702         if (serviceRefs.length != 0) {
703
704             // get the current ClassLoader
705
ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
706
707             // get the JServiceFactory
708
JServiceFactory factory = ClientJServiceFactoryFinder.getJOnASServiceFactory();
709
710             for (int i = 0; i < serviceRefs.length; i++) {
711                 // Create the Service from the ServiceRef description
712
String JavaDoc refname = serviceRefs[i].getServiceRefName();
713
714                 Reference JavaDoc ref = factory.getServiceReference(serviceRefs[i], loader);
715                 envCtx.rebind(refname, ref);
716
717                 if (logger.isLoggable(BasicLevel.DEBUG)) {
718                     logger.log(BasicLevel.DEBUG, "Adding service-ref 'java:comp/env/" + refname + "'");
719                 }
720             }
721         }
722
723         // MessageDestination References
724
MessageDestinationRefDesc[] mdref = clientDD.getMessageDestinationRefDesc();
725
726         for (int i = 0; i < mdref.length; i++) {
727             // get information in descriptor
728
String JavaDoc name = mdref[i].getMessageDestinationRefName();
729             String JavaDoc mdname = null;
730             mdname = mdref[i].getJndiName();
731
732             LinkRef JavaDoc lref = new LinkRef JavaDoc(mdname);
733
734             if (logger.isLoggable(BasicLevel.DEBUG)) {
735                 logger.log(BasicLevel.DEBUG, "Linking message-destination-ref " + name + " -> " + mdname);
736             }
737
738             envCtx.rebind(name, lref);
739         }
740     }
741
742     /**
743      * Analyze arguments and extract parameters for the client container
744      * @throws Exception if there is an error when analyzing arguments
745      */

746     private void analyzeArgs() throws Exception JavaDoc {
747         for (int argn = 0; argn < args.length; argn++) {
748             String JavaDoc arg = args[argn];
749
750             try {
751                 if (arg.equals("-tmpDir")) {
752                     tmpDir = args[++argn];
753
754                     continue;
755                 }
756
757                 if (arg.equals("-jarClient")) {
758                     jarClient = args[++argn];
759
760                     continue;
761                 }
762
763                 if (arg.equals("-traceFile")) {
764                     clientTraceFile = args[++argn];
765
766                     continue;
767                 }
768
769                 if (arg.equals("-carolFile")) {
770                     carolFile = args[++argn];
771
772                     continue;
773                 }
774
775                 if (arg.equals("-cp")) {
776                     classpath = args[++argn];
777                     continue;
778                 }
779
780                 if (arg.equals("--help") || arg.equals("-help") || arg.equals("-h") || arg.equals("-?")) {
781                     usage();
782                     System.exit(1);
783                 }
784
785                 // Add argument to the application arguments
786
appArgs.add(arg);
787             } catch (ArrayIndexOutOfBoundsException JavaDoc aioobe) {
788                 // The next argument is not in the array
789
throw new ClientContainerException("A required parameter was missing after the argument" + arg);
790             }
791         }
792     }
793
794     /**
795      * Print the usage of this client
796      */

797     private void usage() {
798         System.out.println("Usage of this client :");
799         System.out.println("-------------------------------------------------------------------");
800         System.out.println("java -jar client.jar <client.jar|app.ear|className> [options]");
801         System.out.println("-------------------------------------------------------------------");
802         System.out.println(" -jarClient : Specify the client jar to use of the ear if many.");
803         System.out.println(" -traceFile : Specify the configuration file to use for the traces\n"
804                 + " of this client instead of the default file\n"
805                 + " (traceclient.properties) present in client.jar.");
806         System.out.println(" -carolFile : Specify the carol.properties file to use instead of \n"
807                 + " the default carol.properties file of the client.jar");
808         System.out.println(" -tmpDir : Specify the temp directory where unpack the ear.");
809         System.out.println(" -cp : Specify the classpath to use for the jar client.");
810         System.out.println("-------------------------------------------------------------------");
811         System.out.println(" --help : Display this help.");
812         System.out.println(" -help : Display this help.");
813         System.out.println(" -h : Display this help.");
814         System.out.println(" -? : Display this help.");
815         System.out.println("-------------------------------------------------------------------");
816     }
817
818     /**
819      * Extract the client of an ear and analyze ear too
820      * @param earFile ear to be analyzed
821      * @return the file of the client which was extracted
822      * @throws Exception if the analyze and/or extract fails
823      */

824     private File JavaDoc extractAndAnalyzeEar(File JavaDoc earFile) throws Exception JavaDoc {
825         if (logger.isLoggable(BasicLevel.DEBUG)) {
826             logger.log(BasicLevel.DEBUG, "");
827         }
828
829         URL JavaDoc earUrl = null;
830
831         try {
832             earUrl = earFile.toURL();
833         } catch (MalformedURLException JavaDoc mue) {
834             throw new ClientContainerException("Can not build an url with the filename '" + earFile + "'.", mue);
835         }
836
837         // Create classLoader
838
URL JavaDoc[] arrURL = new URL JavaDoc[1];
839         arrURL[0] = earUrl;
840
841         // parent classloader is the current classloader
842
ClassLoader JavaDoc currentLoader = Thread.currentThread().getContextClassLoader();
843         URLClassLoader JavaDoc loaderCls = new URLClassLoader JavaDoc(arrURL, currentLoader);
844
845         EarDeploymentDesc earDD = null;
846
847         if (logger.isLoggable(BasicLevel.DEBUG)) {
848             logger.log(BasicLevel.DEBUG, "Getting the deployment descriptor of the file" + earFile.getPath());
849         }
850
851         try {
852             earDD = EarDeploymentDescManager.getDeploymentDesc(earFile.getPath(), loaderCls);
853         } catch (EarDeploymentDescException e) {
854             String JavaDoc err = "Error in the Deployment descriptor '" + earFile + "'";
855             throw new ClientContainerException(err, e);
856         }
857
858         Map JavaDoc userToRoleMapping = earDD.getUserToRoleMapping();
859         // Do user-to-role mapping
860
if (userToRoleMapping != null) {
861             for (Iterator JavaDoc itMapping = userToRoleMapping.keySet().iterator(); itMapping.hasNext();) {
862                 String JavaDoc principalName = (String JavaDoc) itMapping.next();
863                 List JavaDoc roles = (List JavaDoc) userToRoleMapping.get(principalName);
864                 String JavaDoc[] roleNames = (String JavaDoc[]) roles.toArray(new String JavaDoc[roles.size()]);
865                 JPolicyUserRoleMapping.addGlobalUserToRoleMapping(principalName, roleNames);
866             }
867         }
868
869
870         // Get the tags from the Deployment descriptor
871
String JavaDoc[] ejbTags = earDD.getEjbTags();
872         Web[] webTags = earDD.getWebTags();
873         String JavaDoc[] clientTags = earDD.getClientTags();
874         String JavaDoc[] altDDEjbs = earDD.getAltDDEjbs();
875         String JavaDoc[] altDDWebs = earDD.getAltDDWebs();
876         String JavaDoc[] altDDClients = earDD.getAltDDClients();
877
878         // Check if all modules are inside the EAR file
879
// no relatives mode like ../../file1.jar
880
File JavaDoc fEar = null;
881         File JavaDoc tmpFile = null;
882
883         try {
884             fEar = earFile.getCanonicalFile();
885         } catch (IOException JavaDoc ioe) {
886             String JavaDoc err = "Error : Can not get canonical file for the file '" + earFile + "'.";
887             throw new ClientContainerException(err, ioe);
888         }
889
890         try {
891             for (int i = 0; i < ejbTags.length; i++) {
892                 tmpFile = new File JavaDoc(fEar, ejbTags[i]);
893                 tmpFile = tmpFile.getCanonicalFile();
894                 if (!tmpFile.getPath().startsWith(fEar.getPath())) {
895                     String JavaDoc err = "Error : The ejb-jar file " + ejbTags[i] + " is not inside the ear file " + fEar;
896                     throw new ClientContainerException(err);
897                 }
898             }
899
900             for (int i = 0; i < webTags.length; i++) {
901                 tmpFile = new File JavaDoc(fEar, webTags[i].getWebUri());
902                 tmpFile = tmpFile.getCanonicalFile();
903                 if (!tmpFile.getPath().startsWith(fEar.getPath())) {
904                     String JavaDoc err = "Error : The webapp file " + webTags[i] + " is not inside the ear file " + fEar;
905                     throw new ClientContainerException(err);
906                 }
907             }
908
909             for (int i = 0; i < clientTags.length; i++) {
910                 tmpFile = new File JavaDoc(fEar, clientTags[i]);
911                 tmpFile = tmpFile.getCanonicalFile();
912
913                 if (!tmpFile.getPath().startsWith(fEar.getPath())) {
914                     String JavaDoc err = "Error : The client jar file " + clientTags[i] + " is not inside the ear file " + fEar;
915                     throw new ClientContainerException(err);
916                 }
917             }
918         } catch (IOException JavaDoc ioe) {
919             String JavaDoc err = "Error while trying to get the canonical file of " + tmpFile;
920             throw new ClientContainerException(err, ioe);
921         }
922
923         //Changing array into JarList
924
JarList ejbsList = new JarList(ejbTags);
925         JarList websList = new JarList(webTags);
926         JarList clientsList = new JarList(clientTags);
927
928         // Temporary directory
929
String JavaDoc tempDir = null;
930
931         if (tmpDir != null) {
932             // use specific directory
933
tempDir = tmpDir;
934             info("Use your specified temp directory '" + tempDir + "'.");
935         } else {
936             // use default
937
tempDir = System.getProperty("java.io.tmpdir");
938         }
939
940         if (logger.isLoggable(BasicLevel.DEBUG)) {
941             logger.log(BasicLevel.DEBUG, "Using temp directory '" + tempDir + "'.");
942         }
943
944         // Can we write to ?
945
File JavaDoc tmpFileDir = new File JavaDoc(tempDir);
946
947         if (!tmpFileDir.exists() || !tmpFileDir.isDirectory()) {
948             throw new ClientContainerException("The temp directory '" + tempDir
949                     + "' doesn't exist or is not a directory.");
950         }
951
952         if (!tmpFileDir.canWrite()) {
953             throw new ClientContainerException("Can not write to the temporary directory '" + tempDir + "'.");
954         }
955
956         // Unpack the ear file and get the unpacked dir
957
URL JavaDoc dirUnpackURL = null;
958
959         try {
960             dirUnpackURL = EarFileManager.unpackEar(earUrl, tmpFileDir.toURL(), false);
961         } catch (Exception JavaDoc e) {
962             String JavaDoc err = "Error while unpacking the file '" + earUrl + "'";
963             throw new ClientContainerException(err, e);
964         }
965
966         // Ear is unpacked, now analyze manifest Class-path:
967
EarClassPathManager earCPManager = null;
968
969         try {
970             earCPManager = new EarClassPathManager(clientsList, dirUnpackURL);
971         } catch (EarClassPathManagerException e) {
972             String JavaDoc err = "Error while creating the Ear class path manager of the ear : '" + earUrl + "'";
973             error(err + " : " + e.getMessage());
974             throw new ClientContainerException(err, e);
975         }
976
977         URL JavaDoc[] classpathURLs = null;
978
979         //Get the urls of the ear class path manager
980
try {
981             classpathURLs = earCPManager.getResolvedClassPath();
982         } catch (EarClassPathManagerException e) {
983             String JavaDoc err = "Error while trying to resolve the classpath of the ejbjars and wars of the ear : '" + earUrl
984                     + "'";
985             error(err + " : " + e.getMessage());
986             throw new ClientContainerException(err, e);
987         }
988
989         if (logger.isLoggable(BasicLevel.DEBUG)) {
990             logger.log(BasicLevel.DEBUG, "EAR : ejbs = " + ejbsList);
991             logger.log(BasicLevel.DEBUG, "EAR : clientUrls = " + clientsList);
992         }
993
994         currentLoader = Thread.currentThread().getContextClassLoader();
995         earClassLoader = new URLClassLoader JavaDoc(new URL JavaDoc[0], currentLoader);
996
997         //Extract the urls of the jarList
998
URL JavaDoc[] jarUrls = null;
999         URL JavaDoc[] warUrls = null;
1000        URL JavaDoc[] clientUrls = null;
1001
1002        try {
1003            jarUrls = ejbsList.getURLs(dirUnpackURL.toExternalForm());
1004            warUrls = websList.getURLs(dirUnpackURL.toExternalForm());
1005            clientUrls = clientsList.getURLs(dirUnpackURL.toExternalForm());
1006        } catch (JarListException e) {
1007            String JavaDoc err = "Error while geting the Urls from jarlist of the ear : '" + earUrl + "'";
1008            throw new ClientContainerException(err, e);
1009        }
1010
1011        //Fill Alt-DD for Ejbs and Clients
1012
String JavaDoc altdd = null;
1013        File JavaDoc fAltDD = null;
1014
1015        //Transorm the array altDDWebs into an array with the absolute URL to
1016
// the file
1017
URL JavaDoc[] clientsAltDDs = new URL JavaDoc[altDDClients.length];
1018
1019        for (int i = 0; i < altDDClients.length; i++) {
1020            if (altDDClients[i] != null) {
1021                altdd = altDDClients[i];
1022
1023                if (altdd != null) {
1024                    try {
1025                        fAltDD = new File JavaDoc(new URL JavaDoc(dirUnpackURL.toExternalForm() + File.separator + altdd).getFile());
1026                        clientsAltDDs[i] = fAltDD.getCanonicalFile().toURL();
1027                    } catch (MalformedURLException JavaDoc e) {
1028                        String JavaDoc err = "Can't build URL for alt-dd '" + altdd;
1029                        error(err + "': " + e.getMessage());
1030                        throw new ClientContainerException(err, e);
1031                    } catch (IOException JavaDoc ioe) {
1032                        String JavaDoc err = "Can't get canonicalFile() for the file '" + fAltDD;
1033                        error(err + "': " + ioe.getMessage());
1034                        throw new ClientContainerException(err, ioe);
1035                    }
1036                }
1037            }
1038        }
1039
1040        URL JavaDoc[] ejbsAltDDs = new URL JavaDoc[altDDEjbs.length];
1041
1042        for (int i = 0; i < altDDEjbs.length; i++) {
1043            if (altDDEjbs[i] != null) {
1044                altdd = altDDEjbs[i];
1045
1046                if (altdd != null) {
1047                    try {
1048                        fAltDD = new File JavaDoc(new URL JavaDoc(dirUnpackURL.toExternalForm() + File.separator + altdd).getFile());
1049                        ejbsAltDDs[i] = fAltDD.getCanonicalFile().toURL();
1050                    } catch (MalformedURLException JavaDoc e) {
1051                        String JavaDoc err = "Can't build URL for alt-dd '" + altdd;
1052                        error(err + "': " + e.getMessage());
1053                        throw new ClientContainerException(err, e);
1054                    } catch (IOException JavaDoc ioe) {
1055                        String JavaDoc err = "Can't get canonicalFile() for the file '" + fAltDD;
1056                        error(err + "': " + ioe.getMessage());
1057                        throw new ClientContainerException(err, ioe);
1058                    }
1059                }
1060            }
1061        }
1062
1063        URL JavaDoc[] websAltDDs = new URL JavaDoc[altDDWebs.length];
1064
1065        for (int i = 0; i < altDDWebs.length; i++) {
1066            if (altDDWebs[i] != null) {
1067                altdd = altDDWebs[i];
1068
1069                if (altdd != null) {
1070                    try {
1071                        fAltDD = new File JavaDoc(new URL JavaDoc(dirUnpackURL.toExternalForm() + File.separator + altdd).getFile());
1072                        websAltDDs[i] = fAltDD.getCanonicalFile().toURL();
1073                    } catch (MalformedURLException JavaDoc e) {
1074                        String JavaDoc err = "Can't build URL for alt-dd '" + altdd;
1075                        error(err + "': " + e.getMessage());
1076                        throw new ClientContainerException(err, e);
1077                    } catch (IOException JavaDoc ioe) {
1078                        String JavaDoc err = "Can't get canonicalFile() for the file '" + fAltDD;
1079                        error(err + "': " + ioe.getMessage());
1080                        throw new ClientContainerException(err, ioe);
1081                    }
1082                }
1083            }
1084        }
1085
1086        EjbDeploymentDescManager.getInstance().setAvailableEjbJarsAndAltDDs(earClassLoader, jarUrls, ejbsAltDDs);
1087        WebDeploymentDescManager.getInstance().setAltDD(earClassLoader, warUrls, websAltDDs);
1088        ClientDeploymentDescManager.getInstance().setAltDD(earClassLoader, clientUrls, clientsAltDDs);
1089
1090        // Construct the ejb classloader for all the ejb-jars of the same
1091
// ear application. Because there is one ejb classloader for all
1092
// the ejb-jars of the same ear application.
1093
URL JavaDoc[] userURLs = getUserClasspathUrls();
1094        extensionsURLs = new URL JavaDoc[jarUrls.length + classpathURLs.length + userURLs.length];
1095
1096        System.arraycopy(jarUrls, 0, extensionsURLs, 0, jarUrls.length);
1097        System.arraycopy(classpathURLs, 0, extensionsURLs, jarUrls.length, classpathURLs.length);
1098        System.arraycopy(userURLs, 0, extensionsURLs, jarUrls.length + classpathURLs.length, userURLs.length);
1099
1100        if (logger.isLoggable(BasicLevel.DEBUG)) {
1101            logger.log(BasicLevel.DEBUG, "Extensions urls :");
1102
1103            for (int ii = 0; ii < extensionsURLs.length; ii++) {
1104                logger.log(BasicLevel.DEBUG, "url[" + ii + "] = " + extensionsURLs[ii]);
1105            }
1106        }
1107
1108        // Choose the jar client
1109
if (clientUrls.length == 0) {
1110            throw new ClientContainerException("No java client was found in the application.xml file of the Ear '"
1111                    + earUrl + "'.");
1112        }
1113
1114        File JavaDoc fClient = null;
1115
1116        // User has specify an application client to execute
1117
// Search it
1118
if (jarClient != null) {
1119            int f = 0;
1120            File JavaDoc ff = null;
1121            boolean found = false;
1122
1123            while (f < clientUrls.length && !found) {
1124                ff = new File JavaDoc(clientUrls[f].getFile());
1125
1126                if (ff.getPath().endsWith(jarClient)) {
1127                    found = true;
1128                    fClient = ff;
1129
1130                    if (logger.isLoggable(BasicLevel.DEBUG)) {
1131                        logger.log(BasicLevel.DEBUG, "Found a matching client with the name " + ff);
1132                    }
1133                }
1134
1135                f++;
1136            }
1137
1138            if (!found) {
1139                throw new ClientContainerException("No client with the name '" + jarClient
1140                        + "' was found in this Ear file");
1141            }
1142        } else {
1143            // Take first
1144
fClient = new File JavaDoc(clientUrls[0].getFile());
1145
1146            // Warning if many
1147
if (clientUrls.length > 1) {
1148                warn("There are " + clientUrls.length + " clients in this ear, choosing the first one : "
1149                        + fClient.getName());
1150            }
1151        }
1152
1153        info("Use the application client '" + fClient + "' of the Ear '" + earUrl + "'.");
1154
1155        return fClient;
1156    }
1157
1158    /**
1159     * Gets the URL of user classpath (can be empty
1160     * @return URL of user classpath (-cp arg)
1161     */

1162    private URL JavaDoc[] getUserClasspathUrls() {
1163        if (classpath == null) {
1164            return new URL JavaDoc[0];
1165        }
1166        String JavaDoc sep = File.pathSeparator;
1167        List JavaDoc clUser = new ArrayList JavaDoc();
1168        StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(classpath, sep);
1169        while (tokenizer.hasMoreTokens()) {
1170            File JavaDoc file = new File JavaDoc(tokenizer.nextToken());
1171            try {
1172                clUser.add(file.toURL());
1173            } catch (MalformedURLException JavaDoc mue) {
1174                logger.log(BasicLevel.WARN, "Cannot transform to URL the file : '" + file + "'", mue);
1175            }
1176        }
1177        return (URL JavaDoc[]) clUser.toArray(new URL JavaDoc[0]);
1178    }
1179
1180    /**
1181     * Display an info message with the logger
1182     * @param s the message
1183     */

1184    private void info(String JavaDoc s) {
1185        logger.log(BasicLevel.INFO, s);
1186    }
1187
1188    /**
1189     * Display an error message with the logger
1190     * @param s the message
1191     */

1192    private void error(String JavaDoc s) {
1193        logger.log(BasicLevel.ERROR, s);
1194    }
1195
1196    /**
1197     * Display a warn message with the logger
1198     * @param s the message
1199     */

1200    private void warn(String JavaDoc s) {
1201        logger.log(BasicLevel.WARN, s);
1202    }
1203}
1204
Popular Tags