ResourceServiceImpl.java

00001 
00027 package org.objectweb.jonas.resource;
00028 
00029 import java.io.File;
00030 import java.io.IOException;
00031 import java.net.URL;
00032 import java.rmi.RemoteException;
00033 import java.util.ArrayList;
00034 import java.util.Enumeration;
00035 import java.util.HashSet;
00036 import java.util.List;
00037 import java.util.Set;
00038 import java.util.StringTokenizer;
00039 import java.util.Vector;
00040 
00041 import javax.management.InstanceAlreadyExistsException;
00042 import javax.management.InstanceNotFoundException;
00043 import javax.management.MBeanRegistrationException;
00044 import javax.management.MBeanServer;
00045 import javax.naming.Context;
00046 import javax.naming.InitialContext;
00047 import javax.naming.NamingException;
00048 
00049 import javax.resource.spi.XATerminator;
00050 
00051 import org.objectweb.transaction.jta.TransactionManager;
00052 
00053 import org.objectweb.jonas_rar.deployment.lib.wrapper.RarManagerWrapper;
00054 
00055 import org.objectweb.jonas.common.JModule;
00056 import org.objectweb.jonas.common.JProp;
00057 import org.objectweb.jonas.common.Log;
00058 import org.objectweb.jonas.jmx.JmxService;
00059 import org.objectweb.jonas.jmx.JonasObjectName;
00060 import org.objectweb.jonas.jtm.TransactionService;
00061 import org.objectweb.jonas.naming.CompNamingContext;
00062 import org.objectweb.jonas.server.LoaderManager;
00063 //import org.objectweb.jonas.server.JClassLoader;
00064 import org.objectweb.jonas.service.AbsServiceImpl;
00065 import org.objectweb.jonas.service.ServiceException;
00066 import org.objectweb.jonas.service.ServiceManager;
00067 
00068 import org.objectweb.util.monolog.api.BasicLevel;
00069 import org.objectweb.util.monolog.api.Logger;
00070 
00081 public class ResourceServiceImpl extends AbsServiceImpl implements
00082     ResourceService,
00083     ResourceServiceImplMBean {
00084 
00085     // Loggers used in the ResourceService
00089     private static Logger logger = null;
00093     private static Logger poolLogger = null;
00097     private static Logger setterLogger = null;
00101     private static Logger manageLogger = null;
00102 
00103     // Properties for inits
00104 
00105     // JCA resource service configuration parameters
00109     public static final String AUTOLOADDIR = "jonas.service.resource.autoloaddir";
00113     public static final String CLASS = "jonas.service.resource.class";
00117     public static final String JNDI_NAME = "jndiname";
00121     public static final String RAR_OBJNAME = "rarobjname";
00125     public static final String FACTORY_OFFSET = "factoryoffset";
00129     public static final String FACTORY_TYPE = "factorytype";
00133     public static final String RAR_FILENAME = "rarfilename";
00137     public static final String LNK_JNDI_NAME = "lnkjndiname";
00141     public static final String LNK_RAR_FILENAME = "lnkrarfilename";
00145     public static final String JONAS_RA_XML = "jonasraxml";
00149     public static final String RA_XML = "raxml";
00153     public static final String PARSINGWITHVALIDATION = "jonas.service.resource.parsingwithvalidation";
00157     public static final String RESOURCE_LIST = "jonas.service.resource.resources";
00161     public static final String THREADWAITTIMEOUT = "jonas.service.resource.threadwaittimeout";
00165     public static final String MINWORKTHREADS = "jonas.service.resource.minworkthreads";
00169     public static final String MAXWORKTHREADS = "jonas.service.resource.maxworkthreads";
00173     public static final String EXECTIMEOUT = "jonas.service.resource.worktimeout";
00174 
00178     public static final int DEF_WRK_THREADWAITTIMEOUT = 60;
00182     public static final int DEF_WRK_THREADS = 5;
00186     public static final int DEF_MAX_WRK_THREADS = 80;
00190     public static final int DEF_EXEC_TIME = 0;
00191 
00195 //    private static Hashtable jndiName2RA = new Hashtable();
00199 //    private static Hashtable fileName2RA = new Hashtable();
00203 //    private static Hashtable jndiName2Factory = new Hashtable();
00204 
00210     private Vector delayedRAs = new Vector();
00214     private boolean processingDelayed = false;
00215 
00219     private TransactionService ts = null;
00223     private TransactionManager tm = null;
00224 
00228     private MBeanServer mbeanServer = null;
00229 
00233     private Context ictx = null;
00234 
00238     private Vector autoNames = null;
00242     private Vector resourceNames = null;
00243 
00244 
00245     // J2EE CA 1.5 objects
00249     private ResourceWorkManager workMgr = null;
00253     private ResourceBootstrapContext bootCtx = null;
00254 
00258     public static final String JONAS_BASE = JProp.getJonasBase();
00259 
00263     public static final String WORK_RARS_DIR = JProp.getWorkDir() + File.separator + "rars";
00264 
00268     public static final String RARSDIR = JProp.getJonasBase() + File.separator + "rars";
00269 
00273     private ClassLoader appsClassLoader;
00274 
00278     public ResourceServiceImpl() {
00279     }
00280 
00281     //IMPLEMENTATION OF 'AbsServiceImpl' ABSTRACT CLASS
00291     public void doInit(Context ctx) {
00292         if (logger == null) {
00293             logger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".process");
00294         }
00295         if (poolLogger == null) {
00296             poolLogger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".pool");
00297         }
00298         if (setterLogger == null) {
00299             setterLogger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".setters");
00300         }
00301         if (manageLogger == null) {
00302             manageLogger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".management");
00303         }
00304 
00305         try {
00306             LoaderManager lm = LoaderManager.getInstance();
00307             appsClassLoader = lm.getAppsLoader();
00308         } catch (Exception e) {
00309             logger.log(BasicLevel.ERROR, "Cannot get the Applications ClassLoader from RAR Container Service: " + e);
00310             throw new ServiceException("Cannot get the Applications ClassLoader from RAR Container Service", e);
00311         }
00312 
00313         resourceNames = new Vector();
00314         autoNames = new Vector();
00315 
00316         // Avoid using NamingManager here: performance is not a goal here.
00317         try {
00318             ictx = new InitialContext();
00319         } catch (NamingException e) {
00320             logger.log(BasicLevel.ERROR, "Cannot create initial context when Resource service initializing");
00321             throw new ServiceException("Cannot create initial context when Resource service initializing", e);
00322         }
00323 
00324         // Add the rars of the jonas.service.resource.autoloaddir property
00325         String dirValue = null;
00326         try {
00327             dirValue = (String) ctx.lookup(AUTOLOADDIR);
00328             logger.log(BasicLevel.DEBUG, "autoloaddir= " + dirValue);
00329         } catch (NamingException e) {
00330             logger.log(BasicLevel.DEBUG, "No autoloaddir value specified in context, usually for client container");
00331         }
00332         if (dirValue != null) {
00333             StringTokenizer st = new StringTokenizer(dirValue, ",");
00334             String dirName = null;
00335             while (st.hasMoreTokens()) {
00336                 dirName = normalizePath(st.nextToken().trim());
00337                 addRars(dirName);
00338             }
00339         }
00340 
00341         // Get the list of the resource adapter names
00342         try {
00343             String rs = (String) ctx.lookup(RESOURCE_LIST);
00344             logger.log(BasicLevel.DEBUG, "resource list= " + rs);
00345             if (rs != null) {
00346                 StringTokenizer st = new StringTokenizer(rs, ",");
00347                 String resFilename = null;
00348                 while (st.hasMoreTokens()) {
00349                     resFilename = normalizePath(st.nextToken().trim());
00350                     resourceNames.add(resFilename);
00351                 }
00352             }
00353         } catch (NamingException e) {
00354             logger.log(BasicLevel.ERROR, "Cannot lookup the configuration context at Resource service starting");
00355         }
00356 
00357         // Get a reference to the Transaction service
00358         try {
00359             ServiceManager sm = ServiceManager.getInstance();
00360             ts = (TransactionService) sm.getTransactionService();
00361             tm = ts.getTransactionManager();
00362         } catch (Exception e) {
00363             logger.log(BasicLevel.ERROR, "Cannot get the Transaction service: " + e);
00364             throw new ServiceException("Cannot get the Transaction service: ", e);
00365         }
00366 
00367         // Get the JMX Server via JMX Service
00368         try {
00369             mbeanServer =
00370                 ((JmxService) ServiceManager.getInstance().getJmxService()).getJmxServer();
00371         } catch (Exception e) {
00372             // the JMX service may not be started
00373             mbeanServer = null;
00374         }
00375 
00376         // Init the XML parsing mode to no validation
00377         String parsingMode = "false";
00378         try {
00379             parsingMode = (String) ctx.lookup(PARSINGWITHVALIDATION);
00380         } catch (NamingException e) {
00381             // No problem if there is no value for 'parsingwithvalidation' (false by default)
00382             logger.log(BasicLevel.DEBUG, "No parsingwithvalidation value specified in context");
00383         }
00384         if ("false".equalsIgnoreCase(parsingMode)) {
00385             RarManagerWrapper.setParsingWithValidation(false);
00386             logger.log(BasicLevel.DEBUG, "XML parsing without validation");
00387         } else {
00388             logger.log(BasicLevel.DEBUG, "XML parsing with validation");
00389         }
00390 
00391         // Get the parameters for the WorkManager
00392         int execTime = 0;
00393         try {
00394             String etime = (String) ctx.lookup(EXECTIMEOUT);
00395             execTime = (new Integer(etime)).intValue();
00396         } catch (NamingException e) {
00397             // No problem if there is no value --> default value
00398             logger.log(BasicLevel.DEBUG, "No exectimeout value specified in context, usually for client container");
00399         }
00400 
00401         // Thread wait timeout
00402         int threadWaitTimeout = DEF_WRK_THREADWAITTIMEOUT;
00403         try {
00404             String tTimeout = (String) ctx.lookup(THREADWAITTIMEOUT);
00405             threadWaitTimeout = (new Integer(tTimeout)).intValue();
00406             if (threadWaitTimeout <= 0) {
00407                 threadWaitTimeout = DEF_WRK_THREADWAITTIMEOUT;
00408                 logger.log(BasicLevel.DEBUG, "Resetting thread wait timeout to " + DEF_WRK_THREADWAITTIMEOUT);
00409             }
00410         } catch (Exception e) {
00411             // default value will be used.
00412             logger.log(BasicLevel.DEBUG, "No workthread wait timeout value specified in context");
00413         }
00414 
00415         // MIN thread pool size
00416         int minWorkThreads = DEF_WRK_THREADS;
00417         try {
00418             String wThreads = (String) ctx.lookup(MINWORKTHREADS);
00419             minWorkThreads = (new Integer(wThreads)).intValue();
00420             if (minWorkThreads <= 0) {
00421                 minWorkThreads = DEF_WRK_THREADS;
00422                 logger.log(BasicLevel.DEBUG, "Resetting min threads to " + DEF_WRK_THREADS);
00423             }
00424         } catch (Exception e) {
00425             // default value will be used.
00426             logger.log(BasicLevel.DEBUG, "No min workthreads value specified in context");
00427         }
00428 
00429         // MAX thread pool size
00430         int maxWorkThreads = DEF_MAX_WRK_THREADS;
00431         try {
00432             String wThreads = (String) ctx.lookup(MAXWORKTHREADS);
00433             maxWorkThreads = (new Integer(wThreads)).intValue();
00434             if (maxWorkThreads <= 0) {
00435                 maxWorkThreads = DEF_MAX_WRK_THREADS;
00436                 logger.log(BasicLevel.DEBUG, "Resetting max threads to " + DEF_WRK_THREADS);
00437             }
00438         } catch (Exception e) {
00439             // default value will be used.
00440             logger.log(BasicLevel.DEBUG, "No max workthreads value specified in context");
00441         }
00442 
00443         // Create WorkManager and BootstrapContext
00444         workMgr = new ResourceWorkManager(tm, minWorkThreads, maxWorkThreads, threadWaitTimeout, execTime, logger);
00445         XATerminator xat = null;
00446         try {
00447             xat = ts.getCurrent().getXATerminator();
00448         } catch (Exception ex) {
00449             logger.log(BasicLevel.ERROR, "Unable to get an XATerminator from the TransactionService");
00450             throw new ServiceException("Unable to get an XATerminator from the TransactionService", ex);
00451         }
00452         bootCtx = new ResourceBootstrapContext(workMgr, xat);
00453 
00454         logger.log(BasicLevel.DEBUG, "ResourceService initialized");
00455     }
00456 
00461     public void doStart() throws ServiceException {
00462         // creates each resource
00463         String rarFileName = null;
00464         CompNamingContext ctx = null;
00465         for (int i = 0; i < resourceNames.size(); i++) {
00466             rarFileName = (String) resourceNames.elementAt(i);
00467             logger.log(BasicLevel.DEBUG, "rarFileName=" + rarFileName);
00468             try {
00469                 ctx = new CompNamingContext(rarFileName);
00470                 ctx.rebind("rarFileName", rarFileName);
00471                 ctx.rebind("isInEar", new Boolean(false));
00472                 ctx.rebind("classloader", appsClassLoader);
00473                 createResourceAdapter(ctx);
00474             } catch (Exception e) {
00475                 logger.log(BasicLevel.ERROR, "JOnAS: Cannot create resource: " + rarFileName + " exception: " + e);
00476                 e.printStackTrace();
00477             }
00478         }
00479 
00480         // process any delayed rars
00481         if (!delayedRAs.isEmpty()) {
00482           try {
00483             processingDelayed = true;
00484             Object [] rList = null;
00485             rList = delayedRAs.toArray();
00486             for (int i = 0; i < rList.length; i++) {
00487                 try {
00488                     createResourceAdapter((CompNamingContext) rList[i]);
00489                 } catch (Exception e) {
00490                     e.printStackTrace();
00491                     String rFile = (String) ((CompNamingContext) rList[i]).lookup("rarFileName");
00492                     logger.log(BasicLevel.ERROR, "JOnAS: Cannot create resource: " + rFile + " exception: " + e);
00493                     logger.log(BasicLevel.ERROR, "Please verify that the rarlink is correct/deployed");
00494                 }
00495             }
00496           } catch (Exception e) {
00497              e.printStackTrace();
00498              logger.log(BasicLevel.ERROR, "ResourceService: Error with delayed RAR file deployment\n" + e);
00499              throw new ServiceException("ResourceService: Error with delayed RAR file deployment", e);
00500           }
00501         }
00502 
00503         // Create and register the Resource Service MBean
00504         if (mbeanServer != null) {
00505             try {
00506                 mbeanServer.registerMBean(this, JonasObjectName.resourceService());
00507             } catch (InstanceAlreadyExistsException iae) {
00508                 logger.log(BasicLevel.ERROR, "Cannot start the Resource Service Already Exists:\n" + iae);
00509                 throw new ServiceException("Cannot start the Resource Service Already Exists", iae);
00510             } catch (Exception e) {
00511                 logger.log(BasicLevel.ERROR, "ResourceService: Cannot start the Resource service:\n" + e);
00512                 throw new ServiceException("ResourceService: Cannot start the Resource service", e);
00513             }
00514         }
00515 
00516     }
00517 
00522     public void doStop() throws ServiceException {
00523 
00524         ServiceException se = null;
00525         synchronized (Rar.fileName2RA) {
00526             Enumeration keys = Rar.fileName2RA.elements();
00527             while (keys.hasMoreElements()) {
00528                 Rar ra = (Rar) keys.nextElement();
00529                 try {
00530                     ra.unRegister();
00531                     Rar.fileName2RA.remove(ra);
00532                 } catch (Exception ex) {
00533                     logger.log(BasicLevel.ERROR, "ResourceService: Received the following:" + ex);
00534                     ex.printStackTrace();
00535                     if (se == null) {
00536                         se = new ServiceException(ex.getMessage());
00537                     }
00538                 }
00539             }
00540         }
00541         // unregister resource MBeans
00542         if (mbeanServer != null) {
00543             try {
00544                 // unregister resource Service MBean
00545                 mbeanServer.unregisterMBean(JonasObjectName.resourceService());
00546             } catch  (MBeanRegistrationException mr) {
00547                 logger.log(BasicLevel.ERROR, "Cannot cleanly stop the ResourceService: "
00548                                              + mr.getMessage());
00549             } catch  (InstanceNotFoundException infe) {
00550                 logger.log(BasicLevel.ERROR, "Cannot cleanly stop the ResourceService: "
00551                                              + infe.getMessage());
00552             } catch (Exception e) {
00553                 logger.log(BasicLevel.ERROR, "ResourceService: Cannot stop the Resource service:\n" + e);
00554                 throw new ServiceException("ResourceService: Cannot stop the Resource service", e);
00555             }
00556         }
00557 
00558         if (se != null) {
00559             throw se;
00560         }
00561         logger.log(BasicLevel.DEBUG, "ResourceService stopped");
00562     }
00563 
00564 
00565     // IMPLEMENTATION OF 'ResourceService' INTERFACE //
00566 
00574     public String createResourceAdapter(Context ctx) throws Exception {
00575 
00576         // Parameters :
00577         // rarFileName, isInEar, classloader and possible AltDD and earUrl
00578         String rarFileName;
00579         try {
00580             rarFileName = (String) ctx.lookup("rarFileName");
00581             ctx.rebind("deployed", new Boolean(false));
00582         } catch (Exception ex) {
00583             String err = "Error while getting parameter from context param.";
00584             logger.log(BasicLevel.ERROR, err + ex.getMessage());
00585             throw new ResourceServiceException(err, ex);
00586         }
00587 
00588         logger.log(BasicLevel.DEBUG, rarFileName);
00589         if (!rarFileName.endsWith(".rar")) {
00590             rarFileName += ".rar";
00591             ctx.rebind("rarFileName", rarFileName);
00592         }
00593 
00594         // Determine if the RAR file exists
00595         File f = new File(rarFileName);
00596         if (!f.exists()) {
00597             boolean found = false;
00598             String resFileName = null;
00599             // In case of the name is a rar file name, check also in
00600             // the JONAS_BASE/rars directory
00601             resFileName = RARSDIR + File.separator + rarFileName;
00602             f = new File(resFileName);
00603             found = f.exists();
00604             if (found) {
00605                 rarFileName = resFileName;
00606                 ctx.rebind("rarFileName", rarFileName);
00607             } else {
00608                 logger.log(BasicLevel.ERROR, "createResourceAdapter: " + resFileName + " not found");
00609                 Exception e = new NamingException(resFileName + " not found");
00610                 throw e;
00611             }
00612         }
00613 
00614         URL rarUrl = f.toURL();
00615 
00616         Rar rar = new Rar(ctx, getDomainName(), getJonasServerName(), workMgr, bootCtx);
00617 
00618         Context ctxRar = rar.processRar();
00619 
00620         boolean isDeployed = false;
00621         try {
00622             isDeployed = ((Boolean) ctx.lookup("deployed")).booleanValue();
00623         } catch (Exception ex) {
00624             String err = "Error while getting parameter(isDeployed) from context param.";
00625             logger.log(BasicLevel.ERROR, err + ex.getMessage());
00626             throw new ResourceServiceException(err, ex);
00627         }
00628 
00629         if (!isDeployed) {
00630             // If isDeployed in not set, then an rar-link was specified that is not deployed and if
00631             // we are already processing the delayed rar files, then throw an exception otherwise
00632             // update the delayedRAs vector and process it again later.
00633             if (processingDelayed) {
00634                 logger.log(BasicLevel.ERROR, "ResourceService.createRA: Resource (" + rarFileName + ") contains an invalid rarlink.");
00635                 throw new ResourceServiceException("resource input file incorrect: invalid rarlink");
00636             }
00637             delayedRAs.add(ctx);
00638             return null;
00639         }
00640 
00641         Vector jNames = rar.getJndinames();
00642         if (jNames != null) {
00643             for (int i = 0; i < jNames.size(); i++) {
00644                 Rar.jndiName2RA.put(jNames.get(i), rar);
00645             }
00646         }
00647 
00648         // Processed and deployed rar, so add it to our lists
00649         Rar.fileName2RA.put(rarUrl.getPath(), rar);
00650 
00651         String onRar = null;
00652         try {
00653             onRar = (String) ctx.lookup("onRar");
00654         } catch (Exception ex) {
00655             String err = "Error while getting parameter(onRar) from context param.";
00656             logger.log(BasicLevel.ERROR, err + ex.getMessage());
00657             throw new ResourceServiceException(err, ex);
00658         }
00659 
00660         return onRar.toString();
00661     }
00662 
00663 
00678     public void deployRars(Context ctx) throws ResourceServiceException {
00679 
00680         // Gets the parameters from the context :
00681         //    - urls the list of the urls of the rars to deploy.
00682         //    - earRootURL the URL of the ear application file.
00683         //    - earClassLoader the ear classLoader of the j2ee app.
00684         //    - altDDs the optional URI of deployment descriptor.
00685         URL[] urls = null;
00686         URL earUrl = null;
00687         ClassLoader earClassLoader = null;
00688         URL[] altDDs = null;
00689         try {
00690             urls = (URL[]) ctx.lookup("urls");
00691             earUrl = (URL) ctx.lookup("earUrl");
00692             earClassLoader = (ClassLoader) ctx.lookup("earClassLoader");
00693             altDDs = (URL[]) ctx.lookup("altDDs");
00694         } catch (NamingException e) {
00695             String err = "Error while getting parameter from context param ";
00696             logger.log(BasicLevel.ERROR, err + e.getMessage());
00697             throw new ResourceServiceException(err, e);
00698         }
00699 
00700         delayedRAs.clear(); // reset the delayed RAs
00701         // Deploy all the rars of the ear application.
00702         for (int i = 0; i < urls.length; i++) {
00703             // Get the name of a rar to deploy.
00704             String fileName = urls[i].getFile();
00705             logger.log(BasicLevel.DEBUG, "Deploy rar '" + fileName + "' for the ear service");
00706 
00707             // The context to give for the creation of the container
00708             // associated to the ejb-jar.
00709             Context contctx = null;
00710             try {
00711                 contctx = new CompNamingContext(fileName);
00712                 contctx.rebind("rarFileName", fileName);
00713                 contctx.rebind("isInEar", new Boolean(true));
00714                 contctx.rebind("earUrl", earUrl);
00715                 if (altDDs[i] != null) {
00716                     contctx.rebind("altDD", altDDs[i]);
00717                 }
00718                 contctx.rebind("classloader", earClassLoader);
00719                 createResourceAdapter(contctx);
00720             } catch (Exception e) {
00721                 // A rar is corrupted so undeploy all the deployed rar
00722                 // of the ear application.
00723                 logger.log(BasicLevel.ERROR, "Error when deploying '" + fileName + "'");
00724                 logger.log(BasicLevel.ERROR, e.getMessage());
00725                 logger.log(BasicLevel.ERROR, "Undeploy rar of the ear application");
00726 
00727                 for (int j = 0; j < i; j++) {
00728                     String rarFileName = urls[j].getFile();
00729                     try {
00730                         // Try to undeploy a rar of the ear application.
00731                         CompNamingContext compctx = new CompNamingContext(rarFileName);
00732                         compctx.rebind("rarFileName", rarFileName);
00733                         compctx.rebind("isInEar", new Boolean(true));
00734                         contctx.rebind("earUrl", earUrl);
00735                         unRegisterRar(compctx);
00736                     } catch (Exception ex) {
00737                         // Cannot undeploy a rar of the ear application
00738                         // So there is an error message.
00739                         logger.log(BasicLevel.ERROR, "Error when undeploying '" + rarFileName + "'");
00740                         logger.log(BasicLevel.ERROR, ex.getMessage());
00741                         logger.log(BasicLevel.ERROR, "Cannot undeploy rar of the ear application");
00742                     }
00743 
00744                 }
00745                 throw new ResourceServiceException("Error during the deployment", e);
00746             }
00747         }
00748         // process any delayed rars
00749         if (!delayedRAs.isEmpty()) {
00750           try {
00751             processingDelayed = true;
00752             Object [] rList = null;
00753             rList = delayedRAs.toArray();
00754             for (int i = 0; i < rList.length; i++) {
00755                 try {
00756                     createResourceAdapter((CompNamingContext) rList[i]);
00757                 } catch (Exception e) {
00758                     logger.log(BasicLevel.ERROR, "JOnAS: Cannot create resource: " + (String) rList[i] + " exception: " + e);
00759                     logger.log(BasicLevel.ERROR, "Please verify that the rarlink is correct");
00760                     e.printStackTrace();
00761                 }
00762             }
00763           } catch (Exception e) {
00764             logger.log(BasicLevel.ERROR, "ResourceService: Error with delayed RAR file deployment\n" + e);
00765             throw new ServiceException("ResourceService: Error with delayed RAR file deployment", e);
00766           }
00767         }
00768     }
00769 
00770 
00777     public void unDeployRars(URL[] urls, URL earUrl) {
00778         for (int i = 0; i < urls.length; i++) {
00779             String fileName = urls[i].getFile();
00780             if (Rar.fileName2RA.containsKey(fileName)) {
00781                 try {
00782                     // Try to undeploy a rar of the ear application.
00783                     CompNamingContext compctx = new CompNamingContext(fileName);
00784                     compctx.rebind("rarFileName", fileName);
00785                     compctx.rebind("isInEar", new Boolean(true));
00786                     compctx.rebind("earUrl", earUrl);
00787                     unRegisterRar(compctx);
00788                 } catch (Exception ex) {
00789                     logger.log(BasicLevel.ERROR, "Cannot undeploy resource: " + fileName + " " + ex);
00790                 }
00791             } else {
00792                 logger.log(BasicLevel.ERROR, "Cannot remove the non-existant rar '" + fileName + "'");
00793             }
00794         }
00795     }
00796 
00797 
00803     public void unRegisterRar(Context ctx) throws Exception {
00804         String rarFileName;
00805         try {
00806             rarFileName = (String) ctx.lookup("rarFileName");
00807         } catch (NamingException e) {
00808             String err = "Error while getting parameter from context param.";
00809             logger.log(BasicLevel.ERROR, err + e.getMessage());
00810             throw new ResourceServiceException(err, e);
00811         } catch (Exception ex) {
00812             String err = "Error while getting parameter from context param.";
00813             logger.log(BasicLevel.ERROR, err + ex.getMessage());
00814             throw new ResourceServiceException(err, ex);
00815         }
00816 
00817         if (manageLogger.isLoggable(BasicLevel.DEBUG)) {
00818             manageLogger.log(BasicLevel.DEBUG, "TEST Unregister MBeans for RAR in file: " + rarFileName);
00819         }
00820 
00821         String rarPath = (new File(rarFileName)).toURL().getPath();
00822         Rar rar = (Rar) Rar.fileName2RA.get(rarPath);
00823         Vector jNames = rar.getJndinames();
00824         rar.unRegister();
00825 
00826         // Remove rars from hashtables
00827         for (int i = 0; i < jNames.size(); i++) {
00828             Rar.jndiName2RA.remove((String) jNames.get(i));
00829         }
00830         Rar.fileName2RA.remove(rarPath);
00831         resourceNames.remove(normalizePath(rarFileName));
00832 
00833         logger.log(BasicLevel.INFO,
00834                     "ResourceService: unRegisterRar: " + rarFileName);
00835     }
00836 
00837     //--------------------------------------------------------------
00838     //           MBean Methods
00839     //--------------------------------------------------------------
00840 
00844     public Integer getCurrentNumberOfResource() {
00845         return getCurrentNumberOfRars();
00846     }
00847 
00848 
00852     public Integer getCurrentNumberOfRars() {
00853         return new Integer(Rar.fileName2RA.size());
00854     }
00855 
00856 
00860     public List getDeployedRars() {
00861         ArrayList al = new ArrayList();
00862         String rarFileName = null;
00863         Enumeration keys = Rar.fileName2RA.keys();
00864         while (keys.hasMoreElements()) {
00865             rarFileName = keys.nextElement().toString();
00866             try {
00867                 al.add((new File(rarFileName)).toURL().getPath());
00868             } catch (Exception e) {
00869                 logger.log(BasicLevel.DEBUG, "Unable to add rarfile " + rarFileName + " to arraylist");
00870             }
00871         }
00872         return al;
00873     }
00874 
00882     public List getInstalledRars() throws Exception {
00883         // get JAR files found in JONAS_BASE/rars
00884         ArrayList al = JModule.getInstalledContainersInDir(RARSDIR, JModule.RAR_EXTENSION
00885             , JModule.RAR_CHILD_DIR, JModule.RAR_CONFIRM_FILE);
00886         // get RAR files found in all autoload directories
00887         for (int i = 0; i < autoNames.size(); i++) {
00888             al.addAll(JModule.getInstalledContainersInDir(autoNames.get(i).toString(),
00889                 JModule.RAR_EXTENSION, JModule.RAR_CHILD_DIR, JModule.RAR_CONFIRM_FILE));
00890         }
00891         return al;
00892     }
00893 
00899     public Set getRarNames() {
00900         HashSet names = new HashSet();
00901         String rarFileName = null;
00902         for (int i = 0; i < resourceNames.size(); i++) {
00903             rarFileName = (String) resourceNames.elementAt(i);
00904             names.add(rarFileName);
00905         }
00906         return names;
00907     }
00908 
00909 
00918     public String deployRarMBean(String fileName) throws RemoteException, ResourceServiceException {
00919         Context ctx = null;
00920         String onRar = null;
00921         try {
00922             ctx = new CompNamingContext(fileName);
00923             ctx.rebind("rarFileName", fileName);
00924             ctx.rebind("isInEar", new Boolean(false));
00925             ctx.rebind("classloader", appsClassLoader);
00926             onRar = createResourceAdapter(ctx);
00927         } catch (Exception e) {
00928             String err = "Error when deploying the rar file: " + fileName;
00929             logger.log(BasicLevel.ERROR, err + e.getMessage());
00930             e.printStackTrace();
00931             throw new ResourceServiceException(err, e);
00932         }
00933 
00934         return onRar;
00935     }
00936 
00943     public String deployRar(String fileName) throws Exception {
00944         return deployRarMBean(fileName);
00945     }
00946 
00952     public Boolean isRarDeployed(String fileName) {
00953         return new Boolean(isRarLoaded(fileName));
00954     }
00955 
00962     public boolean isRarDeployedByUnpackName(String unpackName) {
00963         logger.log(BasicLevel.DEBUG, "entering for unpackName= " + unpackName);
00964 /*        // for each rar loaded
00965         Enumeration lc = ears.elements();
00966         while (lc.hasMoreElements()) {
00967             Ear ear = (Ear) lc.nextElement();
00968 
00969             // get unpack name of the ear
00970             String deployedUnpackName = new File(ear.getUnpackName()).getName() ;
00971             logger.log(BasicLevel.DEBUG, "deployedUnpackName=" + deployedUnpackName);
00972 
00973             if (deployedUnpackName.equals(unpackName)) {
00974                 return true;
00975             }
00976             // else, go to the next loop
00977         }
00978         // not found
00979 */
00980         return false;
00981     }
00982 
00990     public void unDeployRarMBean(String fileName) throws RemoteException, ResourceServiceException {
00991         /* We have only the name of the file, not its associated path, so we look in
00992            the current directory and in the rar applications directory
00993         */
00994 
00995         boolean found = true;
00996         logger.log(BasicLevel.DEBUG, "Trying to undeploy: " + fileName
00997                                      + " with the following deployed:" + Rar.fileName2RA);
00998 
00999         try {
01000             // Determine if the RAR is in list
01001             File f = new File(fileName);
01002             if (!Rar.fileName2RA.containsKey(f.toURL().getPath())) {
01003                 found = false;
01004                 // Check also in the JONAS_BASE/rars directory
01005                 String resFileName = RARSDIR + File.separator + fileName;
01006                 f = new File(resFileName);
01007                 if (Rar.fileName2RA.containsKey(f.toURL().getPath())) {
01008                     fileName = resFileName;
01009                     found = true;
01010                 }
01011             }
01012 
01013             if (!found) {
01014                 String err = "Cannot undeploy the rar '" + fileName + "', it is not deployed.";
01015                 logger.log(BasicLevel.ERROR, err);
01016                 throw new ResourceServiceException(err);
01017             }
01018         } catch (Exception ex) {
01019             String err = "Error trying to undeployRarMBean " + fileName;
01020             logger.log(BasicLevel.ERROR, err + ex.getMessage());
01021             throw new ResourceServiceException(err, ex);
01022         }
01023 
01024         //We've got the file, now we bind the params
01025         CompNamingContext compctx = null;
01026         try {
01027             compctx = new CompNamingContext(fileName);
01028             compctx.rebind("rarFileName", fileName);
01029             compctx.rebind("isInEar", new Boolean(false));
01030             //Call the function
01031             unRegisterRar(compctx);
01032         } catch (NamingException e) {
01033             String err = "Error when binding parameters";
01034             logger.log(BasicLevel.ERROR, err + e.getMessage());
01035             throw new ResourceServiceException(err, e);
01036         } catch (Exception ex) {
01037             String err = "Error when unRegistering rar " + fileName;
01038             logger.log(BasicLevel.ERROR, err + ex.getMessage());
01039             ex.printStackTrace();
01040             throw new ResourceServiceException(err, ex);
01041         }
01042 
01043     }
01044 
01050     public void unDeployRar(String fileName) throws Exception {
01051         unDeployRarMBean(fileName);
01052     }
01053 
01059     public boolean isRarLoaded(String fileName) {
01060 
01061         String updateName = null;
01062         boolean isLoaded = false;
01063         try {
01064             if (Rar.fileName2RA.containsKey(fileName)) {
01065                 isLoaded = true;
01066             }
01067             // If not found check the exact filename
01068             if (!isLoaded) {
01069                 // construct name for rars in JONAS_BASE/rars directory
01070                 updateName = RARSDIR + File.separator + fileName;
01071 
01072                 //Check if the rar is already deployed or not
01073                 if (Rar.fileName2RA.containsKey(updateName)) {
01074                     isLoaded = true;
01075                 }
01076             }
01077         } catch (Exception e) {
01078             String err = "Cannot determine if the rar is deployed or not";
01079             logger.log(BasicLevel.ERROR, err);
01080             return false;
01081         }
01082 
01083         return isLoaded;
01084     }
01085 
01086 
01093     public List getDeployableRars() throws Exception {
01094         List al = getInstalledRars();
01095         al.removeAll(getDeployedRars());
01096         return al;
01097     }
01098 
01103     public List getAutoloadDirectories() {
01104         ArrayList al = new ArrayList();
01105         for (int i = 0; i < autoNames.size(); i++) {
01106             try {
01107                 al.add((new File(autoNames.get(i).toString())).toURL().getPath());
01108             } catch (Exception e) {
01109                 logger.log(BasicLevel.DEBUG, "Can't get autoload directories : " + e.getMessage());
01110             }
01111         }
01112         return al;
01113     }
01114 
01119     public String getRarsDirectory() {
01120         String sRet = null;
01121         try {
01122             sRet = (new File(RARSDIR)).toURL().getPath();
01123         } catch (Exception e) {
01124             throw new RuntimeException("Cannot get the RARS directory", e);
01125         }
01126         return sRet;
01127     }
01128 
01129     //--------------------------------------------------------------
01130     //           Private Methods
01131     //--------------------------------------------------------------
01132 
01141     private void addRars(String dirPath) {
01142         boolean found = false;
01143 
01144         // Look the directory relative to where the JOnAS server is launch or
01145         // if the path is absolute.
01146         File dir = new File(dirPath);
01147         found = dir.isDirectory();
01148 
01149         if (!found) {
01150             // Look the directory relative to the $JONAS_BASE/rars directory
01151             dir = new File(RARSDIR + File.separator + dirPath);
01152             found = dir.isDirectory();
01153         }
01154 
01155         if (found) {
01156             autoNames.add(dir);
01157             addRarsFrom(dir);
01158         } else {
01159             String err = "Warning: Cannot load dir: '" + dirPath + "' ";
01160             err += "is not a directory or directory doesn't exist";
01161             logger.log(BasicLevel.WARN, err);
01162         }
01163     }
01164 
01170     private void addRarsFrom(File dir) throws ResourceServiceException {
01171         try {
01172             if (dir.isDirectory()) {
01173                 File[] files = dir.listFiles();
01174                 for (int i = 0; i < files.length; i++) {
01175                     if (files[i].isFile()) {
01176                         if (files[i].getPath().toLowerCase().endsWith(".rar")) {
01177                             resourceNames.add(files[i].getCanonicalPath());
01178                         }
01179                     } else {
01180                         autoNames.add(files[i]);
01181                         addRarsFrom(files[i]);
01182                     }
01183                 }
01184             } else {
01185                 String err = "Cannot load dir: '" + dir.getPath();
01186                 err += "' is not a directory";
01187                 logger.log(BasicLevel.ERROR, err);
01188                 throw new ResourceServiceException(err);
01189             }
01190         } catch (IOException e) {
01191             String err = "Invalid file name '" + dir.getPath();
01192             logger.log(BasicLevel.ERROR, err);
01193             throw new ResourceServiceException(err, e);
01194         }
01195     }
01196 
01202     private String normalizePath(String path) {
01203         String ret = null;
01204         if (File.separatorChar == '/') {
01205             ret = path.replace('\\', File.separatorChar);
01206         } else {
01207             ret = path.replace('/', File.separatorChar);
01208         }
01209         return ret;
01210     }
01211 }
01212 
01213 

Generated on Tue Feb 15 15:05:20 2005 for JOnAS by  doxygen 1.3.9.1