1 22 package org.jboss.web; 23 24 import java.net.MalformedURLException ; 25 import java.net.URL ; 26 import java.net.URLClassLoader ; 27 import java.util.ArrayList ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.Set ; 31 import java.security.Policy ; 32 import javax.management.MBeanServer ; 33 import javax.naming.Context ; 34 import javax.naming.InitialContext ; 35 import javax.naming.LinkRef ; 36 import javax.naming.NamingException ; 37 import javax.security.jacc.PolicyConfiguration ; 38 import javax.security.jacc.PolicyConfigurationFactory ; 39 import javax.security.jacc.PolicyContextException ; 40 41 import org.jboss.deployment.DeploymentException; 42 import org.jboss.deployment.DeploymentInfo; 43 import org.jboss.deployment.J2eeApplicationMetaData; 44 import org.jboss.ejb.Container; 45 import org.jboss.ejb.EjbUtil; 46 import org.jboss.logging.Logger; 47 import org.jboss.metadata.EjbLocalRefMetaData; 48 import org.jboss.metadata.EjbRefMetaData; 49 import org.jboss.metadata.EnvEntryMetaData; 50 import org.jboss.metadata.MessageDestinationMetaData; 51 import org.jboss.metadata.MessageDestinationRefMetaData; 52 import org.jboss.metadata.ResourceEnvRefMetaData; 53 import org.jboss.metadata.ResourceRefMetaData; 54 import org.jboss.metadata.WebMetaData; 55 import org.jboss.mx.loading.LoaderRepositoryFactory; 56 import org.jboss.mx.util.MBeanProxyExt; 57 import org.jboss.naming.NonSerializableFactory; 58 import org.jboss.naming.Util; 59 import org.jboss.security.AuthorizationManager; 60 import org.jboss.security.authorization.PolicyRegistration; 61 import org.jboss.security.plugins.AuthorizationManagerServiceMBean; 62 import org.jboss.web.AbstractWebContainer.WebDescriptorParser; 63 import org.jboss.webservice.ServiceRefHandler; 64 import org.jboss.webservice.ServiceRefHandlerFactory; 65 import org.omg.CORBA.ORB ; 66 67 161 public abstract class AbstractWebDeployer 162 { 163 public static final String ERROR = "org.jboss.web.AbstractWebContainer.error"; 164 protected Logger log; 165 166 protected MBeanServer server; 167 170 protected boolean java2ClassLoadingCompliance = false; 171 174 protected boolean unpackWars = true; 175 179 protected boolean lenientEjbLink = false; 180 181 184 protected String defaultSecurityDomain; 185 186 public AbstractWebDeployer() 187 { 188 log = Logger.getLogger(getClass()); 189 } 190 191 public abstract void init(Object containerConfig) throws Exception ; 192 193 public MBeanServer getServer() 194 { 195 return server; 196 } 197 198 public void setServer(MBeanServer server) 199 { 200 this.server = server; 201 } 202 203 209 public boolean getJava2ClassLoadingCompliance() 210 { 211 return java2ClassLoadingCompliance; 212 } 213 214 220 public void setJava2ClassLoadingCompliance(boolean flag) 221 { 222 java2ClassLoadingCompliance = flag; 223 } 224 225 232 public boolean getUnpackWars() 233 { 234 return unpackWars; 235 } 236 237 244 public void setUnpackWars(boolean flag) 245 { 246 this.unpackWars = flag; 247 } 248 249 255 public boolean getLenientEjbLink() 256 { 257 return lenientEjbLink; 258 } 259 260 265 public void setLenientEjbLink(boolean flag) 266 { 267 lenientEjbLink = flag; 268 } 269 270 276 public String getDefaultSecurityDomain() 277 { 278 return defaultSecurityDomain; 279 } 280 281 288 public void setDefaultSecurityDomain(String defaultSecurityDomain) 289 { 290 this.defaultSecurityDomain = defaultSecurityDomain; 291 } 292 293 325 public synchronized WebApplication start(DeploymentInfo di) throws DeploymentException 326 { 327 Thread thread = Thread.currentThread(); 328 ClassLoader appClassLoader = thread.getContextClassLoader(); 329 WebApplication warInfo = null; 330 try 331 { 332 URL [] empty = {}; 334 URLClassLoader warLoader1 = URLClassLoader.newInstance(empty, di.ucl); 335 URLClassLoader warLoader = warLoader1; 336 thread.setContextClassLoader(warLoader); 337 WebDescriptorParser webAppParser = new DescriptorParser(di); 338 String webContext = di.webContext; 339 if (webContext != null && webContext.startsWith("/") == false) 340 webContext = "/" + webContext; 341 342 URL warURL = di.localUrl != null ? di.localUrl : di.url; 344 345 log.debug("webContext: " + webContext); 346 log.debug("warURL: " + warURL); 347 log.debug("webAppParser: " + webAppParser); 348 349 WebMetaData webMetaData = (WebMetaData) di.metaData; 351 352 if (di.parent != null && di.parent.metaData instanceof J2eeApplicationMetaData) 354 { 355 J2eeApplicationMetaData appMetaData = (J2eeApplicationMetaData) di.parent.metaData; 356 357 if (webMetaData.getSecurityDomain() == null) 358 webMetaData.setSecurityDomain(appMetaData.getSecurityDomain()); 359 360 webMetaData.mergeSecurityRoles(appMetaData.getSecurityRoles()); 361 } 362 363 String contextID = di.shortName; 365 if (contextID == null) 366 contextID = di.shortName; 367 webMetaData.setJaccContextID(contextID); 368 PolicyConfigurationFactory pcFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory(); 369 PolicyConfiguration pc = pcFactory.getPolicyConfiguration(contextID, true); 370 createPermissions(webMetaData, pc); 371 DeploymentInfo current = di; 373 while (current.parent != null) 374 current = current.parent; 375 PolicyConfiguration parentPC = (PolicyConfiguration ) 376 current.context.get("javax.security.jacc.PolicyConfiguration"); 377 if (parentPC != null && parentPC != pc) 378 parentPC.linkConfiguration(pc); 379 380 pc.commit(); 382 Policy.getPolicy().refresh(); 384 385 warInfo = new WebApplication(webMetaData); 386 warInfo.setClassLoader(warLoader); 387 performDeploy(warInfo, warURL.toString(), webAppParser); 388 } 389 catch (DeploymentException e) 390 { 391 di.context.put(ERROR, e); 392 throw e; 393 } 394 catch (Exception e) 395 { 396 DeploymentException ex = new DeploymentException("Error during deploy", e); 397 di.context.put(ERROR, ex); 398 throw ex; 399 } 400 finally 401 { 402 thread.setContextClassLoader(appClassLoader); 403 } 404 return warInfo; 405 } 406 407 421 protected abstract void performDeploy(WebApplication webApp, String warUrl, 422 WebDescriptorParser webAppParser) throws Exception ; 423 424 430 public synchronized void stop(DeploymentInfo di) 431 throws DeploymentException 432 { 433 URL warURL = di.localUrl != null ? di.localUrl : di.url; 434 String warUrl = warURL.toString(); 435 try 436 { 437 WebApplication webApp = (WebApplication) di.context.get(AbstractWebContainer.WEB_APP); 438 performUndeploy(warUrl, webApp); 439 WebMetaData webMetaData = (WebMetaData) di.metaData; 441 String contextID = webMetaData.getJaccContextID(); 442 PolicyConfigurationFactory pcFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory(); 443 PolicyConfiguration pc = pcFactory.getPolicyConfiguration(contextID, true); 444 pc.delete(); 445 String prefixedSecurityDomain = webApp.getMetaData().getSecurityDomain(); 447 if(prefixedSecurityDomain != null) 448 { 449 AuthorizationManager authzmgr = 450 org.jboss.security.Util.getAuthorizationManager(prefixedSecurityDomain); 451 if(authzmgr instanceof PolicyRegistration) 452 { 453 PolicyRegistration xam = (PolicyRegistration)authzmgr; 454 xam.deRegisterPolicy(contextID); 455 } 456 } 457 } 458 catch (DeploymentException e) 459 { 460 throw e; 461 } 462 catch (Exception e) 463 { 464 throw new DeploymentException("Error during deploy", e); 465 } 466 } 467 468 472 protected abstract void performUndeploy(String warUrl, WebApplication webApp) 473 throws Exception ; 474 475 482 protected void parseWebAppDescriptors(DeploymentInfo di, ClassLoader loader, 483 WebMetaData metaData) 484 throws Exception 485 { 486 log.debug("AbstractWebContainer.parseWebAppDescriptors, Begin"); 487 InitialContext iniCtx = new InitialContext (); 488 Context envCtx = null; 489 Thread currentThread = Thread.currentThread(); 490 ClassLoader currentLoader = currentThread.getContextClassLoader(); 491 try 492 { 493 log.debug("Creating ENC using ClassLoader: " + loader); 495 ClassLoader parent = loader.getParent(); 496 while (parent != null) 497 { 498 log.debug(".." + parent); 499 parent = parent.getParent(); 500 } 501 currentThread.setContextClassLoader(loader); 503 metaData.setENCLoader(loader); 504 envCtx = (Context ) iniCtx.lookup("java:comp"); 505 506 ORB orb = null; 507 try 508 { 509 orb = (ORB ) server.getAttribute(Container.ORB_NAME, "ORB"); 510 } 511 catch (Throwable t) 512 { 513 log.debug("Unable to retrieve orb" + t.toString()); 514 } 515 516 if (orb != null) 518 { 519 NonSerializableFactory.rebind(envCtx, "ORB", orb); 520 log.debug("Bound java:comp/ORB"); 521 } 522 523 envCtx.bind("UserTransaction", new LinkRef ("UserTransaction")); 525 log.debug("Linked java:comp/UserTransaction to JNDI name: UserTransaction"); 526 envCtx = envCtx.createSubcontext("env"); 527 processEncReferences(metaData, envCtx, di); 528 } 529 finally 530 { 531 currentThread.setContextClassLoader(currentLoader); 532 } 533 534 String securityDomain = metaData.getSecurityDomain(); 535 log.debug("linkSecurityDomain"); 536 linkSecurityDomain(securityDomain, envCtx); 537 log.debug("AbstractWebContainer.parseWebAppDescriptors, End"); 538 } 539 540 protected void processEncReferences(WebMetaData metaData, Context envCtx, DeploymentInfo di) 541 throws ClassNotFoundException , NamingException , DeploymentException 542 { 543 Iterator envEntries = metaData.getEnvironmentEntries(); 544 log.debug("addEnvEntries"); 545 addEnvEntries(envEntries, envCtx); 546 Iterator resourceEnvRefs = metaData.getResourceEnvReferences(); 547 log.debug("linkResourceEnvRefs"); 548 linkResourceEnvRefs(resourceEnvRefs, envCtx); 549 Iterator resourceRefs = metaData.getResourceReferences(); 550 log.debug("linkResourceRefs"); 551 linkResourceRefs(resourceRefs, envCtx); 552 log.debug("linkMessageDestinationRefs"); 553 linkMessageDestinationRefs(metaData, envCtx, di); 554 Iterator ejbRefs = metaData.getEjbReferences(); 555 log.debug("linkEjbRefs"); 556 linkEjbRefs(ejbRefs, envCtx, di); 557 Iterator ejbLocalRefs = metaData.getEjbLocalReferences(); 558 log.debug("linkEjbLocalRefs"); 559 linkEjbLocalRefs(ejbLocalRefs, envCtx, di); 560 Iterator serviceRefs = metaData.getServiceReferences(); 561 log.debug("linkServiceRefs"); 562 ServiceRefHandler refHandler = ServiceRefHandlerFactory.newInstance(); 563 if (refHandler != null && serviceRefs.hasNext()) 564 refHandler.setupServiceRefEnvironment(envCtx, serviceRefs, di); 565 } 566 567 protected void addEnvEntries(Iterator envEntries, Context envCtx) 568 throws ClassNotFoundException , NamingException 569 { 570 while (envEntries.hasNext()) 571 { 572 EnvEntryMetaData entry = (EnvEntryMetaData) envEntries.next(); 573 log.debug("Binding env-entry: " + entry.getName() + " of type: " + 574 entry.getType() + " to value:" + entry.getValue()); 575 EnvEntryMetaData.bindEnvEntry(envCtx, entry); 576 } 577 } 578 579 protected void linkResourceEnvRefs(Iterator resourceEnvRefs, Context envCtx) 580 throws NamingException 581 { 582 while (resourceEnvRefs.hasNext()) 583 { 584 ResourceEnvRefMetaData ref = (ResourceEnvRefMetaData) resourceEnvRefs.next(); 585 String resourceName = ref.getJndiName(); 586 String refName = ref.getRefName(); 587 if (ref.getType().equals("java.net.URL")) 588 { 589 try 590 { 591 log.debug("Binding '" + refName + "' to URL: " + resourceName); 592 URL url = new URL (resourceName); 593 Util.bind(envCtx, refName, url); 594 } 595 catch (MalformedURLException e) 596 { 597 throw new NamingException ("Malformed URL:" + e.getMessage()); 598 } 599 } 600 else if (resourceName != null) 601 { 602 log.debug("Linking '" + refName + "' to JNDI name: " + resourceName); 603 Util.bind(envCtx, refName, new LinkRef (resourceName)); 604 } 605 else 606 { 607 throw new NamingException ("resource-env-ref: " + refName 608 + " has no valid JNDI binding. Check the jboss-web/resource-env-ref."); 609 } 610 } 611 } 612 613 protected void linkResourceRefs(Iterator resourceRefs, Context envCtx) 614 throws NamingException 615 { 616 while (resourceRefs.hasNext()) 617 { 618 ResourceRefMetaData ref = (ResourceRefMetaData) resourceRefs.next(); 619 String jndiName = ref.getJndiName(); 620 String refName = ref.getRefName(); 621 if (ref.getType().equals("java.net.URL")) 622 { 623 try 624 { 625 String resURL = ref.getResURL(); 626 if (ref.getResURL() != null) 627 { 628 log.debug("Binding '" + refName + "' to URL: " + resURL); 629 URL url = new URL (resURL); 630 Util.bind(envCtx, refName, url); 631 } 632 else 633 { 634 log.debug("Linking '" + refName + "' to URL: " + resURL); 635 LinkRef urlLink = new LinkRef (jndiName); 636 Util.bind(envCtx, refName, urlLink); 637 } 638 } 639 catch (MalformedURLException e) 640 { 641 throw new NamingException ("Malformed URL:" + e.getMessage()); 642 } 643 } 644 else if (jndiName != null) 645 { 646 log.debug("Linking '" + refName + "' to JNDI name: " + jndiName); 647 Util.bind(envCtx, refName, new LinkRef (jndiName)); 648 } 649 else 650 { 651 throw new NamingException ("resource-ref: " + refName 652 + " has no valid JNDI binding. Check the jboss-web/resource-ref."); 653 } 654 } 655 } 656 657 protected void linkMessageDestinationRefs(WebMetaData metaData, Context envCtx, DeploymentInfo di) 658 throws NamingException , DeploymentException 659 { 660 Iterator i = metaData.getMessageDestinationReferences(); 661 662 while (i.hasNext()) 663 { 664 MessageDestinationRefMetaData ref = (MessageDestinationRefMetaData) i.next(); 665 666 String refName = ref.getRefName(); 667 String jndiName = ref.getJNDIName(); 668 String link = ref.getLink(); 669 if (link != null) 670 { 671 if (jndiName == null) 672 { 673 MessageDestinationMetaData messageDestination = EjbUtil.findMessageDestination(server, di, link); 674 if (messageDestination == null) 675 throw new DeploymentException("message-destination-ref '" + refName + 676 "' message-destination-link '" + link + "' not found and no jndi-name in jboss-web.xml"); 677 else 678 { 679 String linkJNDIName = messageDestination.getJNDIName(); 680 if (linkJNDIName == null) 681 log.warn("message-destination '" + link + "' has no jndi-name in jboss-web.xml"); 682 else 683 jndiName = linkJNDIName; 684 } 685 } 686 else 687 log.warn("message-destination-ref '" + refName + 688 "' ignoring message-destination-link '" + link + "' because it has a jndi-name in jboss-web.xml"); 689 } 690 else if (jndiName == null) 691 throw new DeploymentException("message-destination-ref '" + refName + 692 "' has no message-destination-link in web.xml and no jndi-name in jboss-web.xml"); 693 Util.bind(envCtx, refName, new LinkRef (jndiName)); 694 } 695 } 696 697 protected void linkEjbRefs(Iterator ejbRefs, Context envCtx, DeploymentInfo di) 698 throws NamingException 699 { 700 while (ejbRefs.hasNext()) 701 { 702 EjbRefMetaData ejb = (EjbRefMetaData) ejbRefs.next(); 703 String name = ejb.getName(); 704 String linkName = ejb.getLink(); 705 String jndiName = null; 706 707 if (linkName != null) 709 { 710 jndiName = EjbUtil.findEjbLink(server, di, linkName); 711 712 if ((jndiName == null) && !(getLenientEjbLink())) 714 throw new NamingException ("ejb-ref: " + name + ", no ejb-link match"); 715 } 716 717 718 if (jndiName == null) 720 { 721 jndiName = ejb.getJndiName(); 722 if (jndiName == null) 723 throw new NamingException ("ejb-ref: " + name + ", no ejb-link in web.xml and no jndi-name in jboss-web.xml"); 724 } 725 726 log.debug("Linking ejb-ref: " + name + " to JNDI name: " + jndiName); 727 Util.bind(envCtx, name, new LinkRef (jndiName)); 728 } 729 } 730 731 protected void linkEjbLocalRefs(Iterator ejbRefs, Context envCtx, DeploymentInfo di) 732 throws NamingException 733 { 734 while (ejbRefs.hasNext()) 735 { 736 EjbLocalRefMetaData ejb = (EjbLocalRefMetaData) ejbRefs.next(); 737 String name = ejb.getName(); 738 String linkName = ejb.getLink(); 739 String jndiName = null; 740 741 if (linkName != null) 743 { 744 jndiName = EjbUtil.findLocalEjbLink(server, di, linkName); 745 746 if ((jndiName == null) && !(getLenientEjbLink())) 748 throw new NamingException ("ejb-ref: " + name + ", no ejb-link match"); 749 } 750 751 752 if (jndiName == null) 753 { 754 jndiName = ejb.getJndiName(); 755 if (jndiName == null) 756 { 757 String msg = null; 758 if (linkName == null) 759 { 760 msg = "ejb-local-ref: '" + name + "', no ejb-link in web.xml and " 761 + "no local-jndi-name in jboss-web.xml"; 762 } 763 else 764 { 765 msg = "ejb-local-ref: '" + name + "', with web.xml ejb-link: '" 766 + linkName + "' failed to resolve to an ejb with a LocalHome"; 767 } 768 throw new NamingException (msg); 769 } 770 } 771 772 log.debug("Linking ejb-local-ref: " + name + " to JNDI name: " + jndiName); 773 Util.bind(envCtx, name, new LinkRef (jndiName)); 774 } 775 } 776 777 786 protected void linkSecurityDomain(String securityDomain, Context envCtx) 787 throws NamingException 788 { 789 if (securityDomain == null) 790 { 791 securityDomain = getDefaultSecurityDomain(); 792 log.debug("No security-domain given, using default: " + securityDomain); 793 } 794 log.debug("Linking security/securityMgr to JNDI name: " + securityDomain); 795 Util.bind(envCtx, "security/securityMgr", new LinkRef (securityDomain)); 796 Util.bind(envCtx, "security/realmMapping", new LinkRef (securityDomain+"/realmMapping")); 797 Util.bind(envCtx, "security/authorizationMgr", new LinkRef (securityDomain+"/authorizationMgr")); 798 Util.bind(envCtx, "security/security-domain", new LinkRef (securityDomain)); 799 Util.bind(envCtx, "security/subject", new LinkRef (securityDomain + "/subject")); 800 } 801 802 809 public String [] getStandardCompileClasspath(ClassLoader loader) 810 { 811 String [] jspResources = { 812 "javax/servlet/resources/web-app_2_3.dtd", 813 "org/apache/jasper/resources/jsp12.dtd", 814 "javax/ejb/EJBHome.class" 815 }; 816 ArrayList tmp = new ArrayList (); 817 for (int j = 0; j < jspResources.length; j++) 818 { 819 URL rsrcURL = loader.getResource(jspResources[j]); 820 if (rsrcURL != null) 821 { 822 String url = rsrcURL.toExternalForm(); 823 if (rsrcURL.getProtocol().equals("jar")) 824 { 825 url = url.substring(4); 827 int seperator = url.indexOf('!'); 828 url = url.substring(0, seperator); 829 } 830 tmp.add(url); 831 } 832 else 833 { 834 log.warn("Failed to fin jsp rsrc: " + jspResources[j]); 835 } 836 } 837 log.trace("JSP StandardCompileClasspath: " + tmp); 838 String [] cp = new String [tmp.size()]; 839 tmp.toArray(cp); 840 return cp; 841 } 842 843 848 public String [] getCompileClasspath(ClassLoader loader) 849 { 850 HashSet tmp = new HashSet (); 851 ClassLoader cl = loader; 852 while (cl != null) 853 { 854 URL [] urls = AbstractWebContainer.getClassLoaderURLs(cl); 855 addURLs(tmp, urls); 856 cl = cl.getParent(); 857 } 858 try 859 { 860 URL [] globalUrls = (URL []) server.getAttribute(LoaderRepositoryFactory.DEFAULT_LOADER_REPOSITORY, 861 "URLs"); 862 addURLs(tmp, globalUrls); 863 } 864 catch (Exception e) 865 { 866 log.warn("Could not get global URL[] from default loader repository!", e); 867 } log.trace("JSP CompileClasspath: " + tmp); 869 String [] cp = new String [tmp.size()]; 870 tmp.toArray(cp); 871 return cp; 872 } 873 874 private void addURLs(Set urlSet, URL [] urls) 875 { 876 for (int u = 0; u < urls.length; u++) 877 { 878 URL url = urls[u]; 879 urlSet.add(url.toExternalForm()); 880 } 881 } 882 883 890 protected void createPermissions(WebMetaData metaData, PolicyConfiguration pc) 891 throws PolicyContextException 892 { 893 WebPermissionMapping.createPermissions(metaData, pc); 894 } 895 896 900 private class DescriptorParser implements WebDescriptorParser 901 { 902 DeploymentInfo di; 903 904 DescriptorParser(DeploymentInfo di) 905 { 906 this.di = di; 907 } 908 909 public void parseWebAppDescriptors(ClassLoader loader, WebMetaData metaData) 910 throws Exception 911 { 912 AbstractWebDeployer.this.parseWebAppDescriptors(di, loader, metaData); 913 } 914 915 public DeploymentInfo getDeploymentInfo() 916 { 917 return di; 918 } 919 } 920 } 921 | Popular Tags |