1 18 package org.apache.tools.ant.taskdefs.optional.ejb; 19 20 import java.io.File ; 21 import java.io.FileInputStream ; 22 import java.io.FileOutputStream ; 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 import java.util.Enumeration ; 26 import java.util.Hashtable ; 27 import java.util.Iterator ; 28 import java.util.Vector ; 29 import java.util.jar.JarEntry ; 30 import java.util.jar.JarFile ; 31 import java.util.jar.JarOutputStream ; 32 import javax.xml.parsers.SAXParser ; 33 import javax.xml.parsers.SAXParserFactory ; 34 import org.apache.tools.ant.AntClassLoader; 35 import org.apache.tools.ant.BuildException; 36 import org.apache.tools.ant.Project; 37 import org.apache.tools.ant.taskdefs.Java; 38 import org.apache.tools.ant.types.Environment; 39 import org.apache.tools.ant.types.Path; 40 import org.apache.tools.ant.util.FileUtils; 41 import org.xml.sax.InputSource ; 42 43 54 public class WeblogicDeploymentTool extends GenericDeploymentTool { 55 56 public static final String PUBLICID_EJB11 57 = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN"; 58 59 public static final String PUBLICID_EJB20 60 = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"; 61 62 public static final String PUBLICID_WEBLOGIC_EJB510 63 = "-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN"; 64 65 public static final String PUBLICID_WEBLOGIC_EJB600 66 = "-//BEA Systems, Inc.//DTD WebLogic 6.0.0 EJB//EN"; 67 68 public static final String PUBLICID_WEBLOGIC_EJB700 69 = "-//BEA Systems, Inc.//DTD WebLogic 7.0.0 EJB//EN"; 70 71 72 protected static final String DEFAULT_WL51_EJB11_DTD_LOCATION 73 = "/weblogic/ejb/deployment/xml/ejb-jar.dtd"; 74 75 protected static final String DEFAULT_WL60_EJB11_DTD_LOCATION 76 = "/weblogic/ejb20/dd/xml/ejb11-jar.dtd"; 77 78 protected static final String DEFAULT_WL60_EJB20_DTD_LOCATION 79 = "/weblogic/ejb20/dd/xml/ejb20-jar.dtd"; 80 81 protected static final String DEFAULT_WL51_DTD_LOCATION 82 = "/weblogic/ejb/deployment/xml/weblogic-ejb-jar.dtd"; 83 protected static final String DEFAULT_WL60_51_DTD_LOCATION 84 = "/weblogic/ejb20/dd/xml/weblogic510-ejb-jar.dtd"; 85 protected static final String DEFAULT_WL60_DTD_LOCATION 86 = "/weblogic/ejb20/dd/xml/weblogic600-ejb-jar.dtd"; 87 protected static final String DEFAULT_WL70_DTD_LOCATION 88 = "/weblogic/ejb20/dd/xml/weblogic700-ejb-jar.dtd"; 89 90 protected static final String DEFAULT_COMPILER = "default"; 91 92 protected static final String WL_DD = "weblogic-ejb-jar.xml"; 93 protected static final String WL_CMP_DD = "weblogic-cmp-rdbms-jar.xml"; 94 95 protected static final String COMPILER_EJB11 = "weblogic.ejbc"; 96 protected static final String COMPILER_EJB20 = "weblogic.ejbc20"; 97 98 99 private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 100 101 102 private String jarSuffix = ".jar"; 103 104 105 private String weblogicDTD; 106 107 108 private String ejb11DTD; 109 110 111 private boolean keepgenerated = false; 112 113 117 private String ejbcClass = null; 118 119 private String additionalArgs = ""; 120 121 124 private String additionalJvmArgs = ""; 125 126 private boolean keepGeneric = false; 127 128 private String compiler = null; 129 130 private boolean alwaysRebuild = true; 131 132 133 private boolean noEJBC = false; 134 135 136 private boolean newCMP = false; 137 138 139 private Path wlClasspath = null; 140 141 142 private Vector sysprops = new Vector (); 143 144 149 private Integer jvmDebugLevel = null; 150 151 private File outputDir; 152 153 157 public void addSysproperty(Environment.Variable sysp) { 158 sysprops.add(sysp); 159 } 160 161 162 166 public Path createWLClasspath() { 167 if (wlClasspath == null) { 168 wlClasspath = new Path(getTask().getProject()); 169 } 170 return wlClasspath.createPath(); 171 } 172 173 179 public void setOutputDir(File outputDir) { 180 this.outputDir = outputDir; 181 } 182 183 184 194 public void setWLClasspath(Path wlClasspath) { 195 this.wlClasspath = wlClasspath; 196 } 197 198 199 211 public void setCompiler(String compiler) { 212 this.compiler = compiler; 213 } 214 215 216 227 public void setRebuild(boolean rebuild) { 228 this.alwaysRebuild = rebuild; 229 } 230 231 232 238 public void setJvmDebugLevel(Integer jvmDebugLevel) { 239 this.jvmDebugLevel = jvmDebugLevel; 240 } 241 242 243 247 public Integer getJvmDebugLevel() { 248 return jvmDebugLevel; 249 } 250 251 252 253 258 public void setSuffix(String inString) { 259 this.jarSuffix = inString; 260 } 261 262 263 269 public void setKeepgeneric(boolean inValue) { 270 this.keepGeneric = inValue; 271 } 272 273 274 281 public void setKeepgenerated(String inValue) { 282 this.keepgenerated = Boolean.valueOf(inValue).booleanValue(); 283 } 284 285 286 291 public void setArgs(String args) { 292 this.additionalArgs = args; 293 } 294 295 296 300 public void setJvmargs(String args) { 301 this.additionalJvmArgs = args; 302 } 303 304 313 public void setEjbcClass(String ejbcClass) { 314 this.ejbcClass = ejbcClass; 315 } 316 317 318 322 public String getEjbcClass() { 323 return ejbcClass; 324 } 325 326 327 334 public void setWeblogicdtd(String inString) { 335 setEJBdtd(inString); 336 } 337 338 339 346 public void setWLdtd(String inString) { 347 this.weblogicDTD = inString; 348 } 349 350 351 358 public void setEJBdtd(String inString) { 359 this.ejb11DTD = inString; 360 } 361 362 363 368 public void setOldCMP(boolean oldCMP) { 369 this.newCMP = !oldCMP; 370 } 371 372 373 385 public void setNewCMP(boolean newCMP) { 386 this.newCMP = newCMP; 387 } 388 389 390 395 public void setNoEJBC(boolean noEJBC) { 396 this.noEJBC = noEJBC; 397 } 398 399 400 404 protected void registerKnownDTDs(DescriptorHandler handler) { 405 handler.registerDTD(PUBLICID_EJB11, DEFAULT_WL51_EJB11_DTD_LOCATION); 407 handler.registerDTD(PUBLICID_EJB11, DEFAULT_WL60_EJB11_DTD_LOCATION); 408 handler.registerDTD(PUBLICID_EJB11, ejb11DTD); 409 handler.registerDTD(PUBLICID_EJB20, DEFAULT_WL60_EJB20_DTD_LOCATION); 410 } 411 412 413 418 protected DescriptorHandler getWeblogicDescriptorHandler(final File srcDir) { 419 DescriptorHandler handler = 420 new DescriptorHandler(getTask(), srcDir) { 421 protected void processElement() { 422 if (currentElement.equals("type-storage")) { 423 String fileNameWithMETA = currentText; 425 String fileName 427 = fileNameWithMETA.substring(META_DIR.length(), 428 fileNameWithMETA.length()); 429 File descriptorFile = new File (srcDir, fileName); 430 431 ejbFiles.put(fileNameWithMETA, descriptorFile); 432 } 433 } 434 }; 435 436 handler.registerDTD(PUBLICID_WEBLOGIC_EJB510, DEFAULT_WL51_DTD_LOCATION); 437 handler.registerDTD(PUBLICID_WEBLOGIC_EJB510, DEFAULT_WL60_51_DTD_LOCATION); 438 handler.registerDTD(PUBLICID_WEBLOGIC_EJB600, DEFAULT_WL60_DTD_LOCATION); 439 handler.registerDTD(PUBLICID_WEBLOGIC_EJB700, DEFAULT_WL70_DTD_LOCATION); 440 handler.registerDTD(PUBLICID_WEBLOGIC_EJB510, weblogicDTD); 441 handler.registerDTD(PUBLICID_WEBLOGIC_EJB600, weblogicDTD); 442 443 for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) { 444 EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next(); 445 446 handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation()); 447 } 448 return handler; 449 } 450 451 452 457 protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) { 458 File weblogicDD = new File (getConfig().descriptorDir, ddPrefix + WL_DD); 459 460 if (weblogicDD.exists()) { 461 ejbFiles.put(META_DIR + WL_DD, 462 weblogicDD); 463 } else { 464 log("Unable to locate weblogic deployment descriptor. " 465 + "It was expected to be in " 466 + weblogicDD.getPath(), Project.MSG_WARN); 467 return; 468 } 469 470 if (!newCMP) { 471 log("The old method for locating CMP files has been DEPRECATED.", Project.MSG_VERBOSE); 472 log("Please adjust your weblogic descriptor and set " 473 + "newCMP=\"true\" to use the new CMP descriptor " 474 + "inclusion mechanism. ", Project.MSG_VERBOSE); 475 File weblogicCMPDD = new File (getConfig().descriptorDir, ddPrefix + WL_CMP_DD); 477 478 if (weblogicCMPDD.exists()) { 479 ejbFiles.put(META_DIR + WL_CMP_DD, 480 weblogicCMPDD); 481 } 482 } else { 483 try { 488 File ejbDescriptor = (File ) ejbFiles.get(META_DIR + EJB_DD); 489 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); 490 491 saxParserFactory.setValidating(true); 492 493 SAXParser saxParser = saxParserFactory.newSAXParser(); 494 DescriptorHandler handler 495 = getWeblogicDescriptorHandler(ejbDescriptor.getParentFile()); 496 497 saxParser.parse(new InputSource 498 (new FileInputStream (weblogicDD)), 499 handler); 500 501 Hashtable ht = handler.getFiles(); 502 Enumeration e = ht.keys(); 503 504 while (e.hasMoreElements()) { 505 String key = (String ) e.nextElement(); 506 507 ejbFiles.put(key, ht.get(key)); 508 } 509 } catch (Exception e) { 510 String msg = "Exception while adding Vendor specific files: " + e.toString(); 511 512 throw new BuildException(msg, e); 513 } 514 } 515 } 516 517 518 523 File getVendorOutputJarFile(String baseName) { 524 return new File (getDestDir(), baseName + jarSuffix); 525 } 526 527 528 537 private void buildWeblogicJar(File sourceJar, File destJar, String publicId) { 538 Java javaTask = null; 539 540 if (noEJBC) { 541 try { 542 FILE_UTILS.copyFile(sourceJar, destJar); 543 if (!keepgenerated) { 544 sourceJar.delete(); 545 } 546 return; 547 } catch (IOException e) { 548 throw new BuildException("Unable to write EJB jar", e); 549 } 550 } 551 552 String ejbcClassName = ejbcClass; 553 554 try { 555 javaTask = new Java(getTask()); 556 javaTask.setTaskName("ejbc"); 557 558 javaTask.createJvmarg().setLine(additionalJvmArgs); 559 if (!(sysprops.isEmpty())) { 560 for (Enumeration en = sysprops.elements(); en.hasMoreElements();) { 561 Environment.Variable entry 562 = (Environment.Variable) en.nextElement(); 563 javaTask.addSysproperty(entry); 564 } 565 } 566 567 if (getJvmDebugLevel() != null) { 568 javaTask.createJvmarg().setLine(" -Dweblogic.StdoutSeverityLevel=" + jvmDebugLevel); 569 } 570 571 if (ejbcClassName == null) { 572 if (PUBLICID_EJB11.equals(publicId)) { 574 ejbcClassName = COMPILER_EJB11; 575 } else if (PUBLICID_EJB20.equals(publicId)) { 576 ejbcClassName = COMPILER_EJB20; 577 } else { 578 log("Unrecognized publicId " + publicId 579 + " - using EJB 1.1 compiler", Project.MSG_WARN); 580 ejbcClassName = COMPILER_EJB11; 581 } 582 } 583 584 javaTask.setClassname(ejbcClassName); 585 javaTask.createArg().setLine(additionalArgs); 586 if (keepgenerated) { 587 javaTask.createArg().setValue("-keepgenerated"); 588 } 589 if (compiler == null) { 590 String buildCompiler 593 = getTask().getProject().getProperty("build.compiler"); 594 595 if (buildCompiler != null && buildCompiler.equals("jikes")) { 596 javaTask.createArg().setValue("-compiler"); 597 javaTask.createArg().setValue("jikes"); 598 } 599 } else { 600 if (!compiler.equals(DEFAULT_COMPILER)) { 601 javaTask.createArg().setValue("-compiler"); 602 javaTask.createArg().setLine(compiler); 603 } 604 } 605 606 Path combinedClasspath = getCombinedClasspath(); 607 if (wlClasspath != null && combinedClasspath != null 608 && combinedClasspath.toString().trim().length() > 0) { 609 javaTask.createArg().setValue("-classpath"); 610 javaTask.createArg().setPath(combinedClasspath); 611 } 612 613 javaTask.createArg().setValue(sourceJar.getPath()); 614 if (outputDir == null) { 615 javaTask.createArg().setValue(destJar.getPath()); 616 } else { 617 javaTask.createArg().setValue(outputDir.getPath()); 618 } 619 620 Path classpath = wlClasspath; 621 622 if (classpath == null) { 623 classpath = getCombinedClasspath(); 624 } 625 626 javaTask.setFork(true); 627 if (classpath != null) { 628 javaTask.setClasspath(classpath); 629 } 630 631 log("Calling " + ejbcClassName + " for " + sourceJar.toString(), 632 Project.MSG_VERBOSE); 633 634 if (javaTask.executeJava() != 0) { 635 throw new BuildException("Ejbc reported an error"); 636 } 637 } catch (Exception e) { 638 String msg = "Exception while calling " + ejbcClassName 640 + ". Details: " + e.toString(); 641 642 throw new BuildException(msg, e); 643 } 644 } 645 646 647 657 protected void writeJar(String baseName, File jarFile, Hashtable files, 658 String publicId) throws BuildException { 659 File genericJarFile = super.getVendorOutputJarFile(baseName); 661 662 super.writeJar(baseName, genericJarFile, files, publicId); 663 664 if (alwaysRebuild || isRebuildRequired(genericJarFile, jarFile)) { 665 buildWeblogicJar(genericJarFile, jarFile, publicId); 666 } 667 if (!keepGeneric) { 668 log("deleting generic jar " + genericJarFile.toString(), 669 Project.MSG_VERBOSE); 670 genericJarFile.delete(); 671 } 672 } 673 674 675 679 public void validateConfigured() throws BuildException { 680 super.validateConfigured(); 681 } 682 683 684 709 protected boolean isRebuildRequired(File genericJarFile, File weblogicJarFile) { 710 boolean rebuild = false; 711 712 JarFile genericJar = null; 713 JarFile wlJar = null; 714 File newWLJarFile = null; 715 JarOutputStream newJarStream = null; 716 ClassLoader genericLoader = null; 717 718 try { 719 log("Checking if weblogic Jar needs to be rebuilt for jar " + weblogicJarFile.getName(), 720 Project.MSG_VERBOSE); 721 if (genericJarFile.exists() && genericJarFile.isFile() 723 && weblogicJarFile.exists() && weblogicJarFile.isFile()) { 724 genericJar = new JarFile (genericJarFile); 726 wlJar = new JarFile (weblogicJarFile); 727 728 Hashtable genericEntries = new Hashtable (); 729 Hashtable wlEntries = new Hashtable (); 730 Hashtable replaceEntries = new Hashtable (); 731 732 for (Enumeration e = genericJar.entries(); e.hasMoreElements();) { 734 JarEntry je = (JarEntry ) e.nextElement(); 735 736 genericEntries.put(je.getName().replace('\\', '/'), je); 737 } 738 for (Enumeration e = wlJar.entries(); e.hasMoreElements();) { 740 JarEntry je = (JarEntry ) e.nextElement(); 741 742 wlEntries.put(je.getName(), je); 743 } 744 745 genericLoader = getClassLoaderFromJar(genericJarFile); 747 748 for (Enumeration e = genericEntries.keys(); e.hasMoreElements();) { 749 String filepath = (String ) e.nextElement(); 750 751 if (wlEntries.containsKey(filepath)) { 752 754 JarEntry genericEntry = (JarEntry ) genericEntries.get(filepath); 756 JarEntry wlEntry = (JarEntry ) wlEntries.get(filepath); 757 758 if ((genericEntry.getCrc() != wlEntry.getCrc()) 759 || (genericEntry.getSize() != wlEntry.getSize())) { 760 761 if (genericEntry.getName().endsWith(".class")) { 762 String classname 764 = genericEntry.getName().replace(File.separatorChar, '.'); 765 766 classname = classname.substring(0, classname.lastIndexOf(".class")); 767 768 Class genclass = genericLoader.loadClass(classname); 769 770 if (genclass.isInterface()) { 771 log("Interface " + genclass.getName() 773 + " has changed", Project.MSG_VERBOSE); 774 rebuild = true; 775 break; 776 } else { 777 replaceEntries.put(filepath, genericEntry); 779 } 780 } else { 781 if (!genericEntry.getName().equals("META-INF/MANIFEST.MF")) { 783 log("Non class file " + genericEntry.getName() 785 + " has changed", Project.MSG_VERBOSE); 786 rebuild = true; 787 break; 788 } 789 } 790 } 791 } else { 792 794 log("File " + filepath + " not present in weblogic jar", 795 Project.MSG_VERBOSE); 796 rebuild = true; 797 break; 798 } 799 } 800 801 if (!rebuild) { 802 log("No rebuild needed - updating jar", Project.MSG_VERBOSE); 803 newWLJarFile = new File (weblogicJarFile.getAbsolutePath() + ".temp"); 804 if (newWLJarFile.exists()) { 805 newWLJarFile.delete(); 806 } 807 808 newJarStream = new JarOutputStream (new FileOutputStream (newWLJarFile)); 809 newJarStream.setLevel(0); 810 811 for (Enumeration e = wlEntries.elements(); e.hasMoreElements();) { 813 byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; 814 int bytesRead; 815 InputStream is; 816 JarEntry je = (JarEntry ) e.nextElement(); 817 818 if (je.getCompressedSize() == -1 819 || je.getCompressedSize() == je.getSize()) { 820 newJarStream.setLevel(0); 821 } else { 822 newJarStream.setLevel(JAR_COMPRESS_LEVEL); 823 } 824 825 if (replaceEntries.containsKey(je.getName())) { 827 log("Updating Bean class from generic Jar " 828 + je.getName(), Project.MSG_VERBOSE); 829 je = (JarEntry ) replaceEntries.get(je.getName()); 831 is = genericJar.getInputStream(je); 832 } else { 833 835 is = wlJar.getInputStream(je); 836 } 837 newJarStream.putNextEntry(new JarEntry (je.getName())); 838 839 while ((bytesRead = is.read(buffer)) != -1) { 840 newJarStream.write(buffer, 0, bytesRead); 841 } 842 is.close(); 843 } 844 } else { 845 log("Weblogic Jar rebuild needed due to changed " 846 + "interface or XML", Project.MSG_VERBOSE); 847 } 848 } else { 849 rebuild = true; 850 } 851 } catch (ClassNotFoundException cnfe) { 852 String cnfmsg = "ClassNotFoundException while processing ejb-jar file" 853 + ". Details: " 854 + cnfe.getMessage(); 855 856 throw new BuildException(cnfmsg, cnfe); 857 } catch (IOException ioe) { 858 String msg = "IOException while processing ejb-jar file " 859 + ". Details: " 860 + ioe.getMessage(); 861 862 throw new BuildException(msg, ioe); 863 } finally { 864 if (genericJar != null) { 866 try { 867 genericJar.close(); 868 } catch (IOException closeException) { 869 } 871 } 872 873 if (wlJar != null) { 874 try { 875 wlJar.close(); 876 } catch (IOException closeException) { 877 } 879 } 880 881 if (newJarStream != null) { 882 try { 883 newJarStream.close(); 884 } catch (IOException closeException) { 885 } 887 888 try { 889 FILE_UTILS.rename(newWLJarFile, weblogicJarFile); 890 } catch (IOException renameException) { 891 log(renameException.getMessage(), Project.MSG_WARN); 892 rebuild = true; 893 } 894 } 895 if (genericLoader != null 896 && genericLoader instanceof AntClassLoader) { 897 AntClassLoader loader = (AntClassLoader) genericLoader; 898 loader.cleanup(); 899 } 900 } 901 902 return rebuild; 903 } 904 905 906 914 protected ClassLoader getClassLoaderFromJar(File classjar) throws IOException { 915 Path lookupPath = new Path(getTask().getProject()); 916 917 lookupPath.setLocation(classjar); 918 919 Path classpath = getCombinedClasspath(); 920 921 if (classpath != null) { 922 lookupPath.append(classpath); 923 } 924 925 return getTask().getProject().createClassLoader(lookupPath); 926 } 927 } 928 | Popular Tags |