| 1 22 package org.jboss.deployment; 23 24 import java.io.BufferedInputStream ; 25 import java.io.BufferedOutputStream ; 26 import java.io.File ; 27 import java.io.FileOutputStream ; 28 import java.io.IOException ; 29 import java.io.InputStream ; 30 import java.io.OutputStream ; 31 import java.net.MalformedURLException ; 32 import java.net.URL ; 33 import java.net.URLClassLoader ; 34 import java.util.ArrayList ; 35 import java.util.Collection ; 36 import java.util.Collections ; 37 import java.util.Comparator ; 38 import java.util.HashMap ; 39 import java.util.HashSet ; 40 import java.util.Iterator ; 41 import java.util.LinkedList ; 42 import java.util.List ; 43 import java.util.ListIterator ; 44 import java.util.Map ; 45 import java.util.Set ; 46 import java.util.StringTokenizer ; 47 import java.util.jar.Attributes ; 48 import java.util.jar.Manifest ; 49 50 import javax.management.JMException ; 51 import javax.management.MBeanServer ; 52 import javax.management.MalformedObjectNameException ; 53 import javax.management.Notification ; 54 import javax.management.ObjectName ; 55 56 import org.jboss.deployers.plugins.structure.AbstractDeploymentContext; 57 import org.jboss.deployers.spi.structure.DeploymentContext; 58 import org.jboss.mx.util.JMXExceptionDecoder; 59 import org.jboss.system.ServiceContext; 60 import org.jboss.system.ServiceMBeanSupport; 61 import org.jboss.system.server.ServerConfig; 62 import org.jboss.system.server.ServerConfigLocator; 63 import org.jboss.util.file.Files; 64 import org.jboss.util.file.JarUtils; 65 import org.jboss.util.stream.Streams; 66 import org.jboss.virtual.VFS; 67 import org.jboss.virtual.VirtualFile; 68 69 81 public class MainDeployer extends ServiceMBeanSupport 82 implements Deployer, MainDeployerMBean 83 { 84 private org.jboss.deployers.spi.deployment.MainDeployer delegate; 85 private Map <URL , String > contextMap = Collections.synchronizedMap(new HashMap <URL , String >()); 86 87 92 private ObjectName serviceController; 93 94 95 private final LinkedList deployers = new LinkedList (); 96 97 98 private final Map deploymentMap = Collections.synchronizedMap(new HashMap ()); 99 100 101 private final List deploymentList = new ArrayList (); 102 103 104 private final List waitingDeployments = new ArrayList (); 105 106 107 private final DeploymentSorter sorter = new DeploymentSorter(); 108 109 110 private final Comparator infoSorter = new DeploymentInfoComparator(sorter); 111 112 113 private final SuffixOrderHelper suffixOrderHelper = new SuffixOrderHelper(sorter); 114 115 116 private boolean copyFiles = true; 117 118 119 private File tempDir; 120 121 122 private String tempDirString; 123 124 127 public MainDeployer() 128 { 129 String localCopy = System.getProperty("jboss.deploy.localcopy"); 131 if (localCopy != null && ( 132 localCopy.equalsIgnoreCase("false") || 133 localCopy.equalsIgnoreCase("no") || 134 localCopy.equalsIgnoreCase("off"))) 135 { 136 log.debug("Disabling local copies of file: urls"); 137 copyFiles = false; 138 } 139 } 140 141 public org.jboss.deployers.spi.deployment.MainDeployer getKernelMainDeployer() 142 { 143 return delegate; 144 } 145 public void setKernelMainDeployer(org.jboss.deployers.spi.deployment.MainDeployer delegate) 146 { 147 this.delegate = delegate; 148 } 149 150 155 public boolean getCopyFiles() 156 { 157 return copyFiles; 158 } 159 166 public void setCopyFiles(boolean copyFiles) 167 { 168 this.copyFiles = copyFiles; 169 } 170 171 176 public File getTempDir() 177 { 178 return tempDir; 179 } 180 185 public void setTempDir(File tempDir) 186 { 187 this.tempDir = tempDir; 188 } 189 190 195 public String getTempDirString() 196 { 197 return tempDirString; 198 } 199 200 205 public String [] getSuffixOrder() 206 { 207 return suffixOrderHelper.getSuffixOrder(); 208 } 209 210 215 public String [] getEnhancedSuffixOrder() 216 { 217 return suffixOrderHelper.getEnhancedSuffixes(); 218 } 219 220 225 public void setEnhancedSuffixOrder(String [] enhancedSuffixOrder) 226 { 227 suffixOrderHelper.setEnhancedSuffixes(enhancedSuffixOrder); 228 } 229 230 236 public void setServiceController(final ObjectName serviceController) 237 { 238 this.serviceController = serviceController; 239 } 240 241 248 public Collection listDeployed() 249 { 250 synchronized (deploymentList) 251 { 252 log.debug("deployment list string: " + deploymentList); 253 return new ArrayList (deploymentList); 254 } 255 } 256 257 264 public Collection listDeployedModules() 265 { 266 log.debug("listDeployedModules"); 267 268 HashMap map = new HashMap (); 269 synchronized (deploymentList) 270 { 271 Collection col = new ArrayList (deploymentList); 272 273 for (Iterator it = col.iterator(); it.hasNext();) 275 { 276 DeploymentInfo info = (DeploymentInfo) it.next(); 277 map.put(info.url, new SerializableDeploymentInfo(info)); 278 fillParentAndChildrenSDI(info, map); 280 } 281 } 282 283 return new ArrayList (map.values()); 285 } 286 287 293 public String listDeployedAsString() 294 { 295 return "<pre>" + listDeployed() + "</pre>"; 296 } 297 298 306 public Collection listIncompletelyDeployed() 307 { 308 List id = new ArrayList (); 309 List copy; 310 synchronized (deploymentList) 311 { 312 copy = new ArrayList (deploymentList); 313 } 314 for (Iterator i = copy.iterator(); i.hasNext();) 315 { 316 DeploymentInfo di = (DeploymentInfo)i.next(); 317 if (!"Deployed".equals(di.status) && !"Starting".equals(di.status)) 318 { 319 id.add(di); 320 } 322 } return id; 324 } 325 326 333 public Collection listWaitingForDeployer() 334 { 335 synchronized (waitingDeployments) 336 { 337 return new ArrayList (waitingDeployments); 338 } 339 } 340 341 348 public void addDeployer(final SubDeployer deployer) 349 { 350 log.debug("Adding deployer: " + deployer); 351 ObjectName deployerName = deployer.getServiceName(); 352 353 synchronized(deployers) 354 { 355 deployers.addFirst(deployer); 356 try 357 { 358 String [] suffixes = (String []) server.getAttribute(deployerName, "EnhancedSuffixes"); 359 suffixOrderHelper.addEnhancedSuffixes(suffixes); 360 } 361 catch(Exception e) 362 { 363 log.debug(deployerName + " does not support EnhancedSuffixes"); 364 suffixOrderHelper.addSuffixes(deployer.getSuffixes(), deployer.getRelativeOrder()); 365 } 366 } 367 368 Notification msg = new Notification (ADD_DEPLOYER, this, getNextNotificationSequenceNumber()); 370 msg.setUserData(deployerName); 371 sendNotification(msg); 372 373 synchronized (waitingDeployments) 374 { 375 List copy = new ArrayList (waitingDeployments); 376 waitingDeployments.clear(); 377 for (Iterator i = copy.iterator(); i.hasNext();) 378 { 379 DeploymentInfo di = (DeploymentInfo)i.next(); 380 log.debug("trying to deploy with new deployer: " + di.shortName); 381 try 382 { 383 di.setServer(server); 384 deploy(di); 385 } 386 catch (DeploymentException e) 387 { 388 log.error("DeploymentException while trying to deploy a package with a new deployer", e); 389 } } } 392 } 393 394 401 public void removeDeployer(final SubDeployer deployer) 402 { 403 log.debug("Removing deployer: " + deployer); 404 ObjectName deployerName = deployer.getServiceName(); 405 boolean removed = false; 406 407 synchronized(deployers) 408 { 409 removed = deployers.remove(deployer); 410 try 411 { 412 String [] suffixes = (String []) server.getAttribute(deployerName, "EnhancedSuffixes"); 413 suffixOrderHelper.removeEnhancedSuffixes(suffixes); 414 } 415 catch(Exception e) 416 { 417 log.debug(deployerName + " does not support EnhancedSuffixes"); 418 suffixOrderHelper.removeSuffixes(deployer.getSuffixes(), deployer.getRelativeOrder()); 419 } 420 } 421 422 if (removed) 424 { 425 Notification msg = new Notification (REMOVE_DEPLOYER, this, getNextNotificationSequenceNumber()); 426 msg.setUserData(deployerName); 427 sendNotification(msg); 428 } 429 430 List copy; 431 synchronized (deploymentList) 432 { 433 copy = new ArrayList (deploymentList); 434 } 435 for (Iterator i = copy.iterator(); i.hasNext(); ) 436 { 437 DeploymentInfo di = (DeploymentInfo)i.next(); 438 if (di.deployer == deployer) 439 { 440 undeploy(di); 441 di.deployer = null; 442 synchronized (waitingDeployments) 443 { 444 waitingDeployments.add(di); 445 } 446 } 447 } 448 } 449 450 457 public Collection listDeployers() 458 { 459 ArrayList deployerNames = new ArrayList (); 460 synchronized(deployers) 461 { 462 for(int n = 0; n < deployers.size(); n ++) 463 { 464 SubDeployer deployer = (SubDeployer) deployers.get(n); 465 ObjectName name = deployer.getServiceName(); 466 deployerNames.add(name); 467 } 468 } 469 return deployerNames; 470 } 471 472 474 protected ObjectName getObjectName(MBeanServer server, ObjectName name) 475 throws MalformedObjectNameException  476 { 477 return name == null ? OBJECT_NAME : name; 478 } 479 480 485 protected void createService() throws Exception  486 { 487 ServerConfig config = ServerConfigLocator.locate(); 488 File basedir = config.getServerTempDir(); 490 tempDir = new File (basedir, "deploy"); 492 Files.delete(tempDir); 494 tempDir.mkdirs(); 496 497 tempDirString = tempDir.toURL().toString(); 499 500 suffixOrderHelper.initialize(); 502 } 503 504 510 public void shutdown() 511 { 512 int deployCounter = 0; 515 516 List copy; 518 synchronized (deploymentList) 519 { 520 copy = new ArrayList (deploymentList); 521 } 522 for (ListIterator i = copy.listIterator(copy.size()); i.hasPrevious(); ) 523 { 524 try 525 { 526 undeploy((DeploymentInfo)i.previous(), true); 527 deployCounter++; 528 } 529 catch (Exception e) 530 { 531 log.info("exception trying to undeploy during shutdown", e); 532 } 533 534 } 535 this.deployers.clear(); 537 this.deploymentMap.clear(); 538 this.deploymentList.clear(); 539 this.waitingDeployments.clear(); 540 this.tempDir = null; 541 542 log.debug("Undeployed " + deployCounter + " deployed packages"); 543 } 544 545 546 554 public void redeploy(String urlspec) 555 throws DeploymentException, MalformedURLException  556 { 557 redeploy(new URL (urlspec)); 558 } 559 560 567 public void redeploy(URL url) throws DeploymentException 568 { 569 undeploy(url); 570 deploy(url); 571 } 572 573 580 public void redeploy(DeploymentInfo sdi) throws DeploymentException 581 { 582 try 583 { 584 undeploy(sdi); 585 } 586 catch (Throwable t) 587 { 588 log.info("Throwable from undeployment attempt: ", t); 589 } sdi.setServer(server); 591 deploy(sdi); 592 } 593 594 601 public void undeploy(String urlspec) 602 throws DeploymentException, MalformedURLException  603 { 604 undeploy(new URL (urlspec)); 605 } 606 607 613 public void undeploy(URL url) throws DeploymentException 614 { 615 String deploymentName = contextMap.remove(url); 616 if (deploymentName != null) 617 { 618 try 619 { 620 delegate.removeDeploymentContext(deploymentName); 621 delegate.process(); 622 } 623 catch(Exception e) 624 { 625 DeploymentException ex = new DeploymentException("Error during undeploy of: "+url, e); 626 throw ex; 627 } 628 } 629 else 630 { 631 log.warn("undeploy '" + url + "' : package not deployed"); 632 } 633 } 634 635 642 public void undeploy(DeploymentInfo di) 643 { 644 undeploy(di, false); 645 } 646 protected void undeploy(DeploymentInfo di, boolean isShutdown) 647 { 648 log.debug("Undeploying "+di.url); 649 stop(di); 650 destroy(di); 651 } 652 653 658 private void stop(DeploymentInfo di) 659 { 660 ArrayList reverseSortedSubs = new ArrayList (di.subDeployments); 662 Collections.sort(reverseSortedSubs, infoSorter); 663 Collections.reverse(reverseSortedSubs); 664 for (Iterator subs = reverseSortedSubs.iterator(); subs.hasNext();) 665 { 666 DeploymentInfo sub = (DeploymentInfo) subs.next(); 667 log.debug("Stopping sub deployment: "+sub.url); 668 stop(sub); 669 } 670 try 672 { 673 if (di.deployer != null) 675 { 676 di.deployer.stop(di); 677 di.status="Stopped"; 678 di.state = DeploymentState.STOPPED; 679 } 680 } 681 catch (Throwable t) 682 { 683 log.error("Deployer stop failed for: " + di.url, t); 684 } 685 686 } 687 688 693 private void destroy(DeploymentInfo di) 694 { 695 ArrayList reverseSortedSubs = new ArrayList (di.subDeployments); 697 Collections.sort(reverseSortedSubs, infoSorter); 698 Collections.reverse(reverseSortedSubs); 699 for (Iterator subs = reverseSortedSubs.iterator(); subs.hasNext();) 700 { 701 DeploymentInfo sub = (DeploymentInfo) subs.next(); 702 log.debug("Destroying sub deployment: "+sub.url); 703 destroy(sub); 704 } 705 try 707 { 708 if (di.deployer != null) 710 { 711 di.deployer.destroy(di); 712 di.status="Destroyed"; 713 di.state = DeploymentState.DESTROYED; 714 } 715 } 716 catch (Throwable t) 717 { 718 log.error("Deployer destroy failed for: " + di.url, t); 719 di.state = DeploymentState.FAILED; 720 } 721 722 try 723 { 724 synchronized (deploymentList) 726 { 727 deploymentMap.remove(di.url); 728 if (deploymentList.lastIndexOf(di) != -1) 729 { 730 deploymentList.remove(deploymentList.lastIndexOf(di)); 731 } 732 } 733 synchronized (waitingDeployments) 734 { 735 waitingDeployments.remove(di); 736 } 737 di.cleanup(); 739 740 log.debug("Undeployed "+di.url); 741 } 742 catch (Throwable t) 743 { 744 log.error("Undeployment cleanup failed: " + di.url, t); 745 } 746 } 747 748 756 public void deploy(String urlspec) 757 throws DeploymentException, MalformedURLException  758 { 759 if( server == null ) 760 throw new DeploymentException("The MainDeployer has been unregistered"); 761 762 URL url; 763 try 764 { 765 url = new URL (urlspec); 766 } 767 catch (MalformedURLException e) 768 { 769 File file = new File (urlspec); 770 url = file.toURL(); 771 } 772 773 deploy(url); 774 } 775 776 782 public void deploy(URL url) throws DeploymentException 783 { 784 log.info("deploy, url="+url); 785 String deploymentName = contextMap.get(url); 786 if (deploymentName == null) 788 { 789 try 790 { 791 VirtualFile file = VFS.getRoot(url); 792 DeploymentContext deployment = new AbstractDeploymentContext(file); 793 delegate.addDeploymentContext(deployment); 794 deploymentName = deployment.getName(); 795 delegate.process(); 796 contextMap.put(url, deploymentName); 797 } 798 catch(Exception e) 799 { 800 log.warn("Failed to deploy: "+url, e); 801 DeploymentException ex = new DeploymentException("Failed to deploy: "+url, e); 802 throw ex; 803 } 804 } 805 } 806 807 814 public void deploy(DeploymentInfo deployment) 815 throws DeploymentException 816 { 817 if (isDeployed(deployment.url)) 819 { 820 log.info("Package: " + deployment.url + " is already deployed"); 821 return; 822 } 823 log.debug("Starting deployment of package: " + deployment.url); 824 825 boolean inited = false; 826 try 827 { 828 inited = init(deployment); 829 } 830 catch (Throwable t) 831 { 832 log.error("Could not initialise deployment: " + deployment.url, t); 833 DeploymentException.rethrowAsDeploymentException("Could not initialise deployment: " + deployment.url, t); 834 } 835 if ( inited ) 836 { 837 create(deployment); 838 start(deployment); 839 log.debug("Deployed package: " + deployment.url); 840 } else 842 { 843 log.debug("Deployment of package: " + deployment.url + " is waiting for an appropriate deployer."); 844 } } 846 847 848 856 private boolean init(DeploymentInfo deployment) throws DeploymentException 857 { 858 if (isDeployed(deployment.url)) 860 { 861 log.info("Package: " + deployment.url + " is already deployed"); 862 return false; 863 } 864 log.debug("Starting deployment (init step) of package at: " + deployment.url); 865 try 866 { 867 if (deployment.localUrl == null) 869 { 870 makeLocalCopy(deployment); 871 URL [] localCl = new URL []{deployment.localUrl}; 872 deployment.localCl = new URLClassLoader (localCl); 873 } 874 875 findDeployer(deployment); 877 878 if(deployment.deployer == null) 879 { 880 deployment.state = DeploymentState.INIT_WAITING_DEPLOYER; 881 log.debug("deployment waiting for deployer: " + deployment.url); 882 synchronized (waitingDeployments) 883 { 884 if (waitingDeployments.contains(deployment) == false) 885 waitingDeployments.add(deployment); 886 } 887 return false; 888 } 889 deployment.state = DeploymentState.INIT_DEPLOYER; 890  
|