KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > resource > ResourceServiceImpl


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 any 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: ResourceServiceImpl.java,v 1.57 2005/07/28 13:35:38 durieuxp Exp $
23  * --------------------------------------------------------------------------
24  */

25
26
27 package org.objectweb.jonas.resource;
28
29 import java.io.File JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.net.URL JavaDoc;
32 import java.rmi.RemoteException JavaDoc;
33 import java.util.ArrayList JavaDoc;
34 import java.util.Enumeration JavaDoc;
35 import java.util.HashSet JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.Set JavaDoc;
38 import java.util.StringTokenizer JavaDoc;
39 import java.util.Vector JavaDoc;
40
41 import javax.management.InstanceAlreadyExistsException JavaDoc;
42 import javax.management.InstanceNotFoundException JavaDoc;
43 import javax.management.MBeanRegistrationException JavaDoc;
44 import javax.management.MBeanServer JavaDoc;
45 import javax.naming.Context JavaDoc;
46 import javax.naming.NamingException JavaDoc;
47 import javax.resource.spi.XATerminator JavaDoc;
48 import javax.resource.spi.work.WorkManager JavaDoc;
49
50 import org.objectweb.transaction.jta.TransactionManager;
51
52 import org.objectweb.jonas_lib.JWorkManager;
53 import org.objectweb.jonas_rar.deployment.lib.wrapper.RarManagerWrapper;
54
55 import org.objectweb.jonas.common.JModule;
56 import org.objectweb.jonas.common.JProp;
57 import org.objectweb.jonas.common.Log;
58 import org.objectweb.jonas.container.EJBService;
59 import org.objectweb.jonas.jmx.JmxService;
60 import org.objectweb.jonas.jmx.JonasObjectName;
61 import org.objectweb.jonas.jtm.TransactionService;
62 import org.objectweb.jonas.naming.CompNamingContext;
63 import org.objectweb.jonas.server.LoaderManager;
64 import org.objectweb.jonas.service.AbsServiceImpl;
65 import org.objectweb.jonas.service.ServiceException;
66 import org.objectweb.jonas.service.ServiceManager;
67
68 import org.objectweb.util.monolog.api.BasicLevel;
69 import org.objectweb.util.monolog.api.Logger;
70
71 /**
72  * JCA resource service implmentation
73  * @author Philippe Coq
74  * Contributor(s):
75  * JOnAS 2.4 Sebastien Chassande-Barrioz (sebastien.chassande@inrialpes.fr)
76  * JOnAS 3.0 Eric Hardesty (Eric.Hardesty@bull.com)
77  * JOnAS 4.0 Adriana Danes (JSR 77 + use of Jakarta Modeler Component : http://jakarta.apache.org/commons/modeler)
78  * Eric Hardesty (J2CA 1.5)
79  *
80  */

81 public class ResourceServiceImpl extends AbsServiceImpl implements
82     ResourceService,
83     ResourceServiceImplMBean {
84
85     // Loggers used in the ResourceService
86
/**
87      * Main logger
88      */

89     private static Logger logger = null;
90     /**
91      * Pool infomation logger
92      */

93     private static Logger poolLogger = null;
94     /**
95      * Config property setter logger
96      */

97     private static Logger setterLogger = null;
98     /**
99      * Management logger
100      */

101     private static Logger manageLogger = null;
102
103     // Properties for inits
104

105     // JCA resource service configuration parameters
106
/**
107      * Autoload directory property name
108      */

109     public static final String JavaDoc AUTOLOADDIR = "jonas.service.resource.autoloaddir";
110     /**
111      * Service class property name
112      */

113     public static final String JavaDoc CLASS = "jonas.service.resource.class";
114     /**
115      * Jndiname property name
116      */

117     public static final String JavaDoc JNDI_NAME = "jndiname";
118     /**
119      * Rar object property name
120      */

121     public static final String JavaDoc RAR_OBJNAME = "rarobjname";
122     /**
123      * Factory offset property name
124      */

125     public static final String JavaDoc FACTORY_OFFSET = "factoryoffset";
126     /**
127      * Factory type property name
128      */

129     public static final String JavaDoc FACTORY_TYPE = "factorytype";
130     /**
131      * Rar filename property name
132      */

133     public static final String JavaDoc RAR_FILENAME = "rarfilename";
134     /**
135      * Jndiname link property name
136      */

137     public static final String JavaDoc LNK_JNDI_NAME = "lnkjndiname";
138     /**
139      * Link Rar filename property name
140      */

141     public static final String JavaDoc LNK_RAR_FILENAME = "lnkrarfilename";
142     /**
143      * Jonas ra.xml property name
144      */

145     public static final String JavaDoc JONAS_RA_XML = "jonasraxml";
146     /**
147      * ra.xml property name
148      */

149     public static final String JavaDoc RA_XML = "raxml";
150     /**
151      * Parsing validation property name
152      */

153     public static final String JavaDoc PARSINGWITHVALIDATION = "jonas.service.resource.parsingwithvalidation";
154     /**
155      * Resources list property name
156      */

157     public static final String JavaDoc RESOURCE_LIST = "jonas.service.resource.resources";
158     /**
159      * Thread timeout
160      */

161     public static final String JavaDoc THREADWAITTIMEOUT = "jonas.service.resource.threadwaittimeout";
162     /**
163      * Minimum number of work threads property name
164      */

165     public static final String JavaDoc MINWORKTHREADS = "jonas.service.resource.minworkthreads";
166     /**
167      * Maximum number of work threads property name
168      */

169     public static final String JavaDoc MAXWORKTHREADS = "jonas.service.resource.maxworkthreads";
170     /**
171      * Work max execution timeout property name
172      */

173     public static final String JavaDoc EXECTIMEOUT = "jonas.service.resource.worktimeout";
174
175     /**
176      * Default work thread timeout
177      */

178     public static final int DEF_WRK_THREADWAITTIMEOUT = 60;
179     /**
180      * Default number of work threads
181      */

182     public static final int DEF_WRK_THREADS = 5;
183     /**
184      * Default max number of work threads
185      */

186     public static final int DEF_MAX_WRK_THREADS = 80;
187     /**
188      * Maximum work execution timeout (0 is unlimited)
189      */

190     public static final int DEF_EXEC_TIME = 0;
191
192     /**
193      * Hashtable mapping a jndiname to an RAR object
194      */

195 // private static Hashtable jndiName2RA = new Hashtable();
196
/**
197      * Hashtable mapping a filename to an RAR object
198      */

199 // private static Hashtable fileName2RA = new Hashtable();
200
/**
201      * Hashtable mapping a jndiname to an "external" factory
202      */

203 // private static Hashtable jndiName2Factory = new Hashtable();
204

205     /**
206      * This vector is list of RAR files that will be deployed after all
207      * other RAR files have been deployed. The problem is that these RAR
208      * files are associated with another RAR file that has not been processed.
209      */

210     private Vector JavaDoc delayedRAs = new Vector JavaDoc();
211     /**
212      * boolean to determine if processing of delayed Rars has begun
213      */

214     private boolean processingDelayed = false;
215
216     /**
217      * The transaction service for this server
218      */

219     private TransactionService ts = null;
220     /**
221      * The transaction manager for this server
222      */

223     private TransactionManager tm = null;
224
225     /**
226      * Reference to a MBean server.
227      */

228     private MBeanServer JavaDoc mbeanServer = null;
229
230     /**
231      * Autoload directory names
232      */

233     private Vector JavaDoc autoNames = null;
234     /**
235      * List of resource names
236      */

237     private Vector JavaDoc resourceNames = null;
238
239
240     // J2EE CA 1.5 objects
241
/**
242      * Work Manager for the Resource service
243      */

244     private WorkManager JavaDoc workMgr = null;
245     /**
246      * BootstrapContext for the Resource service
247      */

248     private ResourceBootstrapContext bootCtx = null;
249
250     /**
251      * The name of the JONAS_BASE directory
252      */

253     public static final String JavaDoc JONAS_BASE = JProp.getJonasBase();
254
255     /**
256      * The name of the working apps directory.
257      */

258     public static final String JavaDoc WORK_RARS_DIR = JProp.getWorkDir() + File.separator + "rars";
259
260     /**
261      * The name of the rars directory
262      */

263     public static final String JavaDoc RARSDIR = JProp.getJonasBase() + File.separator + "rars";
264
265     /**
266      * Application parent classloader
267      */

268     private ClassLoader JavaDoc appsClassLoader;
269
270     /**
271      * Default construtor for ResourceService
272      */

273     public ResourceServiceImpl() {
274     }
275
276     //IMPLEMENTATION OF 'AbsServiceImpl' ABSTRACT CLASS
277
/**
278      * - Get the loggers
279      * - Get the global jndi context
280      * - Get the list of the resource adapters. The list is reachable in the
281      * - context parameter under the name RESOURCE_LIST.
282      * - Get the transaction manager into the jndi
283      * - Set the XML validation property
284      * @param ctx Context
285      */

286     public void doInit(Context JavaDoc ctx) {
287         if (logger == null) {
288             logger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".process");
289         }
290         if (poolLogger == null) {
291             poolLogger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".pool");
292         }
293         if (setterLogger == null) {
294             setterLogger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".setters");
295         }
296         if (manageLogger == null) {
297             manageLogger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".management");
298         }
299
300         try {
301             LoaderManager lm = LoaderManager.getInstance();
302             appsClassLoader = lm.getAppsLoader();
303         } catch (Exception JavaDoc e) {
304             logger.log(BasicLevel.ERROR, "Cannot get the Applications ClassLoader from RAR Container Service: " + e);
305             throw new ServiceException("Cannot get the Applications ClassLoader from RAR Container Service", e);
306         }
307
308         resourceNames = new Vector JavaDoc();
309         autoNames = new Vector JavaDoc();
310
311         // Add the rars of the jonas.service.resource.autoloaddir property
312
String JavaDoc dirValue = null;
313         try {
314             dirValue = (String JavaDoc) ctx.lookup(AUTOLOADDIR);
315             if (logger.isLoggable(BasicLevel.DEBUG)) {
316                 logger.log(BasicLevel.DEBUG, "autoloaddir= " + dirValue);
317             }
318         } catch (NamingException JavaDoc e) {
319             if (logger.isLoggable(BasicLevel.DEBUG)) {
320                 logger.log(BasicLevel.DEBUG, "No autoloaddir value specified in context, usually for client container");
321             }
322         }
323         if (dirValue != null) {
324             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(dirValue, ",");
325             String JavaDoc dirName = null;
326             while (st.hasMoreTokens()) {
327                 dirName = normalizePath(st.nextToken().trim());
328                 addRars(dirName);
329             }
330         }
331
332         // Get the list of the resource adapter names
333
try {
334             String JavaDoc rs = (String JavaDoc) ctx.lookup(RESOURCE_LIST);
335             if (logger.isLoggable(BasicLevel.DEBUG)) {
336                 logger.log(BasicLevel.DEBUG, "resource list= " + rs);
337             }
338             if (rs != null) {
339                 StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(rs, ",");
340                 String JavaDoc resFilename = null;
341                 while (st.hasMoreTokens()) {
342                     resFilename = normalizePath(st.nextToken().trim());
343                     resourceNames.add(resFilename);
344                 }
345             }
346         } catch (NamingException JavaDoc e) {
347             logger.log(BasicLevel.ERROR, "Cannot lookup the configuration context at Resource service starting");
348         }
349
350         // Get a reference to the Transaction service
351
try {
352             ServiceManager sm = ServiceManager.getInstance();
353             ts = (TransactionService) sm.getTransactionService();
354             tm = ts.getTransactionManager();
355         } catch (Exception JavaDoc e) {
356             logger.log(BasicLevel.ERROR, "Cannot get the Transaction service: " + e);
357             throw new ServiceException("Cannot get the Transaction service: ", e);
358         }
359
360         // Get the JMX Server via JMX Service
361
try {
362             mbeanServer =
363                 ((JmxService) ServiceManager.getInstance().getJmxService()).getJmxServer();
364         } catch (Exception JavaDoc e) {
365             // the JMX service may not be started
366
mbeanServer = null;
367         }
368
369         // Init the XML parsing mode to no validation
370
String JavaDoc parsingMode = "false";
371         try {
372             parsingMode = (String JavaDoc) ctx.lookup(PARSINGWITHVALIDATION);
373         } catch (NamingException JavaDoc e) {
374             // No problem if there is no value for 'parsingwithvalidation' (false by default)
375
if (logger.isLoggable(BasicLevel.DEBUG)) {
376                 logger.log(BasicLevel.DEBUG, "No parsingwithvalidation value specified in context");
377             }
378         }
379         if ("false".equalsIgnoreCase(parsingMode)) {
380             RarManagerWrapper.setParsingWithValidation(false);
381             if (logger.isLoggable(BasicLevel.DEBUG)) {
382                 logger.log(BasicLevel.DEBUG, "XML parsing without validation");
383             }
384         } else {
385             if (logger.isLoggable(BasicLevel.DEBUG)) {
386                 logger.log(BasicLevel.DEBUG, "XML parsing with validation");
387             }
388         }
389
390         // Get the WorkManager defined in the EJB Service, if it exists
391
EJBService ejbService = null;
392         try {
393             ejbService = (EJBService) ServiceManager.getInstance().getEjbService();
394             workMgr = ejbService.getWorkManager();
395         } catch (Exception JavaDoc e) {
396             // the EJB service may not be started
397
workMgr = null;
398         }
399
400         // Get the parameters for the WorkManager
401
int execTime = 0;
402         try {
403             String JavaDoc etime = (String JavaDoc) ctx.lookup(EXECTIMEOUT);
404             execTime = (new Integer JavaDoc(etime)).intValue();
405         } catch (NamingException JavaDoc e) {
406             // No problem if there is no value --> default value
407
if (logger.isLoggable(BasicLevel.DEBUG)) {
408                 logger.log(BasicLevel.DEBUG, "No exectimeout value specified in context, usually for client container");
409             }
410         }
411
412         // Thread wait timeout
413
int threadWaitTimeout = DEF_WRK_THREADWAITTIMEOUT;
414         try {
415             String JavaDoc tTimeout = (String JavaDoc) ctx.lookup(THREADWAITTIMEOUT);
416             threadWaitTimeout = (new Integer JavaDoc(tTimeout)).intValue();
417             if (threadWaitTimeout <= 0) {
418                 threadWaitTimeout = DEF_WRK_THREADWAITTIMEOUT;
419                 if (logger.isLoggable(BasicLevel.DEBUG)) {
420                     logger.log(BasicLevel.DEBUG, "Resetting thread wait timeout to " + DEF_WRK_THREADWAITTIMEOUT);
421                 }
422             }
423         } catch (Exception JavaDoc e) {
424             // default value will be used.
425
if (logger.isLoggable(BasicLevel.DEBUG)) {
426                 logger.log(BasicLevel.DEBUG, "No workthread wait timeout value specified in context");
427             }
428         }
429
430         // MIN thread pool size
431
int minWorkThreads = DEF_WRK_THREADS;
432         try {
433             String JavaDoc wThreads = (String JavaDoc) ctx.lookup(MINWORKTHREADS);
434             minWorkThreads = (new Integer JavaDoc(wThreads)).intValue();
435             if (minWorkThreads <= 0) {
436                 minWorkThreads = DEF_WRK_THREADS;
437                 if (logger.isLoggable(BasicLevel.DEBUG)) {
438                     logger.log(BasicLevel.DEBUG, "Resetting min threads to " + DEF_WRK_THREADS);
439                 }
440             }
441         } catch (Exception JavaDoc e) {
442             // default value will be used.
443
if (logger.isLoggable(BasicLevel.DEBUG)) {
444                 logger.log(BasicLevel.DEBUG, "No min workthreads value specified in context");
445             }
446         }
447
448         // MAX thread pool size
449
int maxWorkThreads = DEF_MAX_WRK_THREADS;
450         try {
451             String JavaDoc wThreads = (String JavaDoc) ctx.lookup(MAXWORKTHREADS);
452             maxWorkThreads = (new Integer JavaDoc(wThreads)).intValue();
453         } catch (Exception JavaDoc e) {
454             // default value will be used.
455
if (logger.isLoggable(BasicLevel.DEBUG)) {
456                 logger.log(BasicLevel.DEBUG, "No max workthreads value specified in context");
457             }
458         }
459
460         // Create WorkManager if we cannot use the one defined in ejb
461
if (maxWorkThreads > 0 || workMgr == null) {
462             logger.log(BasicLevel.DEBUG, "Create a WorkManager for Resources");
463             if (maxWorkThreads <= 0) {
464                 maxWorkThreads = DEF_MAX_WRK_THREADS;
465                 if (logger.isLoggable(BasicLevel.DEBUG)) {
466                     logger.log(BasicLevel.DEBUG, "Resetting max threads to " + DEF_WRK_THREADS);
467                 }
468             }
469             workMgr = new JWorkManager(minWorkThreads, maxWorkThreads, tm, threadWaitTimeout);
470         }
471
472         // Create BootstrapContext
473
XATerminator JavaDoc xat = null;
474         try {
475             xat = ts.getCurrent().getXATerminator();
476         } catch (Exception JavaDoc ex) {
477             logger.log(BasicLevel.ERROR, "Unable to get an XATerminator from the TransactionService");
478             throw new ServiceException("Unable to get an XATerminator from the TransactionService", ex);
479         }
480         bootCtx = new ResourceBootstrapContext(workMgr, xat);
481
482         if (logger.isLoggable(BasicLevel.DEBUG)) {
483             logger.log(BasicLevel.DEBUG, "ResourceService initialized");
484         }
485     }
486
487     /**
488      * Start the Resource service.
489      * @throws ServiceException if the startup failed.
490      */

491     public void doStart() throws ServiceException {
492         // creates each resource
493
String JavaDoc rarFileName = null;
494         CompNamingContext ctx = null;
495         for (int i = 0; i < resourceNames.size(); i++) {
496             rarFileName = (String JavaDoc) resourceNames.elementAt(i);
497             if (logger.isLoggable(BasicLevel.DEBUG)) {
498                 logger.log(BasicLevel.DEBUG, "rarFileName=" + rarFileName);
499             }
500             try {
501                 ctx = new CompNamingContext(rarFileName);
502                 ctx.rebind("rarFileName", rarFileName);
503                 ctx.rebind("isInEar", new Boolean JavaDoc(false));
504                 ctx.rebind("classloader", appsClassLoader);
505                 createResourceAdapter(ctx);
506             } catch (Exception JavaDoc e) {
507                 logger.log(BasicLevel.ERROR, "JOnAS: Cannot create resource: " + rarFileName + " exception: " + e);
508                 e.printStackTrace();
509             }
510         }
511
512         // process any delayed rars
513
if (!delayedRAs.isEmpty()) {
514           try {
515             processingDelayed = true;
516             Object JavaDoc [] rList = null;
517             rList = delayedRAs.toArray();
518             for (int i = 0; i < rList.length; i++) {
519                 try {
520                     createResourceAdapter((CompNamingContext) rList[i]);
521                 } catch (Exception JavaDoc e) {
522                     e.printStackTrace();
523                     String JavaDoc rFile = (String JavaDoc) ((CompNamingContext) rList[i]).lookup("rarFileName");
524                     logger.log(BasicLevel.ERROR, "JOnAS: Cannot create resource: " + rFile + " exception: " + e);
525                     logger.log(BasicLevel.ERROR, "Please verify that the rarlink is correct/deployed");
526                 }
527             }
528           } catch (Exception JavaDoc e) {
529              e.printStackTrace();
530              logger.log(BasicLevel.ERROR, "ResourceService: Error with delayed RAR file deployment\n" + e);
531              throw new ServiceException("ResourceService: Error with delayed RAR file deployment", e);
532           }
533         }
534
535         // Create and register the Resource Service MBean
536
if (mbeanServer != null) {
537             try {
538                 mbeanServer.registerMBean(this, JonasObjectName.resourceService());
539             } catch (InstanceAlreadyExistsException JavaDoc iae) {
540                 logger.log(BasicLevel.ERROR, "Cannot start the Resource Service Already Exists:\n" + iae);
541                 throw new ServiceException("Cannot start the Resource Service Already Exists", iae);
542             } catch (Exception JavaDoc e) {
543                 logger.log(BasicLevel.ERROR, "ResourceService: Cannot start the Resource service:\n" + e);
544                 throw new ServiceException("ResourceService: Cannot start the Resource service", e);
545             }
546         }
547
548     }
549
550     /**
551      * Stop the Resource service.
552      * @throws ServiceException if the stop failed.
553      */

554     public void doStop() throws ServiceException {
555
556         ServiceException se = null;
557         synchronized (Rar.fileName2RA) {
558             Enumeration JavaDoc keys = Rar.fileName2RA.elements();
559             while (keys.hasMoreElements()) {
560                 Rar ra = (Rar) keys.nextElement();
561                 try {
562                     ra.unRegister();
563                     Rar.fileName2RA.remove(ra);
564                 } catch (Exception JavaDoc ex) {
565                     logger.log(BasicLevel.ERROR, "ResourceService: Received the following:" + ex);
566                     ex.printStackTrace();
567                     if (se == null) {
568                         se = new ServiceException(ex.getMessage());
569                     }
570                 }
571             }
572         }
573         // unregister resource MBeans
574
if (mbeanServer != null) {
575             try {
576                 // unregister resource Service MBean
577
mbeanServer.unregisterMBean(JonasObjectName.resourceService());
578             } catch (MBeanRegistrationException JavaDoc mr) {
579                 logger.log(BasicLevel.ERROR, "Cannot cleanly stop the ResourceService: "
580                                              + mr.getMessage());
581             } catch (InstanceNotFoundException JavaDoc infe) {
582                 logger.log(BasicLevel.ERROR, "Cannot cleanly stop the ResourceService: "
583                                              + infe.getMessage());
584             } catch (Exception JavaDoc e) {
585                 logger.log(BasicLevel.ERROR, "ResourceService: Cannot stop the Resource service:\n" + e);
586                 throw new ServiceException("ResourceService: Cannot stop the Resource service", e);
587             }
588         }
589
590         if (se != null) {
591             throw se;
592         }
593         if (logger.isLoggable(BasicLevel.DEBUG)) {
594             logger.log(BasicLevel.DEBUG, "ResourceService stopped");
595         }
596     }
597
598
599     // IMPLEMENTATION OF 'ResourceService' INTERFACE //
600

601     /**
602      * Create a new resource adapter. This Resource Adapter is configured via
603      * xml files in the rar file
604      * @param ctx Context to use for deploying an RAR
605      * @return Sting resource objectName
606      * @throws Exception error encountered
607      */

608     public String JavaDoc createResourceAdapter(Context JavaDoc ctx) throws Exception JavaDoc {
609
610         // Parameters :
611
// rarFileName, isInEar, classloader and possible AltDD and earUrl
612
String JavaDoc rarFileName;
613         try {
614             rarFileName = (String JavaDoc) ctx.lookup("rarFileName");
615             ctx.rebind("deployed", new Boolean JavaDoc(false));
616         } catch (Exception JavaDoc ex) {
617             String JavaDoc err = "Error while getting parameter from context param.";
618             logger.log(BasicLevel.ERROR, err + ex.getMessage());
619             throw new ResourceServiceException(err, ex);
620         }
621
622         if (logger.isLoggable(BasicLevel.DEBUG)) {
623             logger.log(BasicLevel.DEBUG, rarFileName);
624         }
625         if (!rarFileName.endsWith(".rar")) {
626             rarFileName += ".rar";
627             ctx.rebind("rarFileName", rarFileName);
628         }
629
630         // Determine if the RAR file exists
631
File JavaDoc f = new File JavaDoc(rarFileName);
632         if (!f.exists()) {
633             boolean found = false;
634             String JavaDoc resFileName = null;
635             // In case of the name is a rar file name, check also in
636
// the JONAS_BASE/rars directory
637
resFileName = RARSDIR + File.separator + rarFileName;
638             f = new File JavaDoc(resFileName);
639             found = f.exists();
640             if (found) {
641                 rarFileName = resFileName;
642                 ctx.rebind("rarFileName", rarFileName);
643             } else {
644                 logger.log(BasicLevel.ERROR, "createResourceAdapter: " + resFileName + " not found");
645                 Exception JavaDoc e = new NamingException JavaDoc(resFileName + " not found");
646                 throw e;
647             }
648         }
649
650         URL JavaDoc rarUrl = f.toURL();
651
652         Rar rar = new Rar(ctx, getDomainName(), getJonasServerName(), workMgr, bootCtx);
653
654         try {
655             Context JavaDoc ctxRar = rar.processRar();
656         } catch (Exception JavaDoc ex) {
657             // Exception error in processing unregister
658
String JavaDoc err = "Error processing Rar: " + ex.getMessage();
659             try {
660                 rar.unRegister();
661             } catch (Exception JavaDoc exc) {
662                 err = err + " Unregister also failed with " + exc.getMessage();
663             }
664             logger.log(BasicLevel.ERROR, err);
665             throw new ResourceServiceException(err, ex);
666         }
667
668         boolean isDeployed = false;
669         try {
670             isDeployed = ((Boolean JavaDoc) ctx.lookup("deployed")).booleanValue();
671         } catch (Exception JavaDoc ex) {
672             String JavaDoc err = "Error while getting parameter(isDeployed) from context param.";
673             logger.log(BasicLevel.ERROR, err + ex.getMessage());
674             throw new ResourceServiceException(err, ex);
675         }
676
677         if (!isDeployed) {
678             // If isDeployed in not set, then an rar-link was specified that is not deployed and if
679
// we are already processing the delayed rar files, then throw an exception otherwise
680
// update the delayedRAs vector and process it again later.
681
if (processingDelayed) {
682                 logger.log(BasicLevel.ERROR, "ResourceService.createRA: Resource (" + rarFileName + ") contains an invalid rarlink.");
683                 throw new ResourceServiceException("resource input file incorrect: invalid rarlink");
684             }
685             delayedRAs.add(ctx);
686             return null;
687         }
688
689         Vector JavaDoc jNames = rar.getJndinames();
690         if (jNames != null) {
691             for (int i = 0; i < jNames.size(); i++) {
692                 Rar.jndiName2RA.put(jNames.get(i), rar);
693             }
694         }
695
696         // Processed and deployed rar, so add it to our lists
697
Rar.fileName2RA.put(rarUrl.getPath(), rar);
698
699         String JavaDoc onRar = null;
700         try {
701             onRar = (String JavaDoc) ctx.lookup("onRar");
702         } catch (Exception JavaDoc ex) {
703             String JavaDoc err = "Error while getting parameter(onRar) from context param.";
704             logger.log(BasicLevel.ERROR, err + ex.getMessage());
705             throw new ResourceServiceException(err, ex);
706         }
707
708         return onRar.toString();
709     }
710
711
712     /**
713      * Deploy the given rars of an ear file with the specified parent
714      * classloader (ear classloader). (This method is only used for
715      * for ear applications).
716      * @param ctx the context containing the configuration
717      * to deploy the rars.<BR>
718      * This context contains the following parameters :<BR>
719      * - urls the list of the urls of the rars to deploy.<BR>
720      * - earRootURL the URL of the ear application file.<BR>
721      * - earClassLoader the ear classLoader of the j2ee app.<BR>
722      * - altDDs the optional URI of deployment descriptor.<BR>
723      * @throws ResourceServiceException if an error occurs during
724      * the deployment.
725      */

726     public void deployRars(Context JavaDoc ctx) throws ResourceServiceException {
727
728         // Gets the parameters from the context :
729
// - urls the list of the urls of the rars to deploy.
730
// - earRootURL the URL of the ear application file.
731
// - earClassLoader the ear classLoader of the j2ee app.
732
// - altDDs the optional URI of deployment descriptor.
733
URL JavaDoc[] urls = null;
734         URL JavaDoc earUrl = null;
735         ClassLoader JavaDoc earClassLoader = null;
736         URL JavaDoc[] altDDs = null;
737         try {
738             urls = (URL JavaDoc[]) ctx.lookup("urls");
739