1 18 package org.apache.tools.ant.taskdefs.optional.ejb; 19 20 import java.io.File ; 21 import java.io.FileOutputStream ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.util.Enumeration ; 25 import java.util.Hashtable ; 26 import java.util.Iterator ; 27 import java.util.jar.JarEntry ; 28 import java.util.jar.JarFile ; 29 import java.util.jar.JarOutputStream ; 30 import org.apache.tools.ant.BuildException; 31 import org.apache.tools.ant.Project; 32 import org.apache.tools.ant.taskdefs.Java; 33 import org.apache.tools.ant.types.Environment; 34 import org.apache.tools.ant.types.Path; 35 import org.apache.tools.ant.util.FileUtils; 36 37 61 public class WebsphereDeploymentTool extends GenericDeploymentTool { 62 63 64 public static final String PUBLICID_EJB11 65 = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN"; 66 67 public static final String PUBLICID_EJB20 68 = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"; 69 70 protected static final String SCHEMA_DIR = "Schema/"; 71 72 protected static final String WAS_EXT = "ibm-ejb-jar-ext.xmi"; 73 protected static final String WAS_BND = "ibm-ejb-jar-bnd.xmi"; 74 protected static final String WAS_CMP_MAP = "Map.mapxmi"; 75 protected static final String WAS_CMP_SCHEMA = "Schema.dbxmi"; 76 77 private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 78 79 80 private String jarSuffix = ".jar"; 81 82 83 private String ejb11DTD; 84 85 86 87 private boolean keepGeneric = false; 88 89 private boolean alwaysRebuild = true; 90 91 private boolean ejbdeploy = true; 92 93 94 private boolean newCMP = false; 95 96 97 private Path wasClasspath = null; 98 99 100 private String dbVendor; 101 102 103 private String dbName; 104 105 106 private String dbSchema; 107 108 109 private boolean codegen; 110 111 112 private boolean quiet = true; 113 114 115 private boolean novalidate; 116 117 118 private boolean nowarn; 119 120 121 private boolean noinform; 122 123 124 private boolean trace; 125 126 127 private String rmicOptions; 128 129 130 private boolean use35MappingRules; 131 132 133 private String tempdir = "_ejbdeploy_temp"; 134 135 136 private File websphereHome; 137 138 142 public Path createWASClasspath() { 143 if (wasClasspath == null) { 144 wasClasspath = new Path(getTask().getProject()); 145 } 146 return wasClasspath.createPath(); 147 } 148 149 150 154 public void setWASClasspath(Path wasClasspath) { 155 this.wasClasspath = wasClasspath; 156 } 157 158 159 174 public void setDbvendor(String dbvendor) { 175 this.dbVendor = dbvendor; 176 } 177 178 179 184 public void setDbname(String dbName) { 185 this.dbName = dbName; 186 } 187 188 189 194 public void setDbschema(String dbSchema) { 195 this.dbSchema = dbSchema; 196 } 197 198 199 205 public void setCodegen(boolean codegen) { 206 this.codegen = codegen; 207 } 208 209 210 215 public void setQuiet(boolean quiet) { 216 this.quiet = quiet; 217 } 218 219 220 225 public void setNovalidate(boolean novalidate) { 226 this.novalidate = novalidate; 227 } 228 229 230 235 public void setNowarn(boolean nowarn) { 236 this.nowarn = nowarn; 237 } 238 239 240 245 public void setNoinform(boolean noinform) { 246 this.noinform = noinform; 247 } 248 249 250 255 public void setTrace(boolean trace) { 256 this.trace = trace; 257 } 258 259 264 public void setRmicoptions(String options) { 265 this.rmicOptions = options; 266 } 267 268 273 public void setUse35(boolean attr) { 274 use35MappingRules = attr; 275 } 276 277 278 283 public void setRebuild(boolean rebuild) { 284 this.alwaysRebuild = rebuild; 285 } 286 287 288 294 public void setSuffix(String inString) { 295 this.jarSuffix = inString; 296 } 297 298 299 304 public void setKeepgeneric(boolean inValue) { 305 this.keepGeneric = inValue; 306 } 307 308 309 315 public void setEjbdeploy(boolean ejbdeploy) { 316 this.ejbdeploy = ejbdeploy; 317 } 318 319 320 326 public void setEJBdtd(String inString) { 327 this.ejb11DTD = inString; 328 } 329 330 331 336 public void setOldCMP(boolean oldCMP) { 337 this.newCMP = !oldCMP; 338 } 339 340 341 350 public void setNewCMP(boolean newCMP) { 351 this.newCMP = newCMP; 352 } 353 354 355 360 public void setTempdir(String tempdir) { 361 this.tempdir = tempdir; 362 } 363 364 365 366 protected DescriptorHandler getDescriptorHandler(File srcDir) { 367 DescriptorHandler handler = new DescriptorHandler(getTask(), srcDir); 368 handler.registerDTD(PUBLICID_EJB11, ejb11DTD); 371 372 for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) { 373 EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next(); 374 375 handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation()); 376 } 377 378 return handler; 379 } 380 381 382 387 protected DescriptorHandler getWebsphereDescriptorHandler(final File srcDir) { 388 DescriptorHandler handler = 389 new DescriptorHandler(getTask(), srcDir) { 390 protected void processElement() { 391 } 392 }; 393 394 for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) { 395 EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next(); 396 397 handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation()); 398 } 399 return handler; 400 } 401 402 403 408 protected void addVendorFiles(Hashtable ejbFiles, String baseName) { 409 410 String ddPrefix = (usingBaseJarName() ? "" : baseName); 411 String dbPrefix = (dbVendor == null) ? "" : dbVendor + "-"; 412 413 File websphereEXT = new File (getConfig().descriptorDir, ddPrefix + WAS_EXT); 415 416 if (websphereEXT.exists()) { 417 ejbFiles.put(META_DIR + WAS_EXT, 418 websphereEXT); 419 } else { 420 log("Unable to locate websphere extensions. " 421 + "It was expected to be in " 422 + websphereEXT.getPath(), Project.MSG_VERBOSE); 423 } 424 425 File websphereBND = new File (getConfig().descriptorDir, ddPrefix + WAS_BND); 426 427 if (websphereBND.exists()) { 428 ejbFiles.put(META_DIR + WAS_BND, 429 websphereBND); 430 } else { 431 log("Unable to locate websphere bindings. " 432 + "It was expected to be in " 433 + websphereBND.getPath(), Project.MSG_VERBOSE); 434 } 435 436 if (!newCMP) { 437 log("The old method for locating CMP files has been DEPRECATED.", 438 Project.MSG_VERBOSE); 439 log("Please adjust your websphere descriptor and set " 440 + "newCMP=\"true\" to use the new CMP descriptor " 441 + "inclusion mechanism. ", Project.MSG_VERBOSE); 442 } else { 443 try { 445 File websphereMAP = new File (getConfig().descriptorDir, 447 ddPrefix + dbPrefix + WAS_CMP_MAP); 448 449 if (websphereMAP.exists()) { 450 ejbFiles.put(META_DIR + WAS_CMP_MAP, 451 websphereMAP); 452 } else { 453 log("Unable to locate the websphere Map: " 454 + websphereMAP.getPath(), Project.MSG_VERBOSE); 455 } 456 457 File websphereSchema = new File (getConfig().descriptorDir, 458 ddPrefix + dbPrefix + WAS_CMP_SCHEMA); 459 460 if (websphereSchema.exists()) { 461 ejbFiles.put(META_DIR + SCHEMA_DIR + WAS_CMP_SCHEMA, 462 websphereSchema); 463 } else { 464 log("Unable to locate the websphere Schema: " 465 + websphereSchema.getPath(), Project.MSG_VERBOSE); 466 } 467 } catch (Exception e) { 469 String msg = "Exception while adding Vendor specific files: " 470 + e.toString(); 471 472 throw new BuildException(msg, e); 473 } 474 } 475 } 476 477 478 483 File getVendorOutputJarFile(String baseName) { 484 return new File (getDestDir(), baseName + jarSuffix); 485 } 486 487 488 493 protected String getOptions() { 494 StringBuffer options = new StringBuffer (); 496 497 if (dbVendor != null) { 498 options.append(" -dbvendor ").append(dbVendor); 499 } 500 if (dbName != null) { 501 options.append(" -dbname \"").append(dbName).append("\""); 502 } 503 504 if (dbSchema != null) { 505 options.append(" -dbschema \"").append(dbSchema).append("\""); 506 } 507 508 if (codegen) { 509 options.append(" -codegen"); 510 } 511 512 if (quiet) { 513 options.append(" -quiet"); 514 } 515 516 if (novalidate) { 517 options.append(" -novalidate"); 518 } 519 520 if (nowarn) { 521 options.append(" -nowarn"); 522 } 523 524 if (noinform) { 525 options.append(" -noinform"); 526 } 527 528 if (trace) { 529 options.append(" -trace"); 530 } 531 532 if (use35MappingRules) { 533 options.append(" -35"); 534 } 535 536 if (rmicOptions != null) { 537 options.append(" -rmic \"").append(rmicOptions).append("\""); 538 } 539 540 return options.toString(); 541 } 542 543 544 553 private void buildWebsphereJar(File sourceJar, File destJar) { 554 try { 555 if (ejbdeploy) { 556 Java javaTask = new Java(getTask()); 557 javaTask.createJvmarg().setValue("-Xms64m"); 559 javaTask.createJvmarg().setValue("-Xmx128m"); 560 561 Environment.Variable var = new Environment.Variable(); 563 564 var.setKey("websphere.lib.dir"); 565 File libdir = new File (websphereHome, "lib"); 566 var.setValue(libdir.getAbsolutePath()); 567 javaTask.addSysproperty(var); 568 569 javaTask.setDir(websphereHome); 571 572 javaTask.setTaskName("ejbdeploy"); 574 javaTask.setClassname("com.ibm.etools.ejbdeploy.EJBDeploy"); 575 576 javaTask.createArg().setValue(sourceJar.getPath()); 577 javaTask.createArg().setValue(tempdir); 578 javaTask.createArg().setValue(destJar.getPath()); 579 javaTask.createArg().setLine(getOptions()); 580 if (getCombinedClasspath() != null 581 && getCombinedClasspath().toString().length() > 0) { 582 javaTask.createArg().setValue("-cp"); 583 javaTask.createArg().setValue(getCombinedClasspath().toString()); 584 } 585 586 Path classpath = wasClasspath; 587 588 if (classpath == null) { 589 classpath = getCombinedClasspath(); 590 } 591 592 if (classpath != null) { 593 javaTask.setClasspath(classpath); 594 javaTask.setFork(true); 595 } else { 596 javaTask.setFork(true); 597 } 598 599 log("Calling websphere.ejbdeploy for " + sourceJar.toString(), 600 Project.MSG_VERBOSE); 601 602 javaTask.execute(); 603 } 604 } catch (Exception e) { 605 String msg = "Exception while calling ejbdeploy. Details: " + e.toString(); 607 608 throw new BuildException(msg, e); 609 } 610 } 611 612 613 protected void writeJar(String baseName, File jarFile, Hashtable files, String publicId) 614 throws BuildException { 615 if (ejbdeploy) { 616 File genericJarFile = super.getVendorOutputJarFile(baseName); 618 619 super.writeJar(baseName, genericJarFile, files, publicId); 620 621 if (alwaysRebuild || isRebuildRequired(genericJarFile, jarFile)) { 623 buildWebsphereJar(genericJarFile, jarFile); 624 } 625 if (!keepGeneric) { 626 log("deleting generic jar " + genericJarFile.toString(), 627 Project.MSG_VERBOSE); 628 genericJarFile.delete(); 629 } 630 } else { 631 super.writeJar(baseName, jarFile, files, publicId); 633 } 634 } 635 636 637 641 public void validateConfigured() throws BuildException { 642 super.validateConfigured(); 643 if (ejbdeploy) { 644 String home = getTask().getProject().getProperty("websphere.home"); 645 if (home == null) { 646 throw new BuildException("The 'websphere.home' property must " 647 + "be set when 'ejbdeploy=true'"); 648 } 649 websphereHome = getTask().getProject().resolveFile(home); 650 } 651 } 652 653 654 679 protected boolean isRebuildRequired(File genericJarFile, File websphereJarFile) { 680 boolean rebuild = false; 681 682 JarFile genericJar = null; 683 JarFile wasJar = null; 684 File newwasJarFile = null; 685 JarOutputStream newJarStream = null; 686 687 try { 688 log("Checking if websphere Jar needs to be rebuilt for jar " 689 + websphereJarFile.getName(), Project.MSG_VERBOSE); 690 if (genericJarFile.exists() && genericJarFile.isFile() 692 && websphereJarFile.exists() && websphereJarFile.isFile()) { 693 genericJar = new JarFile (genericJarFile); 695 wasJar = new JarFile (websphereJarFile); 696 697 Hashtable genericEntries = new Hashtable (); 698 Hashtable wasEntries = new Hashtable (); 699 Hashtable replaceEntries = new Hashtable (); 700 701 for (Enumeration e = genericJar.entries(); e.hasMoreElements();) { 703 JarEntry je = (JarEntry ) e.nextElement(); 704 705 genericEntries.put(je.getName().replace('\\', '/'), je); 706 } 707 for (Enumeration e = wasJar.entries(); e.hasMoreElements();) { 709 JarEntry je = (JarEntry ) e.nextElement(); 710 711 wasEntries.put(je.getName(), je); 712 } 713 714 ClassLoader genericLoader = getClassLoaderFromJar(genericJarFile); 716 717 for (Enumeration e = genericEntries.keys(); e.hasMoreElements();) { 718 String filepath = (String ) e.nextElement(); 719 720 if (wasEntries.containsKey(filepath)) { 721 JarEntry genericEntry = (JarEntry ) genericEntries.get(filepath); 724 JarEntry wasEntry = (JarEntry ) wasEntries.get(filepath); 725 726 if ((genericEntry.getCrc() != wasEntry.getCrc()) 727 || (genericEntry.getSize() != wasEntry.getSize())) { 728 729 if (genericEntry.getName().endsWith(".class")) { 730 String classname 732 = genericEntry.getName().replace(File.separatorChar, '.'); 733 734 classname = classname.substring(0, classname.lastIndexOf(".class")); 735 736 Class genclass = genericLoader.loadClass(classname); 737 738 if (genclass.isInterface()) { 739 log("Interface " + genclass.getName() 741 + " has changed", Project.MSG_VERBOSE); 742 rebuild = true; 743 break; 744 } else { 745 replaceEntries.put(filepath, genericEntry); 747 } 748 } else { 749 if (!genericEntry.getName().equals("META-INF/MANIFEST.MF")) { 751 log("Non class file " + genericEntry.getName() 753 + " has changed", Project.MSG_VERBOSE); 754 rebuild = true; 755 } 756 break; 757 } 758 } 759 } else { 760 762 log("File " + filepath + " not present in websphere jar", 763 Project.MSG_VERBOSE); 764 rebuild = true; 765 break; 766 } 767 } 768 769 if (!rebuild) { 770 log("No rebuild needed - updating jar", Project.MSG_VERBOSE); 771 newwasJarFile = new File (websphereJarFile.getAbsolutePath() + ".temp"); 772 if (newwasJarFile.exists()) { 773 newwasJarFile.delete(); 774 } 775 776 newJarStream = new JarOutputStream (new FileOutputStream (newwasJarFile)); 777 newJarStream.setLevel(0); 778 779 for (Enumeration e = wasEntries.elements(); e.hasMoreElements();) { 781 byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; 782 int bytesRead; 783 InputStream is; 784 JarEntry je = (JarEntry ) e.nextElement(); 785 786 if (je.getCompressedSize() == -1 787 || je.getCompressedSize() == je.getSize()) { 788 newJarStream.setLevel(0); 789 } else { 790 newJarStream.setLevel(JAR_COMPRESS_LEVEL); 791 } 792 793 if (replaceEntries.containsKey(je.getName())) { 795 log("Updating Bean class from generic Jar " + je.getName(), 796 Project.MSG_VERBOSE); 797 je = (JarEntry ) replaceEntries.get(je.getName()); 799 is = genericJar.getInputStream(je); 800 } else { 801 803 is = wasJar.getInputStream(je); 804 } 805 newJarStream.putNextEntry(new JarEntry (je.getName())); 806 807 while ((bytesRead = is.read(buffer)) != -1) { 808 newJarStream.write(buffer, 0, bytesRead); 809 } 810 is.close(); 811 } 812 } else { 813 log("websphere Jar rebuild needed due to changed " 814 + "interface or XML", Project.MSG_VERBOSE); 815 } 816 } else { 817 rebuild = true; 818 } 819 } catch (ClassNotFoundException cnfe) { 820 String cnfmsg = "ClassNotFoundException while processing ejb-jar file" 821 + ". Details: " 822 + cnfe.getMessage(); 823 824 throw new BuildException(cnfmsg, cnfe); 825 } catch (IOException ioe) { 826 String msg = "IOException while processing ejb-jar file " 827 + ". Details: " 828 + ioe.getMessage(); 829 830 throw new BuildException(msg, ioe); 831 } finally { 832 if (genericJar != null) { 834 try { 835 genericJar.close(); 836 } catch (IOException closeException) { 837 } 839 } 840 841 if (wasJar != null) { 842 try { 843 wasJar.close(); 844 } catch (IOException closeException) { 845 } 847 } 848 849 if (newJarStream != null) { 850 try { 851 newJarStream.close(); 852 } catch (IOException closeException) { 853 } 855 856 try { 857 FILE_UTILS.rename(newwasJarFile, websphereJarFile); 858 } catch (IOException renameException) { 859 log(renameException.getMessage(), Project.MSG_WARN); 860 rebuild = true; 861 } 862 } 863 } 864 865 return rebuild; 866 } 867 868 869 877 protected ClassLoader getClassLoaderFromJar(File classjar) throws IOException { 878 Path lookupPath = new Path(getTask().getProject()); 879 880 lookupPath.setLocation(classjar); 881 882 Path classpath = getCombinedClasspath(); 883 884 if (classpath != null) { 885 lookupPath.append(classpath); 886 } 887 888 return getTask().getProject().createClassLoader(lookupPath); 889 } 890 } 891 892 | Popular Tags |