Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/mobicents/slee/container/management/DeployableUnitDeployer.java


1   /***************************************************
2    *                                                 *
3    *  Mobicents: The Open Source VoIP Platform       *
4    *                                                 *
5    *  Distributable under LGPL license.              *
6    *  See terms of license at gnu.org.               *
7    *                                                 *
8    ***************************************************/
9   
10  package org.mobicents.slee.container.management;
11  
12  import java.io.File;
13  import java.io.IOException;
14  import java.net.MalformedURLException;
15  import java.net.URL;
16  import java.util.ArrayList;
17  import java.util.Date;
18  import java.util.Enumeration;
19  import java.util.HashSet;
20  import java.util.Iterator;
21  import java.util.List;
22  import java.util.jar.JarEntry;
23  import java.util.jar.JarFile;
24  
25  import javassist.ClassPath;
26  import javassist.ClassPool;
27  
28  import javax.slee.SLEEException;
29  import javax.slee.management.AlreadyDeployedException;
30  import javax.slee.management.DeploymentException;
31  
32  import org.jboss.logging.Logger;
33  import org.jboss.mx.loading.UnifiedClassLoader;
34  import org.jboss.mx.loading.UnifiedLoaderRepository3;
35  import org.jboss.system.server.ServerConfig;
36  import org.jboss.system.server.ServerConfigLocator;
37  import org.mobicents.slee.container.SleeContainer;
38  import org.mobicents.slee.container.deployment.ConcreteClassGeneratorUtils;
39  import org.mobicents.slee.container.deployment.SbbDeployer;
40  import org.mobicents.slee.container.management.xml.XMLConstants;
41  import org.mobicents.slee.container.management.xml.XMLException;
42  import org.mobicents.slee.container.management.xml.XMLUtils;
43  import org.mobicents.slee.container.profile.ProfileDeployer;
44  import org.mobicents.slee.runtime.transaction.SleeTransactionManager;
45  import org.w3c.dom.Document;
46  import org.w3c.dom.Element;
47  
48  /**
49   * An instance of this class is created for every deployable unit that is
50   * installed in the slee. Use of this class goes through the static
51   * <code>deploy</code>. It then creates a UnitDeployer instance that
52   * corresponds the jar file passed to <code>deploy</code>.
53   * 
54   * @author Emil Ivov (original)
55   * @author M. Ranganathan (hacks)
56   * @author Ivelin Ivanov
57   */
58  public class DeployableUnitDeployer {
59      private JarFile unitJarFile = null;
60  
61      private File tempDUJarsDeploymentDirectory = null;
62  
63      private File classpathDirectory = null;
64  
65      private ComponentContainer componentContainer = null;
66  
67      private DeployableUnitIDImpl deployableUnitID;
68  
69      private static int deployableUnitCounter;
70  
71      private File tempClassDeploymentDir;
72  
73      private URL sourceUrl;
74  
75      private static Logger logger;
76      
77      private ClassPath classPath = null;
78  
79      /**
80       * The unique class loader associated with the given DU This should not be
81       * static else you will run into trouble when deploying multiple units.
82       */
83      private UnifiedClassLoader classLoader;
84  
85      /**
86       * shared Javassist pool for all DUs
87       */
88      private static ClassPool classPool = ConcreteClassGeneratorUtils.createClassPool();
89  
90      private File tempDeploymentFile;
91  
92      static {
93          logger = Logger.getLogger(DeployableUnitDeployer.class);
94      }
95  
96      DeployableUnitDeployer() {
97  
98          logger.debug("Creating DeployableUnitDeployer()" + this);
99          
100 
101     }
102 
103     /**
104      * Set the descriptor.
105      */
106 
107     private void setDescriptor(DeployableUnitDescriptorImpl descriptor) {
108         this.deployableUnitID = new DeployableUnitIDImpl(
109                 deployableUnitCounter++);
110         this.deployableUnitID.setDescriptor(descriptor);
111         descriptor.setDeployableUnit(deployableUnitID);
112         descriptor.setTmpDUJarsDirectory(this.tempDUJarsDeploymentDirectory);
113         descriptor.setTmpDeploymentDirectory(this.tempDeploymentFile);
114 
115     }
116 
117     /**
118      * Analyses the specified jar file, extracts and deploys the components that
119      * it contains.
120      * 
121      * @param deployableUnitJar
122      *            The Deployable Unit jar file that we want to deploy.
123      * @param tempDUJarsDeploymentDirectory
124      *            The location where the SLEE stores deployed files.
125      * @param container
126      *            the container where we should install component contents
127      * @param classpathDirectory
128      *            the directory where we should unzip component jars.
129      * @throws DeploymentException
130      *             if deployment fails.
131      */
132     public static synchronized DeployableUnitIDImpl deploy(URL sourceUrl,
133             File deployableUnitJarFile, File deploymentDirectory,
134             ComponentContainer container) throws DeploymentException {
135         logger.debug("jarFile = " + deployableUnitJarFile);
136 
137         JarFile deployableUnitJar;
138         try {
139             deployableUnitJar = new JarFile(deployableUnitJarFile);
140         } catch (IOException e) {
141             throw new DeploymentException(
142                     "Failed to open DU file as JAR file: "
143                             + deployableUnitJarFile, e);
144         }
145 
146         DeployableUnitDeployer deployer = new DeployableUnitDeployer();
147         if (sourceUrl == null || deployableUnitJar == null
148                 || deploymentDirectory == null || container == null)
149             throw new NullPointerException("null arg!");
150 
151         //init the deployer.
152         deployer.setUnitJarFile(deployableUnitJar);
153         deployer.setTempDUJarsDeploymentDirectory(deploymentDirectory);
154         deployer.setComponentContainer(container);
155         deployer.setSourceURL(sourceUrl);
156         deployer.init();
157         //      Get te DU deployment Descriptor;
158         deployer.setDescriptor(new DeployableUnitDescriptorImpl(sourceUrl
159                 .toString(), new Date()));
160 
161         // set UnitID properties to uniquely identify this DU in SLEE
162         deployer.deployableUnitID.setSourceURL(sourceUrl);
163         deployer.deployableUnitID.setSourceURI(deployableUnitJarFile.toURI());
164         deployer.deployableUnitID.setDUDeployer(deployer);
165 
166         deployer.deployUnitContent();
167 
168         container.addDeployableUnit(deployer.deployableUnitID.getDescriptor());
169         return deployer.deployableUnitID;
170 
171     }
172 
173     /**
174      * set the source Url where the DU was read originally
175      * 
176      * @param sourceUrl
177      */
178     private void setSourceURL(URL sourceUrl) {
179         this.sourceUrl = sourceUrl;
180     }
181 
182     /**
183      * @return the source Url where the DU was read originally
184      */
185     public URL getSourceURL() {
186         return sourceUrl;
187     }
188 
189     /**
190      * Sets the jar file that this unit deployer has been created for.
191      * 
192      * @param duJar
193      *            the jar that contains the deployable unit that this instance
194      *            is to take care of.
195      */
196     void setUnitJarFile(JarFile duJar) {
197         this.unitJarFile = duJar;
198     }
199 
200     /**
201      * Sets the SLEE directory where deployable units are stored. The directory
202      * where DU jar files are stored.
203      * 
204      * @param tempDUJarsDeploymentDirectory
205      *            the directory where the Slee stores DUs
206      */
207     private void setTempDUJarsDeploymentDirectory(File deploymentDirectory) {
208         this.tempDUJarsDeploymentDirectory = deploymentDirectory;
209     }
210 
211     /**
212      * The Container where components should be installed.
213      * 
214      * @param componentContainer
215      *            ComponentContainer
216      */
217     public void setComponentContainer(ComponentContainer componentContainer) {
218         this.componentContainer = componentContainer;
219     }
220 
221     /**
222      * Returns the jar file that this unit deployer has been created for.
223      * 
224      * @return the JarFile that contains the deployable unit that this instance
225      *         is to take care of.
226      */
227     JarFile getUnitJarFile() {
228         return unitJarFile;
229     }
230 
231     /**
232      * Returns the SLEE directory where deployable units are stored.
233      * 
234      * @return the directory where DU jar files are stored.
235      */
236     public File getTempDUJarsDeploymentDirectory() {
237         return tempDUJarsDeploymentDirectory;
238     }
239 
240     /**
241      * Returns a reference to the Container where services should be installed.
242      * 
243      * @return the container where we shall install services
244      */
245     public ComponentContainer getComponentContainer() {
246         return componentContainer;
247     }
248 
249     /**
250      * Returns the directory where component contents should be stored. The
251      * directory should be part of the classpath.
252      * 
253      * @return A File instance,
254      */
255     public File getClasspathDirectory() {
256         return tempClassDeploymentDir/*
257                                       * FIXME: this method should be merged with
258                                       * getTempDeploymentDir() - used to return
259                                       * classpathDirectory ->
260                                       * server/all/deploy/mobicents.sar
261                                       */;
262     }
263 
264     /**
265      * Extract and deploy all components contained by the unit jar file.
266      * 
267      * @return the deployable unit id for the deployed component
268      * @throws Exception
269      *             if deployment fails for a reason.
270      */
271     private void deployUnitContent() throws DeploymentException {
272         boolean b = false;
273         SleeTransactionManager transactionManager = SleeContainer.getTransactionManager(); 
274         try {
275             b = transactionManager.requireTransaction();
276 
277             HashSet extractedJars = new HashSet();
278 
279             SbbDeployer.reInit();
280 
281           // explore the library directory
282           // TODO: The proper way to explore the library directories is to follow the JSLEE 1.1
283           // spec for adding the proper library descriptor
284         
285           Enumeration entries = unitJarFile.entries();
286       
287           try {
288        
289             for (JarEntry entry = (JarEntry) entries.nextElement(); 
290                entries.hasMoreElements(); ) 
291             {
292               entry = (JarEntry) entries.nextElement();  
293               if (entry.getName().indexOf("library")!=-1 &&
294                   entry.getName().indexOf("jar")!=-1 && 
295               !entry.isDirectory()) 
296               {
297                 File f = DeploymentManager.extractFile(entry.getName(),unitJarFile,getClasspathDirectory());
298                 DeploymentManager.extractJar(new JarFile(f), getClasspathDirectory());
299 
300               }
301             }
302           } catch (IOException ex) {
303              throw new DeploymentException(ex.getMessage(), ex);
304            }
305             // Note -- once you extact a file from a jar archive, it is
306             // not in the jar archive any longer!! This is totally unexpected.
307             JarEntry duXmlEntry = unitJarFile
308                     .getJarEntry("META-INF/deployable-unit.xml");
309             if (duXmlEntry == null) {
310                 throw new DeploymentException(
311                         "No DeployableUniDeploymentDescriptor descriptor "
312                                 + "(META-INF/deployable-unit.xml) was found in deployable unit"
313                                 + unitJarFile.getName());
314             }
315 
316             //Parse the descriptor
317             Document doc = null;
318 
319             try {
320                 //FIXME -- turn off validation for now.
321                 doc = XMLUtils.parseDocument(unitJarFile
322                         .getInputStream(duXmlEntry), false);
323 
324             } catch (IOException ex) {
325                 throw new DeploymentException("Failed to extract the DU depl "
326                         + "descriptor from " + unitJarFile.getName());
327             }
328 
329             Element duNode = doc.getDocumentElement();
330             DeployableUnitDescriptorImpl deployableUnitDescriptor = this.deployableUnitID
331                     .getDescriptor();
332 
333             try {
334                 String description = XMLUtils.getElementTextValue(duNode,
335                         XMLConstants.DESCRIPTION_ND);
336                 if (description != null)
337                     deployableUnitDescriptor.setDescription(description);
338             } catch (XMLException ex) {
339                 throw new DeploymentException(ex.getMessage());
340             }
341 
342             //Get a list of the jars and services in the deployable unit.
343             List jarNodes = XMLUtils.getAllChildElements(duNode,
344                     XMLConstants.JAR_ND);
345             List serviceNodes = XMLUtils.getAllChildElements(duNode,
346                     XMLConstants.SERVICE_XML_ND);
347             if (jarNodes.size() == 0 && serviceNodes.size() == 0) {
348                 throw new DeploymentException("The " + unitJarFile.getName()
349                         + " deployable unit contains no jars or services");
350             }
351 
352             // Parse the event-jar entries first and the other ones later.
353             ArrayList jarNames = new ArrayList();//used for assserting unique
354             // names
355             Iterator iter = jarNodes.iterator();
356             HashSet complexComponentsJarFiles = new HashSet();
357             HashSet simpleComponentsJarFiles = new HashSet();
358             while (iter.hasNext()) {
359                 try {
360                     String jarName = XMLUtils
361                             .getElementTextValue((Element) iter.next());
362                     if (jarName.length() == 0
363                             || !jarName.toLowerCase().endsWith("jar")) {
364                         throw new DeploymentException(jarName
365                                 + " is not a valid jar file name.");
366                     }
367                     if (jarNames.contains(jarName)) {
368                         throw new DeploymentException("Encountered " + jarName
369                                 + " more than once.");
370                     }
371 
372                     //extract the jar entry
373 
374                     logger.info("jarName " + jarName + " unitJarFile "
375                             + unitJarFile.getName()
376                             + "tempDUJarsDeploymentDirectory "
377                             + getTempDUJarsDeploymentDirectory());
378 
379                     File extractedJarFile = DeploymentManager.extractFile(
380                             jarName, unitJarFile,
381                             getTempDUJarsDeploymentDirectory());
382                     JarFile extractedJar = new JarFile(extractedJarFile);
383                     extractedJars.add(extractedJarFile);
384                     deployableUnitDescriptor.addJar(jarName);
385                     jarNames.add(jarName);
386                     //take care of the deployment of the componentitself
387                     AbstractComponentDeployer deployer = createComponentDeployer(extractedJar);
388                     deployer.initDeployer(extractedJar,
389                             getComponentContainer(),
390                             getTempClassDeploymentDir(), this
391                     /* TODO was: getClasspathDirectory() */);
392 
393                     if (deployer instanceof EventTypeComponentDeployer ||
394                         deployer instanceof ProfileSpecComponentDeployer ) {
395                         simpleComponentsJarFiles.add(deployer);
396                     } else {
397                         complexComponentsJarFiles.add(deployer);
398                     }
399 
400                 } catch (AlreadyDeployedException ex) {
401                     try {
402                         this.getComponentContainer().doRemove(
403                                 deployableUnitDescriptor);
404                     } catch (Exception e) {
405                         logger.error("Problem undeploying partial deployment",
406                                 e);
407                     }
408                     logger.error(ex.getMessage(), ex);
409                     throw ex;
410                 } catch (Exception ex) {
411                     try {
412                         this.getComponentContainer().doRemove(
413                                 deployableUnitDescriptor);
414                     } catch (Exception e) {
415                         logger.error("Problem undeploying partial deployment",
416                                 e);
417                     }
418                     String s = ex.getMessage();
419                     logger.error(s, ex);
420                     throw new DeploymentException(s,ex);
421                 }
422             }
423             //Create DeployableUnitJarEntries for all sbb.jars in the
424             // deployable
425             // unit
426 
427             // unpack all jar files to allow class visibility across dependent
428             // DU components
429             prepareDeploy(simpleComponentsJarFiles);
430             prepareDeploy(complexComponentsJarFiles);
431                         
432             loadDeployment(simpleComponentsJarFiles, complexComponentsJarFiles, serviceNodes, jarNames, extractedJars);
433         } catch (DeploymentException ex) {
434             try {
435                 transactionManager.setRollbackOnly();
436             } catch (Exception e) {
437                 throw new RuntimeException("Pb with Slee Transaction Manager",
438                         e);
439             }
440             throw ex;
441 
442         } finally {
443             try {
444                 if (b) transactionManager.commit();
445             } catch (Exception e) {
446                 throw new RuntimeException("Pb with Slee Transaction Manager",
447                         e);
448             }
449         }
450 
451 
452     }
453 
454     /**
455      * 
456      * Provided that all DU classes are extracted in a local dir,
457      * proceed with loading them up and registering with SLEE runtime
458      * @throws DeploymentException
459      * @throws Exception
460      * 
461      */
462     private void loadDeployment(HashSet simpleCompJarFiles, HashSet complexCompJarFiles, List serviceNodes, List jarNames,
463             HashSet extractedJars) throws DeploymentException  {
464         // Deploy the unit with a unique designated classloader.
465         // There's one classloader per DU and one per SBB thats derived from
466         // this
467         // classloader.
468         ClassLoader oldClassLoader = Thread.currentThread()
469                 .getContextClassLoader();
470 
471         this.classLoader = createDUClassLoader();
472         //this.classPool = ConcreteClassGeneratorUtils.createClassPool();
473         try {
474             classPath = classPool.appendClassPath(this
475                     .getTempClassDeploymentDir().getAbsolutePath());
476             Thread.currentThread().setContextClassLoader(this.classLoader);
477 
478             // events are deployed first
479             Iterator iter = simpleCompJarFiles.iterator();
480             while (iter.hasNext()) {
481                 //take care of the deployment of the componentitself
482                 AbstractComponentDeployer deployer = (AbstractComponentDeployer) iter
483                         .next();
484                 deployer.deployAndInstall(deployableUnitID);
485             }
486                 
487             loadDeployedComponents(complexCompJarFiles, serviceNodes, jarNames, extractedJars);
488         
489         } catch (AlreadyDeployedException ex) {
490             String s = "Could not deploy deploybableUnitID = " + deployableUnitID;
491             
492             try {
493                 this.componentContainer
494                         .doRemove(deployableUnitID.getDescriptor());
495             } catch (Exception ex1) {
496                 ex1.printStackTrace();
497             }
498             
499             throw ex;
500         } catch (DeploymentException ex) {
501             String s = "Could not deploy deploybableUnitID = " + deployableUnitID;
502             
503             try {
504                 this.componentContainer
505                         .doRemove(deployableUnitID.getDescriptor());
506             } catch (Exception ex1) {
507                 ex1.printStackTrace();
508             }
509             
510             throw ex;
511         } catch (Exception ex) {
512             String s = "Could not deploy deploybableUnitID = " + deployableUnitID;
513             
514             try {
515                 this.componentContainer
516                         .doRemove(deployableUnitID.getDescriptor());
517             } catch (Exception ex1) {
518                 ex1.printStackTrace();
519             }
520             this.classPool.removeClassPath(classPath);
521             
522             throw new DeploymentException(ex.getMessage(), ex);
523         } finally {
524             Thread.currentThread().setContextClassLoader(oldClassLoader);
525         }
526     }
527 
528     /**
529      * Iterate over deployed components and register them with SLEE runtime
530      * @throws DeploymentException
531      */
532     private void loadDeployedComponents(HashSet jarFiles, List serviceNodes, List jarNames, HashSet extractedJars) throws DeploymentException {
533         Iterator iter = jarFiles.iterator();
534         while (iter.hasNext()) {
535             try {
536                 //take care of the deployment of the componentitself
537                 AbstractComponentDeployer deployer = (AbstractComponentDeployer) iter
538                         .next();
539 
540                 deployer.deployAndInstall(deployableUnitID);
541                 /** @todo keep a reference to the newly created entry */
542             } catch (AlreadyDeployedException ex) {
543                 ex.printStackTrace();
544                 try {
545                     this.componentContainer
546                             .doRemove(deployableUnitID.getDescriptor());
547                 } catch (Exception ex1) {
548                     ex1.printStackTrace();
549                 }
550                 throw ex;
551             } catch (DeploymentException ex) {
552                 ex.printStackTrace();
553                 try {
554                     this.componentContainer
555                             .doRemove(deployableUnitID.getDescriptor());
556                 } catch (Exception ex1) {
557                     ex1.printStackTrace();
558                 }
559                 throw ex;
560             } catch (Exception ex) {
561                 ex.printStackTrace();
562                 try {
563                     this.componentContainer
564                             .doRemove(deployableUnitID.getDescriptor());
565                 } catch (Exception ex1) {
566                     ex1.printStackTrace();
567                 }
568                 throw new DeploymentException(ex.getMessage(), ex);
569             }
570         }
571 
572         //Create DeployableUnitServiceEntries for for all services in the
573         // DU.
574         ArrayList serviceNames = new ArrayList();//used for asserting
575         // unique
576         // names
577         iter = serviceNodes.iterator();
578         while (iter.hasNext()) {
579             try {
580                 String serviceXmlName = XMLUtils
581                         .getElementTextValue((Element) iter.next());
582                 logger.info("serviceName = " + serviceXmlName);
583                 if (serviceXmlName.length() == 0
584                         || !serviceXmlName.toLowerCase().endsWith("xml")) {
585                     throw new DeploymentException(serviceXmlName
586                             + " is not a valid service-xml file name.");
587                 }
588                 if (serviceNames.contains(serviceXmlName)) {
589                     throw new DeploymentException("Encountered "
590                             + serviceXmlName + " more than once.");
591                 }
592                 jarNames.add(serviceXmlName);
593                 /** @todo keep a reference to the newly created entry */
594 
595                 //extract the xml entry
596                 File serviceXmlFile = DeploymentManager.extractFile(
597                         serviceXmlName, unitJarFile,
598                         getTempDUJarsDeploymentDirectory());
599 
600                 ServiceDeployer deployer = new ServiceDeployer();
601                 deployer.initDeployer(serviceXmlFile,
602                         getComponentContainer());
603                 deployer.deployAndInstall(deployableUnitID);
604 
605                 serviceXmlFile.delete();
606 
607             } catch (Exception ex) {
608                 try {
609                     this.getComponentContainer().doRemove(
610                             deployableUnitID.getDescriptor());
611                 } catch (Exception e) {
612                     logger.error("Error unistalling partial deployment", e);
613                 }
614                 throw new DeploymentException(ex.getMessage(), ex);
615 
616             }
617         }
618 
619 
620         Iterator it = extractedJars.iterator();
621         while (it.hasNext()) {
622             File fname = (File) it.next();
623             logger.debug("trying to delete file " + fname.getName());
624 
625             fname.delete();
626         }
627     }
628 
629     /**
630      * 
631      * Unjars a list of jar files in the DU's deployment dir
632      * 
633      * @param compJarFiles
634      */
635     private void prepareDeploy(HashSet compJarFiles)
636             throws DeploymentException {
637         DeployableUnitDescriptorImpl deployableUnitDescriptor = deployableUnitID
638                 .getDescriptor();
639 
640         Iterator iter = compJarFiles.iterator();
641         while (iter.hasNext()) {
642             try {
643                 //take care of the deployment of the componentitself
644                 AbstractComponentDeployer deployer = (AbstractComponentDeployer) iter
645                         .next();
646 
647                 deployer.prepareDeploy(deployableUnitID);
648                 /**
649                  * (Ivelin) what is this to do about? --> TODO: keep a reference
650                  * to the newly created entry
651                  */
652             } catch (Exception ex) {
653                 ex.printStackTrace();
654                 try {
655                     this.componentContainer.doRemove(deployableUnitDescriptor);
656                 } catch (Exception ex1) {
657                     ex1.printStackTrace();
658                 }
659                 throw new DeploymentException(ex.getMessage(), ex);
660             }
661         }
662     }
663 
664     /**
665      * @return the ClassLoader that will be associated with the DU. It will load
666      *         the classes in the DU and will be also used for JNDI objects
667      *         under ENC - java:comp/env
668      * @throws DeploymentException
669      */
670     protected UnifiedClassLoader createDUClassLoader()
671             throws DeploymentException {
672         try {
673             UnifiedClassLoader ucl = (UnifiedClassLoader) Thread
674                     .currentThread().getContextClassLoader();
675             UnifiedLoaderRepository3 lr = (UnifiedLoaderRepository3) ucl
676                     .getLoaderRepository();
677             UnifiedClassLoader cl = lr.newClassLoader(
678                     getTempClassDeploymentDir().toURL(), new File(
679                             getUnitJarFile().getName()).toURL(), true);
680             // make sure to call ucl.unregister() on undeploy()
681             return cl;
682         } catch (MalformedURLException e1) {
683             throw new DeploymentException(
684                     "Bad ULR for tempClassDeploymentDir: "
685                             + getTempClassDeploymentDir());
686         } catch (Exception e) {
687             throw new DeploymentException(
688                     "Failed Creating ClassLoader for tempClassDeploymentDir: "
689                             + getTempClassDeploymentDir());
690         }
691     }
692 
693     /**
694      * Extracts the file with name <code>fileName</code> out of the
695      * <code>containingJar</code> archive and stores it in <code>dstDir</code>.
696      * 
697      * @param fileName
698      *            the name of the file to extract.
699      * @param containingJar
700      *            the archive where to extract it from.
701      * @param dstDir
702      *            the location where the extracted file should be stored.
703      * @throws IOException
704      *             if reading the archive or storing the extracted file fails
705      * @return a <code>java.io.File</code> reference to the extracted file.
706      */
707     private static JarFile extractJar(String fileName, JarFile containingJar,
708             File dstDir) throws IOException {
709         return new JarFile(DeploymentManager.extractFile(fileName,
710                 containingJar, dstDir));
711 
712     }
713 
714     /**
715      * Verifies what kind of a deployment descriptor does the component jar file
716      * contain, constructs the corresponding ComponentDeployer accordingly,
717      * initilizes it and returns it ready for deployment or throws an exception
718      * if problems occur.
719      * 
720      * @param componentJarFile
721      *            the jar file that contains the component.
722      * @throws DeploymentException
723      *             if an exception occurs while deploying the component
724      * @return a ComponentDeployer ready fo <code>deploy</code> the contents
725      *         of the specified jar file.
726      */
727     private AbstractComponentDeployer createComponentDeployer(
728             JarFile componentJarFile) throws DeploymentException {
729 
730         java.util.jar.JarEntry descriptorXML = null;
731         AbstractComponentDeployer deployer = null;
732 
733         //Determine whether the type of this instance is an sbb, event, RA type
734         // etc.
735         if ((descriptorXML = componentJarFile
736                 .getJarEntry("META-INF/sbb-jar.xml")) != null) {
737 
738             deployer = new SbbComponentDeployer(deployableUnitID, descriptorXML);
739 
740         } else if ((descriptorXML = componentJarFile
741                 .getJarEntry("META-INF/profile-spec-jar.xml")) != null) {
742 
743             deployer = new ProfileSpecComponentDeployer(deployableUnitID,
744                     descriptorXML);
745 
746         } else if ((descriptorXML = componentJarFile
747                 .getJarEntry("META-INF/event-jar.xml")) != null) {
748 
749             deployer = new EventTypeComponentDeployer(deployableUnitID,
750                     descriptorXML);
751 
752         } else if ((descriptorXML = componentJarFile
753                 .getJarEntry("META-INF/resource-adaptor-type-jar.xml")) != null) {
754 
755             deployer = new ResourceAdaptorTypeComponentDeployer(
756                     deployableUnitID, descriptorXML);
757 
758         } else if ((descriptorXML = componentJarFile
759                 .getJarEntry("META-INF/resource-adaptor-jar.xml")) != null) {
760 
761             deployer = new ResourceAdaptorComponentDeployer(deployableUnitID,
762                     descriptorXML);
763 
764         } else {
765             throw new DeploymentException(
766                     "No Deployment Descriptor found in the "
767                             + componentJarFile.getName()
768                             + " entry of a deployable unit.");
769         }
770 
771         return deployer;
772     }
773 
774     /**
775      * 
776      * Sets the directory that will be used for deployment of the DU. Logic
777      * borrowed from JBoss deployment mechanism. Note: at some point we need to
778      * explore in-memory deployment to avoid IO overhead
779      * 
780      * @TODO: make sure to remove the temp directory on undeploy
781      * 
782      * @param jarName
783      *            The name of the jarFile which will be used as component in the
784      *            temp deployment dir name
785      * @throws IOException
786      *             if the temp dir cannot be created
787      */
788     private void createTempDeploymentDir() {
789         String jarName = new File(getUnitJarFile().getName()).getName();
790         ServerConfig config = ServerConfigLocator.locate();
791         File basedir = config.getServerTempDir();
792 
793         // ${jboss.server.home.dir}/tmp/deploy
794         File tempDeploymentRootDir = new File(basedir, "deploy");
795 
796         if (!tempDeploymentRootDir.exists()) {
797             boolean dirCreated = tempDeploymentRootDir.mkdirs();
798             if (!dirCreated)
799                 throw new SLEEException(
800                         "failed to create temp deployment dir: "
801                                 + tempDeploymentRootDir);
802         }
803 
804         try {
805             // first create a dummy file to gurantee uniqueness. I would have
806             // been nice if the File class had a createTempDir() method
807             // Caution - dont use jarName here -- the tck uses huge jar names.
808             this.tempDeploymentFile = File.createTempFile("tmpDUJarsUnpackaged", "",
809                     tempDeploymentRootDir);
810             //tempDeploymentFile.deleteOnExit();
811            
812 
813             tempClassDeploymentDir = new File(tempDeploymentFile
814                     .getAbsolutePath()
815                     + "-contents");
816             if (!tempClassDeploymentDir.exists())
817                 tempClassDeploymentDir.mkdirs();
818             
819             //tempClassDeploymentDir.deleteOnExit();
820 
821         } catch (IOException e) {
822             logger
823                     .error("Temp Deployment Directory could not be created for SLEE DU: "
824                             + jarName,e);
825             throw new SLEEException("Failed to create temp deployment dir", e);
826         }
827     }
828 
829     /**
830      * 
831      * @return Returns the tempClassDeploymentDir.
832      */
833     public File getTempClassDeploymentDir() {
834         return tempClassDeploymentDir;
835     }
836 
837     public ClassLoader getClassLoader() {
838         return classLoader;
839     }
840 
841     public ClassPool getClassPool() {
842         return this.classPool;
843     }
844 
845     /**
846      * Prepare for deployment sequence
847      *  
848      */
849     private void init() {
850         createTempDeploymentDir();
851     }
852 
853     /**
854      * Undeploy sequence for the DU that this deployer is responsible for
855      */
856     public void undeploy() {
857         // remove association with loader repository
858         
859         logger.debug("undeploy() " + this);
860         
861         if ( classLoader != null )
862         classLoader.unregister();
863         
864         // javassist cleanup
865         this.classPool.removeClassPath(classPath);
866 
867         // TODO -- clean up the du file
868     }
869 
870 }