0001: /**
0002: * JOnAS: Java(TM) Open Application Server
0003: * Copyright (C) 1999-2005 Bull S.A.
0004: * Contact: jonas-team@objectweb.org
0005: *
0006: * This library is free software; you can redistribute it and/or
0007: * modify it under the terms of the GNU Lesser General Public
0008: * License as published by the Free Software Foundation; either
0009: * version 2.1 of the License, or any later version.
0010: *
0011: * This library is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * Lesser General Public License for more details.
0015: *
0016: * You should have received a copy of the GNU Lesser General Public
0017: * License along with this library; if not, write to the Free Software
0018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
0019: * USA
0020: *
0021: * --------------------------------------------------------------------------
0022: * $Id: ResourceServiceImpl.java 9708 2006-10-10 06:12:37Z ehardesty $
0023: * --------------------------------------------------------------------------
0024: */package org.objectweb.jonas.resource;
0025:
0026: import java.io.File;
0027: import java.io.IOException;
0028: import java.net.URL;
0029: import java.rmi.RemoteException;
0030: import java.util.ArrayList;
0031: import java.util.Enumeration;
0032: import java.util.HashSet;
0033: import java.util.Iterator;
0034: import java.util.List;
0035: import java.util.Properties;
0036: import java.util.Set;
0037: import java.util.StringTokenizer;
0038: import java.util.Vector;
0039:
0040: import javax.management.InstanceAlreadyExistsException;
0041: import javax.management.InstanceNotFoundException;
0042: import javax.management.MBeanRegistrationException;
0043: import javax.management.MBeanServer;
0044: import javax.management.ObjectName;
0045: import javax.management.modelmbean.ModelMBean;
0046: import javax.naming.Context;
0047: import javax.naming.NamingException;
0048: import javax.resource.spi.XATerminator;
0049: import javax.resource.spi.work.WorkManager;
0050:
0051: import org.apache.commons.modeler.ManagedBean;
0052: import org.objectweb.jonas.common.JModule;
0053: import org.objectweb.jonas.common.JProp;
0054: import org.objectweb.jonas.common.Log;
0055: import org.objectweb.jonas.container.EJBService;
0056: import org.objectweb.jonas.jmx.J2eeObjectName;
0057: import org.objectweb.jonas.jmx.JmxService;
0058: import org.objectweb.jonas.jmx.JonasObjectName;
0059: import org.objectweb.jonas.jtm.TransactionService;
0060: import org.objectweb.jonas.management.JonasMBeanTools;
0061: import org.objectweb.jonas.naming.CompNamingContext;
0062: import org.objectweb.jonas.server.LoaderManager;
0063: import org.objectweb.jonas.service.AbsServiceImpl;
0064: import org.objectweb.jonas.service.ServiceException;
0065: import org.objectweb.jonas.service.ServiceManager;
0066: import org.objectweb.jonas_lib.JWorkManager;
0067: import org.objectweb.jonas_rar.deployment.lib.wrapper.RarManagerWrapper;
0068: import org.objectweb.transaction.jta.TransactionManager;
0069: import org.objectweb.util.monolog.api.BasicLevel;
0070: import org.objectweb.util.monolog.api.Logger;
0071:
0072: /**
0073: * JCA resource service implmentation
0074: * @author Philippe Coq
0075: * Contributor(s):
0076: * JOnAS 2.4 Sebastien Chassande-Barrioz (sebastien.chassande@inrialpes.fr)
0077: * JOnAS 3.0 Eric Hardesty (Eric.Hardesty@bull.com)
0078: * JOnAS 4.0 Adriana Danes (JSR 77 + use of Jakarta Modeler Component : http://jakarta.apache.org/commons/modeler)
0079: * Eric Hardesty (J2CA 1.5)
0080: *
0081: */
0082: public class ResourceServiceImpl extends AbsServiceImpl implements
0083: ResourceService, ResourceServiceImplMBean {
0084:
0085: // Loggers used in the ResourceService
0086: /**
0087: * Main logger
0088: */
0089: private static Logger logger = null;
0090: /**
0091: * Pool infomation logger
0092: */
0093: private static Logger poolLogger = null;
0094: /**
0095: * Config property setter logger
0096: */
0097: private static Logger setterLogger = null;
0098: /**
0099: * Management logger
0100: */
0101: private static Logger manageLogger = null;
0102:
0103: // Properties for inits
0104:
0105: // JCA resource service configuration parameters
0106: /**
0107: * Autoload directory property name
0108: */
0109: public static final String AUTOLOADDIR = "jonas.service.resource.autoloaddir";
0110: /**
0111: * Service class property name
0112: */
0113: public static final String CLASS = "jonas.service.resource.class";
0114: /**
0115: * Jndiname property name
0116: */
0117: public static final String JNDI_NAME = "jndiname";
0118: /**
0119: * Rar object property name
0120: */
0121: public static final String RAR_OBJNAME = "rarobjname";
0122: /**
0123: * Factory offset property name
0124: */
0125: public static final String FACTORY_OFFSET = "factoryoffset";
0126: /**
0127: * Factory type property name
0128: */
0129: public static final String FACTORY_TYPE = "factorytype";
0130: /**
0131: * Rar filename property name
0132: */
0133: public static final String RAR_FILENAME = "rarfilename";
0134: /**
0135: * Jndiname link property name
0136: */
0137: public static final String LNK_JNDI_NAME = "lnkjndiname";
0138: /**
0139: * Link Rar filename property name
0140: */
0141: public static final String LNK_RAR_FILENAME = "lnkrarfilename";
0142: /**
0143: * Jonas ra.xml property name
0144: */
0145: public static final String JONAS_RA_XML = "jonasraxml";
0146: /**
0147: * ra.xml property name
0148: */
0149: public static final String RA_XML = "raxml";
0150: /**
0151: * Parsing validation property name
0152: */
0153: public static final String PARSINGWITHVALIDATION = "jonas.service.resource.parsingwithvalidation";
0154: /**
0155: * Resources list property name
0156: */
0157: public static final String RESOURCE_LIST = "jonas.service.resource.resources";
0158: /**
0159: * Thread timeout
0160: */
0161: public static final String THREADWAITTIMEOUT = "jonas.service.resource.threadwaittimeout";
0162: /**
0163: * Minimum number of work threads property name
0164: */
0165: public static final String MINWORKTHREADS = "jonas.service.resource.minworkthreads";
0166: /**
0167: * Maximum number of work threads property name
0168: */
0169: public static final String MAXWORKTHREADS = "jonas.service.resource.maxworkthreads";
0170: /**
0171: * Work max execution timeout property name
0172: */
0173: public static final String EXECTIMEOUT = "jonas.service.resource.worktimeout";
0174:
0175: /**
0176: * Default work thread timeout
0177: */
0178: public static final int DEF_WRK_THREADWAITTIMEOUT = 60;
0179: /**
0180: * Default number of work threads
0181: */
0182: public static final int DEF_WRK_THREADS = 5;
0183: /**
0184: * Default max number of work threads
0185: */
0186: public static final int DEF_MAX_WRK_THREADS = 80;
0187: /**
0188: * Maximum work execution timeout (0 is unlimited)
0189: */
0190: public static final int DEF_EXEC_TIME = 0;
0191:
0192: /**
0193: * Hashtable mapping a jndiname to an RAR object
0194: */
0195: // private static Hashtable jndiName2RA = new Hashtable();
0196: /**
0197: * Hashtable mapping a filename to an RAR object
0198: */
0199: // private static Hashtable fileName2RA = new Hashtable();
0200: /**
0201: * Hashtable mapping a jndiname to an "external" factory
0202: */
0203: // private static Hashtable jndiName2Factory = new Hashtable();
0204: /**
0205: * This vector is list of RAR files that will be deployed after all
0206: * other RAR files have been deployed. The problem is that these RAR
0207: * files are associated with another RAR file that has not been processed.
0208: */
0209: private Vector delayedRAs = new Vector();
0210: /**
0211: * boolean to determine if processing of delayed Rars has begun
0212: */
0213: private boolean processingDelayed = false;
0214:
0215: /**
0216: * The transaction service for this server
0217: */
0218: private TransactionService ts = null;
0219: /**
0220: * The transaction manager for this server
0221: */
0222: private TransactionManager tm = null;
0223:
0224: /**
0225: * Reference to a MBean server.
0226: */
0227: private MBeanServer mbeanServer = null;
0228:
0229: /**
0230: * Autoload directory names
0231: */
0232: private Vector autoNames = null;
0233: /**
0234: * List of resource names
0235: */
0236: private Vector resourceNames = null;
0237:
0238: // J2EE CA 1.5 objects
0239: /**
0240: * Work Manager for the Resource service
0241: */
0242: private WorkManager workMgr = null;
0243: /**
0244: * BootstrapContext for the Resource service
0245: */
0246: private ResourceBootstrapContext bootCtx = null;
0247:
0248: /**
0249: * The name of the JONAS_BASE directory
0250: */
0251: public static final String JONAS_BASE = JProp.getJonasBase();
0252:
0253: /**
0254: * The name of the working apps directory.
0255: */
0256: public static final String WORK_RARS_DIR = JProp.getWorkDir()
0257: + File.separator + "rars";
0258:
0259: /**
0260: * The name of the rars directory
0261: */
0262: public static final String RARSDIR = JProp.getJonasBase()
0263: + File.separator + "rars";
0264:
0265: /**
0266: * Application parent classloader
0267: */
0268: private ClassLoader appsClassLoader;
0269:
0270: /**
0271: * Default construtor for ResourceService
0272: */
0273: public ResourceServiceImpl() {
0274: }
0275:
0276: //IMPLEMENTATION OF 'AbsServiceImpl' ABSTRACT CLASS
0277: /**
0278: * - Get the loggers
0279: * - Get the global jndi context
0280: * - Get the list of the resource adapters. The list is reachable in the
0281: * - context parameter under the name RESOURCE_LIST.
0282: * - Get the transaction manager into the jndi
0283: * - Set the XML validation property
0284: * @param ctx Context
0285: */
0286: public void doInit(Context ctx) {
0287: if (logger == null) {
0288: logger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".process");
0289: }
0290: if (poolLogger == null) {
0291: poolLogger = Log.getLogger(Log.JONAS_JCA_PREFIX + ".pool");
0292: }
0293: if (setterLogger == null) {
0294: setterLogger = Log.getLogger(Log.JONAS_JCA_PREFIX
0295: + ".setters");
0296: }
0297: if (manageLogger == null) {
0298: manageLogger = Log.getLogger(Log.JONAS_JCA_PREFIX
0299: + ".management");
0300: }
0301:
0302: try {
0303: LoaderManager lm = LoaderManager.getInstance();
0304: appsClassLoader = lm.getAppsLoader();
0305: } catch (Exception e) {
0306: logger.log(BasicLevel.ERROR,
0307: "Cannot get the Applications ClassLoader from RAR Container Service: "
0308: + e);
0309: throw new ServiceException(
0310: "Cannot get the Applications ClassLoader from RAR Container Service",
0311: e);
0312: }
0313:
0314: resourceNames = new Vector();
0315: autoNames = new Vector();
0316:
0317: // Add the rars of the jonas.service.resource.autoloaddir property
0318: String dirValue = null;
0319: try {
0320: dirValue = (String) ctx.lookup(AUTOLOADDIR);
0321: if (logger.isLoggable(BasicLevel.DEBUG)) {
0322: logger
0323: .log(BasicLevel.DEBUG, "autoloaddir= "
0324: + dirValue);
0325: }
0326: } catch (NamingException e) {
0327: if (logger.isLoggable(BasicLevel.DEBUG)) {
0328: logger
0329: .log(BasicLevel.DEBUG,
0330: "No autoloaddir value specified in context, usually for client container");
0331: }
0332: }
0333: if (dirValue != null) {
0334: StringTokenizer st = new StringTokenizer(dirValue, ",");
0335: String dirName = null;
0336: while (st.hasMoreTokens()) {
0337: dirName = normalizePath(st.nextToken().trim());
0338: addRars(dirName);
0339: }
0340: }
0341:
0342: // Get the list of the resource adapter names
0343: try {
0344: String rs = (String) ctx.lookup(RESOURCE_LIST);
0345: if (logger.isLoggable(BasicLevel.DEBUG)) {
0346: logger.log(BasicLevel.DEBUG, "resource list= " + rs);
0347: }
0348: if (rs != null) {
0349: StringTokenizer st = new StringTokenizer(rs, ",");
0350: String resFilename = null;
0351: while (st.hasMoreTokens()) {
0352: resFilename = normalizePath(st.nextToken().trim());
0353: resourceNames.add(resFilename);
0354: }
0355: }
0356: } catch (NamingException e) {
0357: logger
0358: .log(BasicLevel.ERROR,
0359: "Cannot lookup the configuration context at Resource service starting");
0360: }
0361:
0362: // Get a reference to the Transaction service
0363: try {
0364: ServiceManager sm = ServiceManager.getInstance();
0365: ts = (TransactionService) sm.getTransactionService();
0366: tm = ts.getTransactionManager();
0367: } catch (Exception e) {
0368: logger.log(BasicLevel.ERROR,
0369: "Cannot get the Transaction service: " + e);
0370: throw new ServiceException(
0371: "Cannot get the Transaction service: ", e);
0372: }
0373:
0374: // Get the JMX Server via JMX Service
0375: try {
0376: mbeanServer = ((JmxService) ServiceManager.getInstance()
0377: .getJmxService()).getJmxServer();
0378: } catch (Exception e) {
0379: // the JMX service may not be started
0380: mbeanServer = null;
0381: }
0382:
0383: // Init the XML parsing mode to no validation
0384: String parsingMode = "false";
0385: try {
0386: parsingMode = (String) ctx.lookup(PARSINGWITHVALIDATION);
0387: } catch (NamingException e) {
0388: // No problem if there is no value for 'parsingwithvalidation' (false by default)
0389: if (logger.isLoggable(BasicLevel.DEBUG)) {
0390: logger
0391: .log(BasicLevel.DEBUG,
0392: "No parsingwithvalidation value specified in context");
0393: }
0394: }
0395: if ("false".equalsIgnoreCase(parsingMode)) {
0396: RarManagerWrapper.setParsingWithValidation(false);
0397: if (logger.isLoggable(BasicLevel.DEBUG)) {
0398: logger.log(BasicLevel.DEBUG,
0399: "XML parsing without validation");
0400: }
0401: } else {
0402: if (logger.isLoggable(BasicLevel.DEBUG)) {
0403: logger.log(BasicLevel.DEBUG,
0404: "XML parsing with validation");
0405: }
0406: }
0407:
0408: // Get the WorkManager defined in the EJB Service, if it exists
0409: EJBService ejbService = null;
0410: try {
0411: ejbService = (EJBService) ServiceManager.getInstance()
0412: .getEjbService();
0413: workMgr = ejbService.getWorkManager();
0414: } catch (Exception e) {
0415: // the EJB service may not be started
0416: workMgr = null;
0417: }
0418:
0419: // Get the parameters for the WorkManager
0420: int execTime = 0;
0421: try {
0422: String etime = (String) ctx.lookup(EXECTIMEOUT);
0423: execTime = (new Integer(etime)).intValue();
0424: } catch (NamingException e) {
0425: // No problem if there is no value --> default value
0426: if (logger.isLoggable(BasicLevel.DEBUG)) {
0427: logger
0428: .log(BasicLevel.DEBUG,
0429: "No exectimeout value specified in context, usually for client container");
0430: }
0431: }
0432:
0433: // Thread wait timeout
0434: int threadWaitTimeout = DEF_WRK_THREADWAITTIMEOUT;
0435: try {
0436: String tTimeout = (String) ctx.lookup(THREADWAITTIMEOUT);
0437: threadWaitTimeout = (new Integer(tTimeout)).intValue();
0438: if (threadWaitTimeout <= 0) {
0439: threadWaitTimeout = DEF_WRK_THREADWAITTIMEOUT;
0440: if (logger.isLoggable(BasicLevel.DEBUG)) {
0441: logger.log(BasicLevel.DEBUG,
0442: "Resetting thread wait timeout to "
0443: + DEF_WRK_THREADWAITTIMEOUT);
0444: }
0445: }
0446: } catch (Exception e) {
0447: // default value will be used.
0448: if (logger.isLoggable(BasicLevel.DEBUG)) {
0449: logger
0450: .log(BasicLevel.DEBUG,
0451: "No workthread wait timeout value specified in context");
0452: }
0453: }
0454:
0455: // MIN thread pool size
0456: int minWorkThreads = DEF_WRK_THREADS;
0457: try {
0458: String wThreads = (String) ctx.lookup(MINWORKTHREADS);
0459: minWorkThreads = (new Integer(wThreads)).intValue();
0460: if (minWorkThreads <= 0) {
0461: minWorkThreads = DEF_WRK_THREADS;
0462: if (logger.isLoggable(BasicLevel.DEBUG)) {
0463: logger.log(BasicLevel.DEBUG,
0464: "Resetting min threads to "
0465: + DEF_WRK_THREADS);
0466: }
0467: }
0468: } catch (Exception e) {
0469: // default value will be used.
0470: if (logger.isLoggable(BasicLevel.DEBUG)) {
0471: logger
0472: .log(BasicLevel.DEBUG,
0473: "No min workthreads value specified in context");
0474: }
0475: }
0476:
0477: // MAX thread pool size
0478: int maxWorkThreads = DEF_MAX_WRK_THREADS;
0479: try {
0480: String wThreads = (String) ctx.lookup(MAXWORKTHREADS);
0481: maxWorkThreads = (new Integer(wThreads)).intValue();
0482: } catch (Exception e) {
0483: // default value will be used.
0484: if (logger.isLoggable(BasicLevel.DEBUG)) {
0485: logger
0486: .log(BasicLevel.DEBUG,
0487: "No max workthreads value specified in context");
0488: }
0489: }
0490:
0491: // Create WorkManager if we cannot use the one defined in ejb
0492: if (maxWorkThreads > 0 || workMgr == null) {
0493: logger.log(BasicLevel.DEBUG,
0494: "Create a WorkManager for Resources");
0495: if (maxWorkThreads <= 0) {
0496: maxWorkThreads = DEF_MAX_WRK_THREADS;
0497: if (logger.isLoggable(BasicLevel.DEBUG)) {
0498: logger.log(BasicLevel.DEBUG,
0499: "Resetting max threads to "
0500: + DEF_WRK_THREADS);
0501: }
0502: }
0503: workMgr = new JWorkManager(minWorkThreads, maxWorkThreads,
0504: tm, threadWaitTimeout);
0505: }
0506:
0507: // Create BootstrapContext
0508: XATerminator xat = null;
0509: try {
0510: xat = ts.getCurrent().getXATerminator();
0511: } catch (Exception ex) {
0512: logger
0513: .log(BasicLevel.ERROR,
0514: "Unable to get an XATerminator from the TransactionService");
0515: throw new ServiceException(
0516: "Unable to get an XATerminator from the TransactionService",
0517: ex);
0518: }
0519: bootCtx = new ResourceBootstrapContext(workMgr, xat);
0520:
0521: if (logger.isLoggable(BasicLevel.DEBUG)) {
0522: logger.log(BasicLevel.DEBUG, "ResourceService initialized");
0523: }
0524: }
0525:
0526: /**
0527: * Start the Resource service.
0528: * @throws ServiceException if the startup failed.
0529: */
0530: public void doStart() throws ServiceException {
0531: // creates each resource
0532: String rarFileName = null;
0533: CompNamingContext ctx = null;
0534: for (int i = 0; i < resourceNames.size(); i++) {
0535: rarFileName = (String) resourceNames.elementAt(i);
0536: if (logger.isLoggable(BasicLevel.DEBUG)) {
0537: logger.log(BasicLevel.DEBUG, "rarFileName="
0538: + rarFileName);
0539: }
0540: try {
0541: ctx = new CompNamingContext(rarFileName);
0542: ctx.rebind("rarFileName", rarFileName);
0543: ctx.rebind("isInEar", new Boolean(false));
0544: ctx.rebind("classloader", appsClassLoader);
0545: createResourceAdapter(ctx);
0546: } catch (Exception e) {
0547: logger.log(BasicLevel.ERROR,
0548: "JOnAS: Cannot create resource: " + rarFileName
0549: + " exception: " + e);
0550: e.printStackTrace();
0551: }
0552: }
0553:
0554: // process any delayed rars
0555: if (!delayedRAs.isEmpty()) {
0556: try {
0557: processingDelayed = true;
0558: Object[] rList = null;
0559: rList = delayedRAs.toArray();
0560: for (int i = 0; i < rList.length; i++) {
0561: try {
0562: createResourceAdapter((CompNamingContext) rList[i]);
0563: } catch (Exception e) {
0564: e.printStackTrace();
0565: String rFile = (String) ((CompNamingContext) rList[i])
0566: .lookup("rarFileName");
0567: logger.log(BasicLevel.ERROR,
0568: "JOnAS: Cannot create resource: "
0569: + rFile + " exception: " + e);
0570: logger
0571: .log(BasicLevel.ERROR,
0572: "Please verify that the rarlink is correct/deployed");
0573: }
0574: }
0575: } catch (Exception e) {
0576: e.printStackTrace();
0577: logger.log(BasicLevel.ERROR,
0578: "ResourceService: Error with delayed RAR file deployment\n"
0579: + e);
0580: throw new ServiceException(
0581: "ResourceService: Error with delayed RAR file deployment",
0582: e);
0583: }
0584: }
0585:
0586: // Create and register the Resource Service MBean
0587: if (mbeanServer != null) {
0588: try {
0589: mbeanServer.registerMBean(this , JonasObjectName
0590: .resourceService());
0591: } catch (InstanceAlreadyExistsException iae) {
0592: logger.log(BasicLevel.ERROR,
0593: "Cannot start the Resource Service Already Exists:\n"
0594: + iae);
0595: throw new ServiceException(
0596: "Cannot start the Resource Service Already Exists",
0597: iae);
0598: } catch (Exception e) {
0599: logger.log(BasicLevel.ERROR,
0600: "ResourceService: Cannot start the Resource service:\n"
0601: + e);
0602: throw new ServiceException(
0603: "ResourceService: Cannot start the Resource service",
0604: e);
0605: }
0606:
0607: // Create and register the archive configuration MBeans
0608: try {
0609: ManagedBean oManaged = JonasMBeanTools.getRegistry()
0610: .findManagedBean("ArchiveConfigMBean");
0611: ModelMBean oMBean = oManaged
0612: .createMBean(new ArchiveConfigMBean());
0613: mbeanServer.registerMBean(oMBean, JonasObjectName
0614: .ArchiveConfig());
0615:
0616: oManaged = JonasMBeanTools.getRegistry()
0617: .findManagedBean("RarConfigMBean");
0618: oMBean = oManaged.createMBean(new RarConfigMBean());
0619: mbeanServer.registerMBean(oMBean, JonasObjectName
0620: .RarConfig());
0621: } catch (Exception e) {
0622: logger
0623: .log(BasicLevel.WARN,
0624: "Could not register Archive Configuration MBean");
0625: e.printStackTrace();
0626: }
0627: }
0628:
0629: }
0630:
0631: /**
0632: * Stop the Resource service.
0633: * @throws ServiceException if the stop failed.
0634: */
0635: public void doStop() throws ServiceException {
0636:
0637: ServiceException se = null;
0638: synchronized (Rar.fileName2RA) {
0639: Enumeration keys = Rar.fileName2RA.elements();
0640: while (keys.hasMoreElements()) {
0641: Rar ra = (Rar) keys.nextElement();
0642: try {
0643: ra.unRegister();
0644: Rar.fileName2RA.remove(ra);
0645: } catch (Exception ex) {
0646: logger.log(BasicLevel.ERROR,
0647: "ResourceService: Received the following:"
0648: + ex);
0649: ex.printStackTrace();
0650: if (se == null) {
0651: se = new ServiceException(ex.getMessage());
0652: }
0653: }
0654: }
0655: }
0656: // unregister resource MBeans
0657: if (mbeanServer != null) {
0658: try {
0659: // unregister Archive Config MBeans
0660: mbeanServer.unregisterMBean(JonasObjectName
0661: .ArchiveConfig());
0662: mbeanServer
0663: .unregisterMBean(JonasObjectName.RarConfig());
0664: } catch (Exception e) {
0665: logger.log(BasicLevel.ERROR,
0666: "ResourceService: Cannot stop the Archive Config MBean:\n"
0667: + e);
0668: }
0669:
0670: try {
0671: // unregister resource Service MBean
0672: mbeanServer.unregisterMBean(JonasObjectName
0673: .resourceService());
0674: } catch (MBeanRegistrationException mr) {
0675: logger.log(BasicLevel.ERROR,
0676: "Cannot cleanly stop the ResourceService: "
0677: + mr.getMessage());
0678: } catch (InstanceNotFoundException infe) {
0679: logger.log(BasicLevel.ERROR,
0680: "Cannot cleanly stop the ResourceService: "
0681: + infe.getMessage());
0682: } catch (Exception e) {
0683: logger.log(BasicLevel.ERROR,
0684: "ResourceService: Cannot stop the Resource service:\n"
0685: + e);
0686: throw new ServiceException(
0687: "ResourceService: Cannot stop the Resource service",
0688: e);
0689: }
0690: }
0691:
0692: if (se != null) {
0693: throw se;
0694: }
0695: if (logger.isLoggable(BasicLevel.DEBUG)) {
0696: logger.log(BasicLevel.DEBUG, "ResourceService stopped");
0697: }
0698: }
0699:
0700: // IMPLEMENTATION OF 'ResourceService' INTERFACE //
0701:
0702: /**
0703: * Create a new resource adapter. This Resource Adapter is configured via
0704: * xml files in the rar file
0705: * @param ctx Context to use for deploying an RAR
0706: * @return Sting resource objectName
0707: * @throws Exception error encountered
0708: */
0709: public String createResourceAdapter(Context ctx) throws Exception {
0710:
0711: // Parameters :
0712: // rarFileName, isInEar, classloader and possible AltDD and earUrl
0713: String rarFileName;
0714: try {
0715: rarFileName = (String) ctx.lookup("rarFileName");
0716: ctx.rebind("deployed", new Boolean(false));
0717: } catch (Exception ex) {
0718: String err = "Error while getting parameter from context param.";
0719: logger.log(BasicLevel.ERROR, err + ex.getMessage());
0720: throw new ResourceServiceException(err, ex);
0721: }
0722:
0723: if (logger.isLoggable(BasicLevel.DEBUG)) {
0724: logger.log(BasicLevel.DEBUG, rarFileName);
0725: }
0726: if (!rarFileName.endsWith(".rar")) {
0727: rarFileName += ".rar";
0728: ctx.rebind("rarFileName", rarFileName);
0729: }
0730:
0731: // Determine if the RAR file exists
0732: File f = new File(rarFileName);
0733: if (!f.exists()) {
0734: boolean found = false;
0735: String resFileName = null;
0736: // In case of the name is a rar file name, check also in
0737: // the JONAS_BASE/rars directory
0738: resFileName = RARSDIR + File.separator + rarFileName;
0739: f = new File(resFileName);
0740: found = f.exists();
0741: if (found) {
0742: rarFileName = resFileName;
0743: ctx.rebind("rarFileName", rarFileName);
0744: } else {
0745: logger.log(BasicLevel.ERROR, "createResourceAdapter: "
0746: + resFileName + " not found");
0747: Exception e = new NamingException(resFileName
0748: + " not found");
0749: throw e;
0750: }
0751: }
0752:
0753: URL rarUrl = f.toURL();
0754:
0755: Rar rar = new Rar(ctx, getDomainName(), getJonasServerName(),
0756: workMgr, bootCtx);
0757:
0758: try {
0759: Context ctxRar = rar.processRar();
0760: } catch (Exception ex) {
0761: // Exception error in processing unregister
0762: String err = "Error processing Rar: " + ex.getMessage();
0763: try {
0764: rar.unRegister();
0765: } catch (Exception exc) {
0766: err = err + " Unregister also failed with "
0767: + exc.getMessage();
0768: }
0769: if (ex.getMessage().indexOf("no jonas-ra.xml") > 0) {
0770: throw new ResourceServiceException("", ex);
0771: }
0772: logger.log(BasicLevel.ERROR, err);
0773: throw new ResourceServiceException(err, ex);
0774: }
0775:
0776: boolean isDeployed = false;
0777: try {
0778: isDeployed = ((Boolean) ctx.lookup("deployed"))
0779: .booleanValue();
0780: } catch (Exception ex) {
0781: String err = "Error while getting parameter(isDeployed) from context param.";
0782: logger.log(BasicLevel.ERROR, err + ex.getMessage());
0783: throw new ResourceServiceException(err, ex);
0784: }
0785:
0786: if (!isDeployed) {
0787: // If isDeployed in not set, then an rar-link was specified that is not deployed and if
0788: // we are already processing the delayed rar files, then throw an exception otherwise
0789: // update the delayedRAs vector and process it again later.
0790: if (processingDelayed) {
0791: logger.log(BasicLevel.ERROR,
0792: "ResourceService.createRA: Resource ("
0793: + rarFileName
0794: + ") contains an invalid rarlink.");
0795: throw new ResourceServiceException(
0796: "resource input file incorrect: invalid rarlink");
0797: }
0798: delayedRAs.add(ctx);
0799: return null;
0800: }
0801:
0802: Vector jNames = rar.getJndinames();
0803: if (jNames != null) {
0804: for (int i = 0; i < jNames.size(); i++) {
0805: Rar.jndiName2RA.put(jNames.get(i), rar);
0806: }
0807: }
0808:
0809: // Processed and deployed rar, so add it to our lists
0810: Rar.fileName2RA.put(rarUrl.getPath(), rar);
0811:
0812: String onRar = null;
0813: try {
0814: onRar = (String) ctx.lookup("onRar");
0815: } catch (Exception ex) {
0816: String err = "Error while getting parameter(onRar) from context param.";
0817: logger.log(BasicLevel.ERROR, err + ex.getMessage());
0818: throw new ResourceServiceException(err, ex);
0819: }
0820:
0821: return onRar.toString();
0822: }
0823:
0824: /**
0825: * Deploy the given rars of an ear file with the specified parent
0826: * classloader (ear classloader). (This method is only used for
0827: * for ear applications).
0828: * @param ctx the context containing the configuration
0829: * to deploy the rars.<BR>
0830: * This context contains the following parameters :<BR>
0831: * - urls the list of the urls of the rars to deploy.<BR>
0832: * - earRootURL the URL of the ear application file.<BR>
0833: * - earClassLoader the ear classLoader of the j2ee app.<BR>
0834: * - altDDs the optional URI of deployment descriptor.<BR>
0835: * @throws ResourceServiceException if an error occurs during
0836: * the deployment.
0837: */
0838: public void deployRars(Context ctx) throws ResourceServiceException {
0839:
0840: // Gets the parameters from the context :
0841: // - urls the list of the urls of the rars to deploy.
0842: // - earRootURL the URL of the ear application file.
0843: // - earClassLoader the ear classLoader of the j2ee app.
0844: // - altDDs the optional URI of deployment descriptor.
0845: URL[] urls = null;
0846: URL earUrl = null;
0847: ClassLoader earClassLoader = null;
0848: URL[] altDDs = null;
0849: try {
0850: urls = (URL[]) ctx.lookup("urls");
0851: earUrl = (URL) ctx.lookup("earUrl");
0852: earClassLoader = (ClassLoader) ctx.lookup("earClassLoader");
0853: altDDs = (URL[]) ctx.lookup("altDDs");
0854: } catch (NamingException e) {
0855: String err = "Error while getting parameter from context param ";
0856: logger.log(BasicLevel.ERROR, err + e.getMessage());
0857: throw new ResourceServiceException(err, e);
0858: }
0859:
0860: delayedRAs.clear(); // reset the delayed RAs
0861: // Deploy all the rars of the ear application.
0862: for (int i = 0; i < urls.length; i++) {
0863: // Get the name of a rar to deploy.
0864: String fileName = urls[i].getFile();
0865: if (logger.isLoggable(BasicLevel.DEBUG)) {
0866: logger.log(BasicLevel.DEBUG, "Deploy rar '" + fileName
0867: + "' for the ear service");
0868: }
0869:
0870: // The context to give for the creation of the container
0871: // associated to the ejb-jar.
0872: Context contctx = null;
0873: try {
0874: contctx = new CompNamingContext(fileName);
0875: contctx.rebind("rarFileName", fileName);
0876: contctx.rebind("isInEar", new Boolean(true));
0877: contctx.rebind("earUrl", earUrl);
0878: if (altDDs[i] != null) {
0879: contctx.rebind("altDD", altDDs[i]);
0880: }
0881: contctx.rebind("classloader", earClassLoader);
0882: createResourceAdapter(contctx);
0883: } catch (Exception e) {
0884: // A rar is corrupted so undeploy all the deployed rar
0885: // of the ear application.
0886: logger.log(BasicLevel.ERROR, "Error when deploying '"
0887: + fileName + "'");
0888: logger.log(BasicLevel.ERROR, e.getMessage());
0889: logger.log(BasicLevel.ERROR,
0890: "Undeploy rar of the ear application");
0891:
0892: for (int j = 0; j < i; j++) {
0893: String rarFileName = urls[j].getFile();
0894: try {
0895: // Try to undeploy a rar of the ear application.
0896: CompNamingContext compctx = new CompNamingContext(
0897: rarFileName);
0898: compctx.rebind("rarFileName", rarFileName);
0899: compctx.rebind("isInEar", new Boolean(true));
0900: contctx.rebind("earUrl", earUrl);
0901: unRegisterRar(compctx);
0902: } catch (Exception ex) {
0903: // Cannot undeploy a rar of the ear application
0904: // So there is an error message.
0905: logger.log(BasicLevel.ERROR,
0906: "Error when undeploying '"
0907: + rarFileName + "'");
0908: logger.log(BasicLevel.ERROR, ex.getMessage());
0909: logger
0910: .log(BasicLevel.ERROR,
0911: "Cannot undeploy rar of the ear application");
0912: }
0913:
0914: }
0915: throw new ResourceServiceException(
0916: "Error during the deployment", e);
0917: }
0918: }
0919: // process any delayed rars
0920: if (!delayedRAs.isEmpty()) {
0921: try {
0922: processingDelayed = true;
0923: Object[] rList = null;
0924: rList = delayedRAs.toArray();
0925: for (int i = 0; i < rList.length; i++) {
0926: try {
0927: createResourceAdapter((CompNamingContext) rList[i]);
0928: } catch (Exception e) {
0929: logger.log(BasicLevel.ERROR,
0930: "JOnAS: Cannot create resource: "
0931: + (String) rList[i]
0932: + " exception: " + e);
0933: logger
0934: .log(BasicLevel.ERROR,
0935: "Please verify that the rarlink is correct");
0936: e.printStackTrace();
0937: }
0938: }
0939: } catch (Exception e) {
0940: logger.log(BasicLevel.ERROR,
0941: "ResourceService: Error with delayed RAR file deployment\n"
0942: + e);
0943: throw new ServiceException(
0944: "ResourceService: Error with delayed RAR file deployment",
0945: e);
0946: }
0947: }
0948: }
0949:
0950: /**
0951: * Undeploy the given rars of an ear file. (This method is only
0952: * used for the ear applications).
0953: * @param urls the list of the urls of the rars to undeploy.
0954: * @param earUrl the URL of the associated EAR file
0955: */
0956: public void unDeployRars(URL[] urls, URL earUrl) {
0957: for (int i = 0; i < urls.length; i++) {
0958: String fileName = urls[i].getFile();
0959: if (Rar.fileName2RA.containsKey(fileName)) {
0960: try {
0961: // Try to undeploy a rar of the ear application.
0962: CompNamingContext compctx = new CompNamingContext(
0963: fileName);
0964: compctx.rebind("rarFileName", fileName);
0965: compctx.rebind("isInEar", new Boolean(true));
0966: compctx.rebind("earUrl", earUrl);
0967: unRegisterRar(compctx);
0968: } catch (Exception ex) {
0969: logger.log(BasicLevel.ERROR,
0970: "Cannot undeploy resource: " + fileName
0971: + " " + ex);
0972: }
0973: } else {
0974: logger.log(BasicLevel.ERROR,
0975: "Cannot remove the non-existant rar '"
0976: + fileName + "'");
0977: }
0978: }
0979: }
0980:
0981: /**
0982: * Unregister the resource adapter.
0983: * @param ctx Context to use for unregistering an RAR
0984: * @throws Exception error encountered
0985: */
0986: public void unRegisterRar(Context ctx) throws Exception {
0987: String rarFileName;
0988: try {
0989: rarFileName = (String) ctx.lookup("rarFileName");
0990: } catch (NamingException e) {
0991: String err = "Error while getting parameter from context param.";
0992: logger.log(BasicLevel.ERROR, err + e.getMessage());
0993: throw new ResourceServiceException(err, e);
0994: } catch (Exception ex) {
0995: String err = "Error while getting parameter from context param.";
0996: logger.log(BasicLevel.ERROR, err + ex.getMessage());
0997: throw new ResourceServiceException(err, ex);
0998: }
0999:
1000: if (manageLogger.isLoggable(BasicLevel.DEBUG)) {
1001: manageLogger.log(BasicLevel.DEBUG,
1002: "TEST Unregister MBeans for RAR in file: "
1003: + rarFileName);
1004: }
1005:
1006: String rarPath = (new File(rarFileName)).toURL().getPath();
1007: Rar rar = (Rar) Rar.fileName2RA.get(rarPath);
1008: Vector jNames = rar.getJndinames();
1009: rar.unRegister();
1010:
1011: // Remove rars from hashtables
1012: for (int i = 0; i < jNames.size(); i++) {
1013: Rar.jndiName2RA.remove(jNames.get(i));
1014: }
1015: Rar.fileName2RA.remove(rarPath);
1016: resourceNames.remove(normalizePath(rarFileName));
1017:
1018: logger.log(BasicLevel.INFO, "ResourceService: unRegisterRar: "
1019: + rarFileName);
1020: }
1021:
1022: /**
1023: * Return the JDBC ResourceAdapter MBean ObjectNames deployed in the current server.
1024: * The JDBC ResourceAdapters have a 'properties' attribue containing the following properties
1025: * set (not null and not empty): 'dsClass', 'URL'.
1026: * @return The found MBean ObjectNames or null if no JDBC ResourceAdapter MBean registered for
1027: * the current server in the current domain.
1028: * @throws Exception The ResourceAdapter MBeans checking failed.
1029: */
1030: public ObjectName[] getJDBCResourceAdapaters() throws Exception {
1031: ObjectName[] result = null;
1032: ArrayList al = null;
1033: ObjectName raOns = J2eeObjectName.getResourceAdapters(
1034: getDomainName(), getJonasServerName());
1035: Set ons = mbeanServer.queryNames(raOns, null);
1036: if (ons.isEmpty()) {
1037: return null;
1038: }
1039: // Got ResourceAdapters for this server
1040: al = new ArrayList();
1041: Iterator it = ons.iterator();
1042: for (; it.hasNext();) {
1043: ObjectName aRaOn = (ObjectName) it.next();
1044: Properties props = (Properties) mbeanServer.getAttribute(
1045: aRaOn, "properties");
1046: String dsClassValue = props.getProperty("dsClass");
1047: String urlValue = props.getProperty("URL");
1048: if (dsClassValue != null && dsClassValue.length() != 0
1049: && urlValue != null && urlValue.length() != 0) {
1050: // Thsis is a well configured JDBC ResourceAdapter
1051: al.add(aRaOn);
1052: }
1053: }
1054: int nbJDBCResourceAdapaters = al.size();
1055: if (nbJDBCResourceAdapaters == 0) {
1056: return null;
1057: } else {
1058: result = new ObjectName[nbJDBCResourceAdapaters];
1059: for (int i = 0; i < nbJDBCResourceAdapaters; i++) {
1060: result[i] = (ObjectName) al.get(i);
1061: }
1062: }
1063: return result;
1064: }
1065:
1066: /**
1067: * Return the JDBC ResourceAdapter MBean OBJECT_NAME deployed in the current server
1068: * haveing the 'jndiName' attribue value equal to the given jndiName
1069: * @param jndiName A DataSource jndi name we are looking for.
1070: * @return The found MBean OBJECT_NAME or null if none of the JDBC ResourceAdapter MBean
1071: * have the given jndi name.
1072: * @throws Exception The ResourceAdapter MBeans checking failed.
1073: */
1074: public String getJDBCResourceAdapater(String jndiName)
1075: throws Exception {
1076: String result = null;
1077: ObjectName[] raOns = getJDBCResourceAdapaters();
1078: ObjectName raOn = null;
1079: String raJndiName = null;
1080: if (raOns != null) {
1081: for (int i = 0; i < raOns.length; i++) {
1082: raOn = raOns[i];
1083: raJndiName = (String) mbeanServer.getAttribute(raOn,
1084: "jndiName");
1085: if (jndiName.equals(raJndiName)) {
1086: // found the JDBC RA MBean having the givent jndi name
1087: return raOn.toString();
1088: }
1089: }
1090: }
1091: return result;
1092: }
1093:
1094: //--------------------------------------------------------------
1095: // MBean Methods
1096: //--------------------------------------------------------------
1097:
1098: /**
1099: * @return Integer Total Number of Resources available in JOnAS
1100: */
1101: public Integer getCurrentNumberOfResource() {
1102: return getCurrentNumberOfRars();
1103: }
1104:
1105: /**
1106: * @return Integer Total Number of Rars available in JOnAS
1107: */
1108: public Integer getCurrentNumberOfRars() {
1109: return new Integer(Rar.fileName2RA.size());
1110: }
1111:
1112: /**
1113: * @return the list of RAR files deployed
1114: */
1115: public List getDeployedRars() {
1116: ArrayList al = new ArrayList();
1117: String rarFileName = null;
1118: Enumeration keys = Rar.fileName2RA.keys();
1119: while (keys.hasMoreElements()) {
1120: rarFileName = keys.nextElement().toString();
1121: try {
1122: al.add((new File(rarFileName)).toURL().getPath());
1123: } catch (Exception e) {
1124: if (logger.isLoggable(BasicLevel.DEBUG)) {
1125: logger.log(BasicLevel.DEBUG,
1126: "Unable to add rarfile " + rarFileName
1127: + " to arraylist");
1128: }
1129: }
1130: }
1131: return al;
1132: }
1133:
1134: /**
1135: * Return the list of installed RAR containers.
1136: * The RAR files or the directories with expanded RAR container are searched
1137: * in JONAS_BASE/rars and all rar directories 'autoload'.
1138: * @return The list of RAR files or the directories with expanded RAR container found
1139: * @throws Exception if the list can't be retrieved
1140: */
1141: public List getInstalledRars() throws Exception {
1142: // get JAR files found in JONAS_BASE/rars
1143: ArrayList al = JModule.getInstalledContainersInDir(RARSDIR,
1144: JModule.RAR_EXTENSION, JModule.RAR_CHILD_DIR,
1145: JModule.RAR_CONFIRM_FILE);
1146: // get RAR files found in all autoload directories
1147: for (int i = 0; i < autoNames.size(); i++) {
1148: al.addAll(JModule.getInstalledContainersInDir(autoNames
1149: .get(i).toString(), JModule.RAR_EXTENSION,
1150: JModule.RAR_CHILD_DIR, JModule.RAR_CONFIRM_FILE));
1151: }
1152: return al;
1153: }
1154:
1155: /**
1156: * This method is added temporarily. It will disapear when Rars will have their associated MBeans
1157: * (when Rars will become manageable)
1158: * @return the names of the rars currently deployed in the JOnAS server
1159: */
1160: public Set getRarNames() {
1161: HashSet names = new HashSet();
1162: String rarFileName = null;
1163: for (int i = 0; i < resourceNames.size(); i++) {
1164: rarFileName = (String) resourceNames.elementAt(i);
1165: names.add(rarFileName);
1166: }
1167: return names;
1168: }
1169:
1170: /**
1171: * Deploy an RAR by delegating the operation to the createResourceAdapter method.
1172: * This is used for JMX management.
1173: * @param fileName the fileName of the rar which must be be deployed.
1174: * @return The ObjectName of the MBean associated to the deployed J2EE Application
1175: * @throws RemoteException if rmi call failed.
1176: * @throws ResourceServiceException if the deployment of the RAR failed.
1177: */
1178: public String deployRarMBean(String fileName)
1179: throws RemoteException, ResourceServiceException {
1180: Context ctx = null;
1181: String onRar = null;
1182: try {
1183: ctx = new CompNamingContext(fileName);
1184: ctx.rebind("rarFileName", fileName);
1185: ctx.rebind("isInEar", new Boolean(false));
1186: ctx.rebind("classloader", appsClassLoader);
1187: onRar = createResourceAdapter(ctx);
1188: } catch (Exception e) {
1189: String err = "Error when deploying the rar file: "
1190: + fileName;
1191: logger.log(BasicLevel.ERROR, err + e.getMessage());
1192: e.printStackTrace();
1193: throw new ResourceServiceException(err, e);
1194: }
1195:
1196: return onRar;
1197: }
1198:
1199: /**
1200: * Deploy the resource adapter
1201: * @param fileName the name of the rar file.
1202: * @throws Exception if unable to deploy the rar
1203: * @return String ObjectName of the deployed rar
1204: */
1205: public String deployRar(String fileName) throws Exception {
1206: return deployRarMBean(fileName);
1207: }
1208:
1209: /**
1210: * Test if the specified filename is already deployed or not.
1211: * @param fileName the name of the rar file.
1212: * @return true if the rar is deployed, else false.
1213: */
1214: public Boolean isRarDeployed(String fileName) {
1215: return new Boolean(isRarLoaded(fileName));
1216: }
1217:
1218: /**
1219: * Test if the specified unpack name is already deployed or not. This
1220: * method is defined in the ResourceService interface.
1221: * @param unpackName the name of the rar file.
1222: * @return true if the rar is deployed, else false.
1223: */
1224: public boolean isRarDeployedByUnpackName(String unpackName) {
1225: if (logger.isLoggable(BasicLevel.DEBUG)) {
1226: logger.log(BasicLevel.DEBUG, "entering for unpackName= "
1227: + unpackName);
1228: }
1229: /* // for each rar loaded
1230: Enumeration lc = ears.elements();
1231: while (lc.hasMoreElements()) {
1232: Ear ear = (Ear) lc.nextElement();
1233:
1234: // get unpack name of the ear
1235: String deployedUnpackName = new File(ear.getUnpackName()).getName() ;
1236: logger.log(BasicLevel.DEBUG, "deployedUnpackName=" + deployedUnpackName);
1237:
1238: if (deployedUnpackName.equals(unpackName)) {
1239: return true;
1240: }
1241: // else, go to the next loop
1242: }
1243: // not found
1244: */
1245: return false;
1246: }
1247:
1248: /**
1249: * Undeploy an RAR by delegating the operation to the unRegisterRar() method.
1250: * This is used for JMX management.
1251: * @param fileName the fileName of the rar which must be be undeployed.
1252: * @throws RemoteException if rmi call failed.
1253: * @throws ResourceServiceException if the undeployment of the RAR failed.
1254: */
1255: public void unDeployRarMBean(String fileName)
1256: throws RemoteException, ResourceServiceException {
1257: /* We have only the name of the file, not its associated path, so we look in
1258: the current directory and in the rar applications directory
1259: */
1260:
1261: boolean found = true;
1262: if (logger.isLoggable(BasicLevel.DEBUG)) {
1263: logger.log(BasicLevel.DEBUG, "Trying to undeploy: "
1264: + fileName + " with the following deployed:"
1265: + Rar.fileName2RA);
1266: }
1267:
1268: try {
1269: // Determine if the RAR is in list
1270: File f = new File(fileName);
1271: if (!Rar.fileName2RA.containsKey(f.toURL().getPath())) {
1272: found = false;
1273: // Check also in the JONAS_BASE/rars directory
1274: String resFileName = RARSDIR + File.separator
1275: + fileName;
1276: f = new File(resFileName);
1277: if (Rar.fileName2RA.containsKey(f.toURL().getPath())) {
1278: fileName = resFileName;
1279: found = true;
1280: }
1281: }
1282:
1283: if (!found) {
1284: String err = "Cannot undeploy the rar '" + fileName
1285: + "', it is not deployed.";
1286: logger.log(BasicLevel.ERROR, err);
1287: throw new ResourceServiceException(err);
1288: }
1289: } catch (Exception ex) {
1290: String err = "Error trying to undeployRarMBean " + fileName;
1291: logger.log(BasicLevel.ERROR, err + ex.getMessage());
1292: throw new ResourceServiceException(err, ex);
1293: }
1294:
1295: //We've got the file, now we bind the params
1296: CompNamingContext compctx = null;
1297: try {
1298: compctx = new CompNamingContext(fileName);
1299: compctx.rebind("rarFileName", fileName);
1300: compctx.rebind("isInEar", new Boolean(false));
1301: //Call the function
1302: unRegisterRar(compctx);
1303: } catch (NamingException e) {
1304: String err = "Error when binding parameters";
1305: logger.log(BasicLevel.ERROR, err + e.getMessage());
1306: throw new ResourceServiceException(err, e);
1307: } catch (Exception ex) {
1308: String err = "Error when unRegistering rar " + fileName;
1309: logger.log(BasicLevel.ERROR, err + ex.getMessage());
1310: ex.printStackTrace();
1311: throw new ResourceServiceException(err, ex);
1312: }
1313:
1314: }
1315:
1316: /**
1317: * Undeploy the resource adapter
1318: * @param fileName the name of the rar file.
1319: * @throws Exception if not able to undeploy the rar
1320: */
1321: public void unDeployRar(String fileName) throws Exception {
1322: unDeployRarMBean(fileName);
1323: }
1324:
1325: /**
1326: * Test if the specified filename is already deployed or not
1327: * @param fileName the name of the rar file.
1328: * @return true if the rar is deployed, else false.
1329: */
1330: public boolean isRarLoaded(String fileName) {
1331:
1332: String updateName = null;
1333: boolean isLoaded = false;
1334: try {
1335: if (Rar.fileName2RA.containsKey(fileName)) {
1336: isLoaded = true;
1337: }
1338: // If not found check the exact filename
1339: if (!isLoaded) {
1340: // construct name for rars in JONAS_BASE/rars directory
1341: updateName = RARSDIR + File.separator + fileName;
1342:
1343: //Check if the rar is already deployed or not
1344: if (Rar.fileName2RA.containsKey(updateName)) {
1345: isLoaded = true;
1346: }
1347: }
1348: } catch (Exception e) {
1349: String err = "Cannot determine if the rar is deployed or not";
1350: logger.log(BasicLevel.ERROR, err);
1351: return false;
1352: }
1353:
1354: return isLoaded;
1355: }
1356:
1357: /**
1358: * Return the list of installed RAR container ready to deploy.
1359: *
1360: * @return The list of deployable RAR container
1361: * @throws Exception if error retrieving the list
1362: */
1363: public List getDeployableRars() throws Exception {
1364: List al = getInstalledRars();
1365: al.removeAll(getDeployedRars());
1366: return al;
1367: }
1368:
1369: /**
1370: * Return the list of "autoload" directories for RAR containers.
1371: * @return The list of all "autoload" directories
1372: */
1373: public List getAutoloadDirectories() {
1374: ArrayList al = new ArrayList();
1375: for (int i = 0; i < autoNames.size(); i++) {
1376: try {
1377: al.add((new File(autoNames.get(i).toString())).toURL()
1378: .getPath());
1379: } catch (Exception e) {
1380: if (logger.isLoggable(BasicLevel.DEBUG)) {
1381: logger.log(BasicLevel.DEBUG,
1382: "Can't get autoload directories : "
1383: + e.getMessage());
1384: }
1385: }
1386: }
1387: return al;
1388: }
1389:
1390: /**
1391: * Return the Rars directory.
1392: * @return The Rars directory
1393: */
1394: public String getRarsDirectory() {
1395: String sRet = null;
1396: try {
1397: sRet = (new File(RARSDIR)).toURL().getPath();
1398: } catch (Exception e) {
1399: throw new RuntimeException("Cannot get the RARS directory",
1400: e);
1401: }
1402: return sRet;
1403: }
1404:
1405: //--------------------------------------------------------------
1406: // Private Methods
1407: //--------------------------------------------------------------
1408:
1409: /**
1410: * Add recursively the rars of the specified directory.
1411: * If the dir has a relative path, this path is relative from where
1412: * the Application Server is launched. If the dir is not found it will
1413: * be searched in $JONAS_BASE/rars/ directory.
1414: * @param dirPath the path to the directory containing the rars to
1415: * load.
1416: */
1417: private void addRars(String dirPath) {
1418: boolean found = false;
1419:
1420: // Look the directory relative to the $JONAS_BASE/rars directory
1421: File dir = new File(RARSDIR + File.separator + dirPath);
1422: found = dir.isDirectory();
1423:
1424: if (found) {
1425: autoNames.add(dir);
1426: addRarsFrom(dir);
1427: } else {
1428: String err = "Warning: Cannot load dir: '" + dirPath + "' ";
1429: err += "is not a directory or directory doesn't exist";
1430: logger.log(BasicLevel.WARN, err);
1431: }
1432: }
1433:
1434: /**
1435: * Add the rars of the specified directory.
1436: * @param dir the directory from which the rars are loaded.
1437: * @throws ResourceServiceException if the argument is not a directory
1438: */
1439: private void addRarsFrom(File dir) throws ResourceServiceException {
1440: try {
1441: if (dir.isDirectory()) {
1442: File[] files = dir.listFiles();
1443: for (int i = 0; i < files.length; i++) {
1444: if (files[i].isFile()) {
1445: if (files[i].getPath().toLowerCase().endsWith(
1446: ".rar")) {
1447: resourceNames.add(files[i]
1448: .getCanonicalPath());
1449: }
1450: } else {
1451: autoNames.add(files[i]);
1452: addRarsFrom(files[i]);
1453: }
1454: }
1455: } else {
1456: String err = "Cannot load dir: '" + dir.getPath();
1457: err += "' is not a directory";
1458: logger.log(BasicLevel.ERROR, err);
1459: throw new ResourceServiceException(err);
1460: }
1461: } catch (IOException e) {
1462: String err = "Invalid file name '" + dir.getPath();
1463: logger.log(BasicLevel.ERROR, err);
1464: throw new ResourceServiceException(err, e);
1465: }
1466: }
1467:
1468: /**
1469: * Normalize the path for the platform
1470: * @param path the path to normalize
1471: * @return String normalized path
1472: */
1473: private String normalizePath(String path) {
1474: String ret = null;
1475: if (File.separatorChar == '/') {
1476: ret = path.replace('\\', File.separatorChar);
1477: } else {
1478: ret = path.replace('/', File.separatorChar);
1479: }
1480: return ret;
1481: }
1482: }
|