1 22 package org.jboss.web.tomcat.tc6.deployers; 23 24 import java.io.File ; 25 import java.io.FileOutputStream ; 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.net.MalformedURLException ; 29 import java.net.URL ; 30 import java.net.URLDecoder ; 31 import java.security.CodeSource ; 32 import java.security.cert.Certificate ; 33 import java.util.ArrayList ; 34 import java.util.HashMap ; 35 import java.util.HashSet ; 36 import java.util.Iterator ; 37 import java.util.List ; 38 import java.util.Set ; 39 import java.util.zip.ZipEntry ; 40 import java.util.zip.ZipFile ; 41 42 import javax.management.Attribute ; 43 import javax.management.MBeanServer ; 44 import javax.management.ObjectName ; 45 import javax.naming.Context ; 46 import javax.naming.InitialContext ; 47 48 import org.apache.catalina.Loader; 49 import org.apache.tomcat.util.modeler.Registry; 50 import org.jboss.deployers.spi.deployer.DeploymentUnit; 51 import org.jboss.logging.Logger; 52 import org.jboss.metadata.WebMetaData; 53 import org.jboss.mx.util.MBeanServerLocator; 54 import org.jboss.security.AuthorizationManager; 55 import org.jboss.security.authorization.PolicyRegistration; 56 import org.jboss.virtual.VirtualFile; 57 import org.jboss.web.WebApplication; 58 import org.jboss.web.deployers.AbstractWarDeployment; 59 import org.jboss.web.tomcat.security.JaccContextValve; 60 import org.jboss.web.tomcat.security.RunAsListener; 61 import org.jboss.web.tomcat.security.SecurityAssociationValve; 62 import org.jboss.web.tomcat.tc6.TomcatInjectionContainer; 63 import org.jboss.web.tomcat.tc6.WebAppLoader; 64 import org.jboss.web.tomcat.tc6.WebCtxLoader; 65 import org.jboss.web.tomcat.tc6.session.AbstractJBossManager; 66 import org.jboss.web.tomcat.tc6.session.ClusteringNotSupportedException; 67 import org.jboss.web.tomcat.tc6.session.JBossCacheManager; 68 import org.omg.CORBA.ORB ; 69 70 77 public class TomcatDeployment extends AbstractWarDeployment 78 { 79 private static final Logger log = Logger.getLogger(TomcatDeployment.class); 80 81 84 private static final String CONTEXT_CONFIG_FILE = "WEB-INF/context.xml"; 85 86 private DeployerConfig config; 87 private String [] javaVMs = { " jboss.management.local:J2EEServer=Local,j2eeType=JVM,name=localhost" }; 88 private String serverName = "jboss"; 89 private HashMap vhostToHostNames = new HashMap (); 90 private ORB orb = null; 91 private TomcatInjectionContainer injectionContainer; 92 93 public ORB getORB() 94 { 95 return orb; 96 } 97 public void setORB(ORB orb) 98 { 99 this.orb = orb; 100 } 101 102 @Override 103 public void init(Object containerConfig) throws Exception 104 { 105 this.config = (DeployerConfig)containerConfig; 106 super.setJava2ClassLoadingCompliance(config.isJava2ClassLoadingCompliance()); 107 super.setUnpackWars(config.isUnpackWars()); 108 super.setLenientEjbLink(config.isLenientEjbLink()); 109 super.setDefaultSecurityDomain(config.getDefaultSecurityDomain()); 110 } 111 112 @Override 113 protected void performDeploy(WebApplication webApp, String warUrl) 114 throws Exception 115 { 116 warUrl = URLDecoder.decode(warUrl, "UTF-8"); 118 webApp.setDomain(config.getCatalinaDomain()); 119 WebMetaData metaData = webApp.getMetaData(); 120 String hostName = null; 121 Iterator vhostNames = metaData.getVirtualHosts(); 123 Iterator hostNames = mapVirtualHosts(vhostNames); 125 if (hostNames.hasNext()) 126 { 127 hostName = hostNames.next().toString(); 128 } 129 performDeployInternal(hostName, webApp, warUrl); 130 while (hostNames.hasNext()) 131 { 132 String additionalHostName = hostNames.next().toString(); 133 performDeployInternal(additionalHostName, webApp, warUrl); 134 } 135 } 136 137 protected void performDeployInternal(String hostName, 138 WebApplication webApp, String warUrl) throws Exception 139 { 140 141 WebMetaData metaData = webApp.getMetaData(); 142 String ctxPath = metaData.getContextRoot(); 143 if (ctxPath.equals("/") || ctxPath.equals("/ROOT") || ctxPath.equals("")) 144 { 145 log.debug("deploy root context=" + ctxPath); 146 ctxPath = "/"; 147 metaData.setContextRoot(ctxPath); 148 } 149 150 log.info("deploy, ctxPath=" + ctxPath + ", warUrl=" 151 + shortWarUrlFromServerHome(warUrl)); 152 153 URL url = new URL (warUrl); 154 155 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 156 metaData.setContextLoader(loader); 157 158 injectionContainer = new TomcatInjectionContainer(webApp, webApp.getDeploymentUnit()); 159 160 Loader webLoader = webApp.getDeploymentUnit().getAttachment(Loader.class); 161 if( webLoader == null ) 162 webLoader = getWebLoader(webApp.getDeploymentUnit(), loader, url); 163 164 webApp.setName(url.getPath()); 165 webApp.setClassLoader(loader); 166 webApp.setURL(url); 167 168 String objectNameS = config.getCatalinaDomain() + ":j2eeType=WebModule,name=//" 169 + ((hostName == null) ? "localhost" : hostName) + ctxPath 170 + ",J2EEApplication=none,J2EEServer=none"; 171 172 ObjectName objectName = new ObjectName (objectNameS); 173 174 String contextClassName = config.getContextClassName(); 175 Registry.getRegistry().registerComponent( 176 Class.forName(contextClassName).newInstance(), objectName, 177 contextClassName); 178 179 String ctxConfig = null; 182 try 183 { 184 ctxConfig = findConfig(url); 186 } catch (IOException e) 187 { 188 log.debug("No " + CONTEXT_CONFIG_FILE + " in " + url, e); 189 } 190 191 if (injectionContainer != null) 192 { 193 server.setAttribute(objectName, new Attribute ("annotationProcessor", injectionContainer)); 194 } 195 196 server.setAttribute(objectName, new Attribute ("docBase", url.getFile())); 197 198 server.setAttribute(objectName, new Attribute ("configFile", ctxConfig)); 199 200 server.setAttribute(objectName, new Attribute ("defaultContextXml", 201 "context.xml")); 202 server.setAttribute(objectName, new Attribute ("defaultWebXml", 203 "conf/web.xml")); 204 if( metaData.getAltDDPath() != null ) 206 { 207 String altPath = metaData.getAltDDPath(); 208 log.debug("Setting altDDName to: "+altPath); 209 server.setAttribute(objectName, new Attribute ("altDDName", altPath)); 210 } 211 212 server.setAttribute(objectName, new Attribute ("javaVMs", javaVMs)); 213 214 server.setAttribute(objectName, new Attribute ("server", serverName)); 215 216 server.setAttribute(objectName, 217 new Attribute ("saveConfig", Boolean.FALSE)); 218 219 if (webLoader != null) 220 { 221 server.setAttribute(objectName, new Attribute ("loader", webLoader)); 222 } else 223 { 224 server.setAttribute(objectName, new Attribute ("parentClassLoader", 225 loader)); 226 } 227 228 server.setAttribute(objectName, new Attribute ("delegate", new Boolean ( 229 webApp.getJava2ClassLoadingCompliance()))); 230 231 String [] jspCP = getCompileClasspath(loader); 232 StringBuffer classpath = new StringBuffer (); 233 for (int u = 0; u < jspCP.length; u++) 234 { 235 String repository = jspCP[u]; 236 if (repository == null) 237 continue; 238 if (repository.startsWith("file://")) 239 repository = repository.substring(7); 240 else if (repository.startsWith("file:")) 241 repository = repository.substring(5); 242 else 243 continue; 244 if (repository == null) 245 continue; 246 File fp = new File (repository); 248 if (!fp.isDirectory()) 249 { 250 try 252 { 253 if (fp.getName().toLowerCase().endsWith(".xml")) 255 continue; 256 257 ZipFile zip = new ZipFile (fp); 258 zip.close(); 259 } catch (IOException e) 260 { 261 continue; 262 } 263 264 } 265 if (u > 0) 266 classpath.append(File.pathSeparator); 267 classpath.append(repository); 268 } 269 270 server.setAttribute(objectName, new Attribute ("compilerClasspath", 271 classpath.toString())); 272 273 switch (metaData.getSessionCookies()) 275 { 276 case WebMetaData.SESSION_COOKIES_ENABLED: 277 server.setAttribute(objectName, new Attribute ("cookies", new Boolean ( 278 true))); 279 log.debug("Enabling session cookies"); 280 break; 281 case WebMetaData.SESSION_COOKIES_DISABLED: 282 server.setAttribute(objectName, new Attribute ("cookies", new Boolean ( 283 false))); 284 log.debug("Disabling session cookies"); 285 break; 286 default: 287 log.debug("Using session cookies default setting"); 288 } 289 290 Certificate [] certs = null; 292 CodeSource cs = new CodeSource (url, certs); 293 JaccContextValve jaccValve = new JaccContextValve(metaData, cs); 294 server.invoke(objectName, "addValve", new Object [] { jaccValve }, 295 new String [] { "org.apache.catalina.Valve" }); 296 297 RunAsListener.metaDataLocal.set(metaData); 299 try 300 { 301 server.invoke(objectName, "init", new Object [] {}, new String [] {}); 303 } 304 finally 305 { 306 RunAsListener.metaDataLocal.set(null); 307 } 308 309 Loader ctxLoader = (Loader) server.getAttribute(objectName, "loader"); 312 metaData.setContextLoader(ctxLoader.getClassLoader()); 313 314 server.invoke(objectName, "start", new Object []{}, 316 new String []{}); 317 319 if (injectionContainer == null) 320 super.processEnc(webLoader.getClassLoader(), webApp); 321 else 322 { 323 Thread currentThread = Thread.currentThread(); 324 ClassLoader currentLoader = loader; 325 try 326 { 327 log.debug("Creating ENC using ClassLoader: " + loader); 329 ClassLoader parent = loader.getParent(); 330 while (parent != null) 331 { 332 log.debug(".." + parent); 333 parent = parent.getParent(); 334 } 335 currentThread.setContextClassLoader(webLoader.getClassLoader()); 337 metaData.setENCLoader(webLoader.getClassLoader()); 338 InitialContext iniCtx = new InitialContext (); 339 Context envCtx = (Context ) iniCtx.lookup("java:comp"); 340 envCtx = envCtx.createSubcontext("env"); 341 injectionContainer.populateEnc(webLoader.getClassLoader()); 342 currentThread.setContextClassLoader(webLoader.getClassLoader()); 344 String securityDomain = metaData.getSecurityDomain(); 345 log.debug("linkSecurityDomain"); 346 linkSecurityDomain(securityDomain, envCtx); 347 } 348 finally 349 { 350 currentThread.setContextClassLoader(currentLoader); 351 } 352 } 353 354 if (metaData.getDistributable()) 356 { 357 try 360 { 361 AbstractJBossManager manager = null; 362 String managerClassName = config.getManagerClass(); 363 Class managerClass = Thread.currentThread().getContextClassLoader() 364 .loadClass(managerClassName); 365 manager = (AbstractJBossManager) managerClass.newInstance(); 366 String name = "//" + ((hostName == null) ? "localhost" : hostName) 367 + ctxPath; 368 manager.init(name, metaData, config.isUseJK(), config 369 .isUseLocalCache()); 370 371 if (manager instanceof JBossCacheManager) 372 { 373 String snapshotMode = config.getSnapshotMode(); 374 int snapshotInterval = config.getSnapshotInterval(); 375 JBossCacheManager jbcm = (JBossCacheManager) manager; 376 jbcm.setSnapshotMode(snapshotMode); 377 jbcm.setSnapshotInterval(snapshotInterval); 378 } 379 380 server.setAttribute(objectName, new Attribute ("manager", manager)); 381 382 log.debug("Enabled clustering support for ctxPath=" + ctxPath); 383 } 384 catch (ClusteringNotSupportedException e) 385 { 386 log.warn("Failed to setup clustering, clustering disabled. ClusteringNotSupportedException: " 388 + e.getMessage()); 389 } 390 catch (NoClassDefFoundError ncdf) 391 { 392 log.debug("Classes needed for clustered webapp unavailable", ncdf); 394 log.warn("Failed to setup clustering, clustering disabled. NoClassDefFoundError: " 395 + ncdf.getMessage()); 396 } 397 catch (Throwable t) 398 { 399 log.error("Failed to setup clustering, clustering disabled. Exception: ", t); 401 } 402 } 403 404 409 SecurityAssociationValve valve = new SecurityAssociationValve(metaData, 410 config.getSecurityManagerService()); 411 valve.setSubjectAttributeName(config.getSubjectAttributeName()); 412 server.invoke(objectName, "addValve", new Object [] { valve }, 413 new String [] { "org.apache.catalina.Valve" }); 414 415 422 423 webApp.setAppData(objectName); 424 425 433 434 if (metaData.getSecurityDomain() != null) 435 { 436 String secDomain = org.jboss.security.Util 437 .unprefixSecurityDomain(metaData.getSecurityDomain()); 438 String contextID = metaData.getJaccContextID(); 440 441 URL xacmlPolicyFile = this.config.getXacmlPolicyURL(); 443 if (xacmlPolicyFile != null) 444 { 445 AuthorizationManager authzmgr = org.jboss.security.Util 446 .getAuthorizationManager(secDomain); 447 if (authzmgr instanceof PolicyRegistration) 448 { 449 PolicyRegistration xam = (PolicyRegistration) authzmgr; 450 xam.registerPolicy(contextID, xacmlPolicyFile); 451 } 452 } 453 } 454 455 log.debug("Initialized: " + webApp + " " + objectName); 456 } 457 458 public Loader getWebLoader(DeploymentUnit unit, ClassLoader loader, URL url) 459 throws MalformedURLException 460 { 461 Loader webLoader = null; 462 463 469 ArrayList <URL > classpath = (ArrayList <URL >) unit.getAttachment("org.jboss.web.expandedWarClasspath"); 470 if (config.isUseJBossWebLoader()) 471 { 472 WebCtxLoader jbossLoader = new WebCtxLoader(loader, injectionContainer); 473 if( classpath != null ) 474 jbossLoader.setClasspath(classpath); 475 webLoader = jbossLoader; 476 } 477 else 478 { 479 String [] pkgs = config.getFilteredPackages(); 480 WebAppLoader jbossLoader = new WebAppLoader(loader, pkgs, injectionContainer); 481 jbossLoader.setDelegate(getJava2ClassLoadingCompliance()); 482 if( classpath != null ) 483 jbossLoader.setClasspath(classpath); 484 webLoader = jbossLoader; 485 } 486 return webLoader; 487 } 488 489 public void setInjectionContainer(TomcatInjectionContainer container) 490 { 491 this.injectionContainer = container; 492 } 493 494 498 protected void performUndeploy(WebApplication warInfo, String warUrl) 499 throws Exception 500 { 501 if (warInfo == null) 502 { 503 log.debug("performUndeploy, no WebApplication found for URL "+ warUrl); 504 return; 505 } 506 507 log.info("undeploy, ctxPath=" + warInfo.getMetaData().getContextRoot() 508 + ", warUrl=" + shortWarUrlFromServerHome(warUrl)); 509 510 WebMetaData metaData = warInfo.getMetaData(); 511 String hostName = null; 512 Iterator hostNames = metaData.getVirtualHosts(); 513 if (hostNames.hasNext()) 514 { 515 hostName = hostNames.next().toString(); 516 } 517 performUndeployInternal(hostName, warUrl, warInfo); 518 while (hostNames.hasNext()) 519 { 520 String additionalHostName = hostNames.next().toString(); 521 performUndeployInternal(additionalHostName, warUrl, warInfo); 522 } 523 524 } 525 526 protected void performUndeployInternal(String hostName, String warUrl, 527 WebApplication warInfo) throws Exception 528 { 529 530 WebMetaData metaData = warInfo.getMetaData(); 531 String ctxPath = metaData.getContextRoot(); 532 533 MBeanServer server = MBeanServerLocator.locateJBoss(); 535 if (server == null) 537 return; 538 539 ObjectName objectName = new ObjectName (config.getCatalinaDomain() 540 + ":j2eeType=WebModule,name=//" 541 + ((hostName == null) ? "localhost" : hostName) + ctxPath 542 + ",J2EEApplication=none,J2EEServer=none"); 543 544 if (server.isRegistered(objectName)) 545 { 546 server.invoke(objectName, "destroy", new Object [] {}, new String [] {}); 548 } 549 550 } 551 552 558 protected synchronized Iterator mapVirtualHosts(Iterator vhostNames) 559 throws Exception 560 { 561 if (vhostToHostNames.size() == 0) 562 { 563 String hostQuery = config.getCatalinaDomain() + ":type=Host,*"; 565 ObjectName query = new ObjectName (hostQuery); 566 Set hosts = server.queryNames(query, null); 567 Iterator iter = hosts.iterator(); 568 while (iter.hasNext()) 569 { 570 ObjectName host = (ObjectName )iter.next(); 571 String name = host.getKeyProperty("host"); 572 if (name != null) 573 { 574 vhostToHostNames.put(name, name); 575 String [] aliases = (String []) 576 server.invoke(host, "findAliases", null, null); 577 int count = aliases != null ? aliases.length : 0; 578 for (int n = 0; n < count; n++) 579 { 580 vhostToHostNames.put(aliases[n], name); 581 } 582 } 583 } 584 } 585 586 HashSet hosts = new HashSet (); 588 while (vhostNames.hasNext()) 589 { 590 String vhost = (String )vhostNames.next(); 591 String host = (String )vhostToHostNames.get(vhost); 592 if (host == null) 593 { 594 log.warn("Failed to map vhost: " + vhost); 595 host = vhost; 597 } 598 hosts.add(host); 599 } 600 return hosts.iterator(); 601 } 602 603 private String findConfig(URL warURL) throws IOException 604 { 605 String result = null; 606 File warFile = new File (warURL.getFile()); 608 if (warURL.getProtocol().equals("file") && warFile.isDirectory() == true) 609 { 610 File webDD = new File (warFile, CONTEXT_CONFIG_FILE); 611 if (webDD.exists() == true) 612 result = webDD.getAbsolutePath(); 613 } else 614 { 615 ZipFile zipFile = new ZipFile (warFile); 616 ZipEntry entry = zipFile.getEntry(CONTEXT_CONFIG_FILE); 617 if (entry != null) 618 { 619 InputStream zipIS = zipFile.getInputStream(entry); 620 byte[] buffer = new byte[512]; 621 int bytes; 622 result = warFile.getAbsolutePath() + "-context.xml"; 623 FileOutputStream fos = new FileOutputStream (result); 624 while ((bytes = zipIS.read(buffer)) > 0) 625 { 626 fos.write(buffer, 0, bytes); 627 } 628 zipIS.close(); 629 fos.close(); 630 } 631 zipFile.close(); 632 } 633 return result; 634 } 635 636 } 637 | Popular Tags |