JonasDeploymentTool.java

00001 
00054 package org.objectweb.jonas.ant;
00055 
00056 import java.io.File;
00057 import java.io.IOException;
00058 import java.util.Hashtable;
00059 
00060 import javax.xml.parsers.SAXParser;
00061 
00062 import org.apache.tools.ant.AntClassLoader;
00063 import org.apache.tools.ant.BuildException;
00064 import org.apache.tools.ant.Project;
00065 import org.apache.tools.ant.taskdefs.Java;
00066 import org.apache.tools.ant.types.Path;
00067 import org.apache.tools.ant.types.Reference;
00068 
00080 public class JonasDeploymentTool extends GenericDeploymentTool {
00081 
00083     protected static final String EJB_JAR_1_1_PUBLIC_ID = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN";
00084     protected static final String EJB_JAR_2_0_PUBLIC_ID = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN";
00085 
00087     protected static final String JONAS_EJB_JAR_2_4_PUBLIC_ID = "-//ObjectWeb//DTD JOnAS 2.4//EN";
00088     protected static final String JONAS_EJB_JAR_2_5_PUBLIC_ID = "-//ObjectWeb//DTD JOnAS 2.5//EN";
00089     protected static final String JONAS_EJB_JAR_3_0_PUBLIC_ID = "-//ObjectWeb//DTD JOnAS 3.0//EN";
00090     protected static final String JONAS_EJB_JAR_3_2_PUBLIC_ID = "-//ObjectWeb//DTD JOnAS 3.2//EN";
00091     protected static final String JONAS_EJB_JAR_3_3_PUBLIC_ID = "-//ObjectWeb//DTD JOnAS 3.3//EN";
00092     protected static final String JONAS_EJB_JAR_3_3_2_PUBLIC_ID = "-//ObjectWeb//DTD JOnAS 3.3.2//EN";
00093 
00098     protected static final String EJB_JAR_1_1_DTD = "ejb-jar_1_1.dtd";
00099     protected static final String EJB_JAR_2_0_DTD = "ejb-jar_2_0.dtd";
00100 
00105     protected static final String JONAS_EJB_JAR_2_4_DTD = "jonas-ejb-jar_2_4.dtd";
00106     protected static final String JONAS_EJB_JAR_2_5_DTD = "jonas-ejb-jar_2_5.dtd";
00107     protected static final String JONAS_EJB_JAR_3_0_DTD = "jonas-ejb-jar_3_0.dtd";
00108     protected static final String JONAS_EJB_JAR_3_2_DTD = "jonas-ejb-jar_3_2.dtd";
00109     protected static final String JONAS_EJB_JAR_3_3_DTD = "jonas-ejb-jar_3_3.dtd";
00110     protected static final String JONAS_EJB_JAR_3_3_2_DTD = "jonas-ejb-jar_3_3_2.dtd";
00111 
00113     protected static final String JONAS_DD = "jonas-ejb-jar.xml";
00114 
00116     protected static final String BOOTSTRAP_CLASS = "org.objectweb.jonas.server.Bootstrap";
00117 
00119     protected static final String GENIC_CLASS = "org.objectweb.jonas_ejb.genic.GenIC";
00120 
00126     private String descriptorName;
00127 
00133     private String jonasDescriptorName;
00134 
00135     /* ------------- */
00136     /* GenIC options */
00137     /* ------------- */
00138 
00142     private File outputdir;
00143 
00148     private boolean keepgenerated = false;
00149 
00154     private boolean nocompil = false;
00155 
00160     private boolean invokeCmd = false;
00161 
00166     private boolean novalidation = false;
00167 
00172     private String javac;
00173 
00175     private String javacopts;
00176 
00178     private String rmicopts;
00179 
00184     private boolean verbose = false;
00185 
00187     private String additionalargs;
00188 
00190     private String jvmopts = null;
00191 
00193     private String protocols = null;
00194 
00195     /* ------------- */
00196     /* other options */
00197     /* ------------- */
00198 
00200     private File jonasroot;
00201 
00203     private File jonasbase;
00204 
00209     private boolean keepgeneric = false;
00210 
00212     private String suffix = ".jar";
00213 
00218     private boolean nogenic = false;
00219 
00220     /* -------------------- */
00221     /* GenIC options setter */
00222     /* -------------------- */
00223 
00228     public void setKeepgenerated(boolean aBoolean) {
00229         keepgenerated = aBoolean;
00230     }
00231 
00236     public void setMappernames(String aString) {
00237         log("'mappernames' attribute ignored (deprecated)", Project.MSG_WARN);
00238     }
00239 
00244     public void setProtocols(String aString) {
00245         protocols = aString;
00246     }
00247 
00252     public void setClasspathref(Reference r) {
00253         createClasspath().setRefid(r);
00254     }
00259     public void setAdditionalargs(String aString) {
00260         additionalargs = aString;
00261     }
00262 
00267     public void setNocompil(boolean aBoolean) {
00268         nocompil = aBoolean;
00269     }
00270 
00275     public void setInvokecmd(boolean aBoolean) {
00276         invokeCmd = aBoolean;
00277     }
00278 
00283     public void setNovalidation(boolean aBoolean) {
00284         novalidation = aBoolean;
00285     }
00286 
00291     public void setJavac(String aString) {
00292         javac = aString;
00293     }
00294 
00299     public void setJavacopts(String aString) {
00300         javacopts = aString;
00301     }
00302 
00307     public void setRmicopts(String aString) {
00308         rmicopts = aString;
00309     }
00310 
00315     public void setVerbose(boolean aBoolean) {
00316         verbose = aBoolean;
00317     }
00318 
00319     /* -------------------- */
00320     /* other options setter */
00321     /* -------------------- */
00322 
00327     public void setJonasroot(File aFile) {
00328         jonasroot = aFile;
00329     }
00330 
00335     public void setJonasbase(File aFile) {
00336         jonasbase = aFile;
00337     }
00338 
00343     public void setKeepgeneric(boolean aBoolean) {
00344         keepgeneric = aBoolean;
00345     }
00346 
00351     public void setJarsuffix(String aString) {
00352         suffix = aString;
00353     }
00354 
00359     public void setNogenic(boolean aBoolean) {
00360         nogenic = aBoolean;
00361     }
00362 
00367     public void setJvmopts(String aString) {
00368         jvmopts = aString;
00369     }
00370 
00371     /* ------------- */
00372     /* other methods */
00373     /* ------------- */
00374 
00375     public void processDescriptor(String aDescriptorName, SAXParser saxParser) {
00376 
00377         descriptorName = aDescriptorName;
00378 
00379         log("JOnAS Deployment Tool processing for JOnAS: " + descriptorName, Project.MSG_VERBOSE);
00380 
00381         super.processDescriptor(descriptorName, saxParser);
00382 
00383         if (outputdir != null) {
00384             // the method deleteOnExit() do not work because the directory is
00385             // not empty
00386             log("Deleting temp output directory '" + outputdir + "'.", Project.MSG_VERBOSE);
00387             deleteAllFiles(outputdir);
00388         }
00389     }
00390 
00391     protected void writeJar(String baseName, File jarfile, Hashtable ejbFiles, String publicId,
00392             boolean includeInnerClasses) throws BuildException {
00393 
00394         // create the generic jar first
00395         File genericJarFile = super.getVendorOutputJarFile(baseName);
00396 
00397         super.writeJar(baseName, genericJarFile, ejbFiles, publicId, true);
00398 
00399         // GenIC call on generic jar
00400         addGenICGeneratedFiles(genericJarFile, ejbFiles);
00401 
00402         // create the real jar
00403         super.writeJar(baseName, getVendorOutputJarFile(baseName), ejbFiles, publicId, false);
00404 
00405         //log("genericJarFile: " + genericJarFile, Project.MSG_VERBOSE);
00406         //log("getVendorOutputJarFile(baseName): " +
00407         // getVendorOutputJarFile(baseName), Project.MSG_VERBOSE);
00408         //log("baseName: " + baseName, Project.MSG_VERBOSE);
00409 
00410         if (!keepgeneric) {
00411             log("Deleting generic JAR " + genericJarFile.toString(), Project.MSG_VERBOSE);
00412             genericJarFile.delete();
00413         }
00414     }
00415 
00416     protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
00417 
00418         // JOnAS-specific descriptor deployment
00419         jonasDescriptorName = getJonasDescriptorName();
00420         File jonasDD = new File(getConfig().descriptorDir, jonasDescriptorName);
00421 
00422         if (jonasDD.exists()) {
00423             ejbFiles.put(META_DIR + JONAS_DD, jonasDD);
00424         } else {
00425             log("Unable to locate the JOnAS deployment descriptor. It was expected to be in: " + jonasDD.getPath()
00426                     + ".", Project.MSG_WARN);
00427         }
00428     }
00429 
00430     protected File getVendorOutputJarFile(String baseName) {
00431         return new File(getDestDir(), baseName + suffix);
00432     }
00433 
00441     private String getJonasDescriptorName() {
00442 
00443         // descriptorName = <path><basename><basenameterminator><remainder>
00444         // examples = /org/objectweb/fooAppli/foo/Foo-ejb-jar.xml
00445         // examples = /org/objectweb/fooAppli/foo/Foo.xml (JOnAS convention)
00446 
00447         String jonasDescriptorName; // JOnAS-specific DD
00448         boolean jonasConvention = false; // true if the JOnAS convention is used
00449                                          // for the DD
00450         String path; // Directory path of the EJB descriptor
00451         String fileName; // EJB descriptor file name
00452         String baseName; // Filename appearing before name terminator
00453         String remainder; // Filename appearing after the name terminator
00454 
00455         int startOfFileName = descriptorName.lastIndexOf(File.separatorChar);
00456         if (startOfFileName != -1) {
00457             // extract path info
00458             path = descriptorName.substring(0, startOfFileName + 1);
00459             fileName = descriptorName.substring(startOfFileName + 1);
00460         } else {
00461             // descriptorName is just a file without path
00462             path = "";
00463             fileName = descriptorName;
00464         }
00465 
00466         if (fileName.startsWith(EJB_DD)) {
00467             return path + JONAS_DD;
00468         }
00469 
00470         int endOfBaseName = descriptorName.indexOf(getConfig().baseNameTerminator, startOfFileName);
00471 
00472         /*
00473          * Check for the odd case where the terminator and/or filename extension
00474          * aren't found. These will ensure "jonas-" appears at the end of the
00475          * name and before the '.' (if present).
00476          */
00477         if (endOfBaseName < 0) {
00478             // baseNameTerminator not found: the descriptor use the
00479             // JOnAS naming convention, ie [Foo.xml,jonas-Foo.xml] and
00480             // not [Foo<baseNameTerminator>-ejb-jar.xml,
00481             // Foo<baseNameTerminator>-jonas-ejb-jar.xml].
00482             endOfBaseName = descriptorName.lastIndexOf('.') - 1;
00483             if (endOfBaseName < 0) {
00484                 // no . found
00485                 endOfBaseName = descriptorName.length() - 1;
00486             }
00487 
00488             jonasConvention = true;
00489         }
00490 
00491         baseName = descriptorName.substring(startOfFileName + 1, endOfBaseName + 1);
00492         remainder = descriptorName.substring(endOfBaseName + 1);
00493 
00494         if (jonasConvention) {
00495             jonasDescriptorName = path + "jonas-" + baseName + ".xml";
00496         } else {
00497             jonasDescriptorName = path + baseName + "jonas-" + remainder;
00498         }
00499 
00500         log("Standard EJB descriptor name: " + descriptorName, Project.MSG_VERBOSE);
00501         log("JOnAS-specific descriptor name: " + jonasDescriptorName, Project.MSG_VERBOSE);
00502 
00503         return jonasDescriptorName;
00504     }
00505 
00506     protected String getJarBaseName(String descriptorFileName) {
00507 
00508         String baseName = null;
00509 
00510         if (getConfig().namingScheme.getValue().equals(EjbJar.NamingScheme.DESCRIPTOR)) {
00511 
00512             // try to find JOnAS specific convention name
00513             if (descriptorFileName.indexOf(getConfig().baseNameTerminator) == -1) {
00514 
00515                 // baseNameTerminator not found: the descriptor use the
00516                 // JOnAS naming convention, ie [Foo.xml,jonas-Foo.xml] and
00517                 // not [Foo<baseNameTerminator>-ejb-jar.xml,
00518                 // Foo<baseNameTerminator>-jonas-ejb-jar.xml].
00519 
00520                 String aCanonicalDescriptor = descriptorFileName.replace('\\', '/');
00521                 int lastSeparatorIndex = aCanonicalDescriptor.lastIndexOf('/');
00522                 int endOfBaseName;
00523 
00524                 if (lastSeparatorIndex != -1) {
00525                     endOfBaseName = descriptorFileName.indexOf(".xml", lastSeparatorIndex);
00526                 } else {
00527                     endOfBaseName = descriptorFileName.indexOf(".xml");
00528                 }
00529 
00530                 if (endOfBaseName != -1) {
00531                     baseName = descriptorFileName.substring(0, endOfBaseName);
00532                 }
00533             }
00534         }
00535 
00536         if (baseName == null) {
00537             // else get standard baseName
00538             baseName = super.getJarBaseName(descriptorFileName);
00539         }
00540 
00541         log("JAR base name: " + baseName, Project.MSG_VERBOSE);
00542 
00543         return baseName;
00544     }
00545 
00546     protected void registerKnownDTDs(DescriptorHandler handler) {
00547 
00548         handler.registerDTD(EJB_JAR_1_1_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00549                 + EJB_JAR_1_1_DTD);
00550         handler.registerDTD(EJB_JAR_2_0_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00551                 + EJB_JAR_2_0_DTD);
00552 
00553         handler.registerDTD(JONAS_EJB_JAR_2_4_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00554                 + JONAS_EJB_JAR_2_4_DTD);
00555         handler.registerDTD(JONAS_EJB_JAR_2_5_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00556                 + JONAS_EJB_JAR_2_5_DTD);
00557         handler.registerDTD(JONAS_EJB_JAR_3_0_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00558                 + JONAS_EJB_JAR_3_0_DTD);
00559         handler.registerDTD(JONAS_EJB_JAR_3_2_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00560                 + JONAS_EJB_JAR_3_2_DTD);
00561         handler.registerDTD(JONAS_EJB_JAR_3_3_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00562                 + JONAS_EJB_JAR_3_3_DTD);
00563         handler.registerDTD(JONAS_EJB_JAR_3_3_2_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00564                 + JONAS_EJB_JAR_3_3_2_DTD);
00565     }
00566 
00572     private void addGenICGeneratedFiles(File genericJarFile, Hashtable ejbFiles) {
00573 
00574         Java genicTask = null; // GenIC task
00575 
00576         if (nogenic) {
00577             return;
00578         }
00579 
00580         genicTask = (Java) getTask().getProject().createTask("java");
00581         genicTask.setTaskName("genic");
00582         genicTask.setFork(true);
00583 
00584         // jonas root
00585         genicTask.createJvmarg().setValue("-Dinstall.root=" + jonasroot);
00586 
00587         // jonas base
00588         genicTask.createJvmarg().setValue("-Djonas.base=" + jonasbase);
00589 
00590         // Endorsed directory
00591         File endorsedDir = new File(new File(jonasroot, "lib"), "endorsed");
00592         genicTask.createJvmarg().setValue("-Djava.endorsed.dirs=" + endorsedDir);
00593 
00594         // java policy file
00595         String jonasConfigDir = jonasroot + File.separator + "conf";
00596         File javaPolicyFile = new File(jonasConfigDir, "java.policy");
00597         if (javaPolicyFile.exists()) {
00598             genicTask.createJvmarg().setValue("-Djava.security.policy=" + javaPolicyFile.toString());
00599         }
00600 
00601         // The bootstrap class must launch the GenIC class
00602         genicTask.createArg().setValue(JonasDeploymentTool.GENIC_CLASS);
00603 
00604         // outputdir
00605         try {
00606             outputdir = createTempDir();
00607         } catch (IOException aIOException) {
00608             String msg = "Cannot create temp dir: " + aIOException.getMessage();
00609             throw new BuildException(msg, aIOException);
00610         }
00611         log("Using temporary output directory: " + outputdir, Project.MSG_VERBOSE);
00612 
00613         genicTask.createArg().setValue("-d");
00614         genicTask.createArg().setFile(outputdir);
00615 
00616         // classpath
00617         Path classpath = getCombinedClasspath();
00618         if (classpath == null) {
00619             classpath = new Path(getTask().getProject());
00620         }
00621         // add ow_jonas_bootstrap.jar
00622         String bootJar = jonasroot + File.separator + "lib" + File.separator + "common" + File.separator
00623                 + "ow_jonas_bootstrap.jar";
00624         Path bootstrap = new Path(getTask().getProject(), bootJar);
00625         //classpath.append(new Path(classpath.getProject(), bootJar));
00626 
00627         classpath.append(new Path(classpath.getProject(), outputdir.toString()));
00628 
00629         log("Using classpath: " + bootstrap.toString(), Project.MSG_VERBOSE);
00630         genicTask.setClasspath(bootstrap);
00631 
00632         if (!checkBootstrapClassName(bootstrap)) {
00633             log("Cannot find bootstrap class in classpath.", Project.MSG_ERR);
00634             throw new BuildException("Bootstrap class not found, please check the classpath.");
00635         } else {
00636             genicTask.setClassname(JonasDeploymentTool.BOOTSTRAP_CLASS);
00637         }
00638 
00639         // classpath
00640         genicTask.createArg().setValue("-classpath");
00641         genicTask.createArg().setPath(classpath);
00642 
00643         // keepgenerated
00644         if (keepgenerated) {
00645             genicTask.createArg().setValue("-keepgenerated");
00646         }
00647 
00648         // nocompil
00649         if (nocompil) {
00650             genicTask.createArg().setValue("-nocompil");
00651         }
00652 
00653         // invokecmd
00654         if (invokeCmd) {
00655             genicTask.createArg().setValue("-invokecmd");
00656         }
00657 
00658         // novalidation
00659         if (novalidation) {
00660             genicTask.createArg().setValue("-novalidation");
00661         }
00662 
00663         // javac
00664         if (javac != null) {
00665             genicTask.createArg().setValue("-javac");
00666             genicTask.createArg().setLine(javac);
00667         }
00668 
00669         // javacopts
00670         if (javacopts != null && !javacopts.equals("")) {
00671             genicTask.createArg().setValue("-javacopts");
00672             genicTask.createArg().setValue(javacopts);
00673         }
00674 
00675         // rmicopts
00676         if (rmicopts != null && !rmicopts.equals("")) {
00677             genicTask.createArg().setValue("-rmicopts");
00678             genicTask.createArg().setValue(rmicopts);
00679         }
00680 
00681         // verbose
00682         if (verbose) {
00683             genicTask.createArg().setValue("-verbose");
00684         }
00685 
00686         // additionalargs
00687         if (additionalargs != null) {
00688             genicTask.createArg().setLine(additionalargs);
00689         }
00690 
00691         // protocols
00692         if (protocols != null) {
00693             genicTask.createArg().setValue("-protocols");
00694             genicTask.createArg().setValue(protocols);
00695         }
00696 
00697         // the generated classes must not be added in the generic JAR!
00698         genicTask.createArg().setValue("-noaddinjar");
00699 
00700         // jvmopts
00701         if (jvmopts != null && !jvmopts.equals("")) {
00702             genicTask.createJvmarg().setLine(jvmopts);
00703         }
00704 
00705         // input file to process by GenIC
00706         genicTask.createArg().setValue(genericJarFile.getPath());
00707 
00708         // calling GenIC task
00709         log("Calling  GenIC task for " + getConfig().descriptorDir + File.separator + descriptorName + ".",
00710                 Project.MSG_VERBOSE);
00711 
00712         if (genicTask.executeJava() != 0) {
00713             // Don't delete the temp output directory in case of error:
00714 
00715             //log("Deleting temp output directory '" + outputdir + "'.",
00716             // Project.MSG_VERBOSE);
00717             // the method deleteOnExit() do not work because the directory is
00718             // not empty
00719             //deleteAllFiles(outputdir);
00720 
00721             if (!keepgeneric) {
00722                 log("Deleting generic JAR " + genericJarFile.toString(), Project.MSG_VERBOSE);
00723                 genericJarFile.delete();
00724             }
00725 
00726             throw new BuildException("GenIC reported an error.");
00727         }
00728 
00729         // add the generated files to the ejbFiles
00730         addAllFiles(outputdir, "", ejbFiles);
00731     }
00732 
00738     private boolean checkBootstrapClassName(Path classpath) {
00739         log("Looking for bootstrap class in classpath: " + classpath.toString(), Project.MSG_VERBOSE);
00740         AntClassLoader cl = new AntClassLoader(classpath.getProject(), classpath);
00741         try {
00742             cl.loadClass(JonasDeploymentTool.BOOTSTRAP_CLASS);
00743             log("Found Bootstrap class '" + JonasDeploymentTool.BOOTSTRAP_CLASS + "' in classpath.",
00744                     Project.MSG_VERBOSE);
00745         } catch (ClassNotFoundException cnf1) {
00746             log("Bootstrap class '" + JonasDeploymentTool.BOOTSTRAP_CLASS + "' not found in classpath.",
00747                     Project.MSG_VERBOSE);
00748             return false;
00749         }
00750         return true;
00751     }
00752 
00753     protected void checkConfiguration(String descriptorFileName, SAXParser saxParser) throws BuildException {
00754         // jonasroot
00755         if (jonasroot == null) {
00756             throw new BuildException("The jonasroot attribute is not set.");
00757         } else if (!jonasroot.isDirectory()) {
00758             throw new BuildException("The jonasroot attribute '" + jonasroot + "' is not a valid directory.");
00759         }
00760         // jonasbase default value is jonasroot
00761         if (jonasbase == null) {
00762             jonasbase = jonasroot;
00763         }
00764 
00765         // additionalargs
00766         if (additionalargs != null && additionalargs.equals("")) {
00767             throw new BuildException("Empty additionalargs attribute.");
00768         }
00769 
00770         // javac
00771         if (javac != null && javac.equals("")) {
00772             throw new BuildException("Empty javac attribute.");
00773         }
00774     }
00775 
00776     /* ----------------------------------------------------------------------------------- */
00777     /* utilitary methods */
00778     /* ----------------------------------------------------------------------------------- */
00779 
00785     private File createTempDir() throws IOException {
00786         File tmpDir = File.createTempFile("genic", null, null);
00787         tmpDir.delete();
00788         if (!tmpDir.mkdir()) {
00789             throw new IOException("Cannot create the temporary directory '" + tmpDir + "'.");
00790         }
00791         return tmpDir;
00792     }
00793 
00799     private void deleteAllFiles(File aFile) {
00800         if (aFile.isDirectory()) {
00801             File someFiles[] = aFile.listFiles();
00802             for (int i = 0; i < someFiles.length; i++) {
00803                 deleteAllFiles(someFiles[i]);
00804             }
00805         }
00806         aFile.delete();
00807     }
00808 
00816     private void addAllFiles(File file, String rootDir, Hashtable hashtable) {
00817 
00818         if (!file.exists()) {
00819             throw new IllegalArgumentException();
00820         }
00821 
00822         String newRootDir;
00823         if (file.isDirectory()) {
00824             File[] files = file.listFiles();
00825             for (int i = 0; i < files.length; i++) {
00826                 if (rootDir.length() > 0) {
00827                     newRootDir = rootDir + File.separator + files[i].getName();
00828                 } else {
00829                     newRootDir = files[i].getName();
00830                 }
00831                 addAllFiles(files[i], newRootDir, hashtable);
00832             }
00833         } else {
00834             hashtable.put(rootDir, file);
00835         }
00836     }
00837 }

Generated on Tue Feb 15 15:05:14 2005 for JOnAS by  doxygen 1.3.9.1