conor 01/12/11 06:18:52
Modified: src/main/org/apache/tools/ant/taskdefs/optional/ejb
EjbJar.java GenericDeploymentTool.java
Added: src/main/org/apache/tools/ant/taskdefs/optional/ejb
WebsphereDeploymentTool.java
Log:
Remove the old mechanism of adding super classes and super interfaces to EJB
jars
and replace with a general class dependnecy check. This should allow ejb jars
to be much more complete as per the spec.
ejbjar now depends on BCEL.
Add support for Websphere.
Submitted by: Holger Engels <[EMAIL PROTECTED]>
Maneesh Sahu <[EMAIL PROTECTED]> (Original Websphere support)
Revision Changes Path
1.25 +13 -0
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java
Index: EjbJar.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -w -u -r1.24 -r1.25
--- EjbJar.java 2001/11/27 18:04:52 1.24
+++ EjbJar.java 2001/12/11 14:18:52 1.25
@@ -219,6 +219,19 @@
}
/**
+ * Create a websphere nested element used to configure a
+ * deployment tool for Websphere 4.0 server.
+ *
+ * @return the deployment tool instance to be configured.
+ */
+ public WebsphereDeploymentTool createWebsphere() {
+ WebsphereDeploymentTool tool = new WebsphereDeploymentTool();
+ tool.setTask(this);
+ deploymentTools.add(tool);
+ return tool;
+ }
+
+ /**
* Create a Borland nested element used to configure a
* deployment tool for Borland server.
*
1.24 +68 -94
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java
Index: GenericDeploymentTool.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -w -u -r1.23 -r1.24
--- GenericDeploymentTool.java 2001/10/28 21:30:20 1.23
+++ GenericDeploymentTool.java 2001/12/11 14:18:52 1.24
@@ -60,6 +60,9 @@
import java.io.FileOutputStream;
import java.util.Hashtable;
import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.jar.JarOutputStream;
@@ -71,6 +74,13 @@
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.types.*;
+import org.apache.tools.ant.util.depend.Dependencies;
+import org.apache.tools.ant.util.depend.Filter;
+import org.apache.bcel.classfile.*;
+import org.apache.bcel.*;
+
import org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Location;
@@ -80,6 +90,7 @@
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.FileSet;
+
/**
* A deployment tool which creates generic EJB jars. Generic jars contains
* only those classes and META-INF entries specified in the EJB 1.1 standard
@@ -204,7 +215,7 @@
/**
* Get the classpath by combining the one from the surrounding task, if
any
- * and the one from tis tool.
+ * and the one from this tool.
*/
protected Path getCombinedClasspath() {
Path combinedPath = classpath;
@@ -339,8 +350,8 @@
// now the vendor specific files, if any
addVendorFiles(ejbFiles, ddPrefix);
- // add any inherited files
- checkAndAddInherited(ejbFiles);
+ // add any dependent files
+ checkAndAddDependants(ejbFiles);
// Lastly create File object for the Jar files. If we are using
// a flat destination dir, then we need to redefine baseName!
@@ -585,6 +596,7 @@
* </code>. If the <code>jarFile</code>'s timestamp is more recent than
* each EJB file, <code>true</code> is returned. Otherwise, <code>false
* </code> is returned.
+ * TODO: find a way to check the manifest-file, that is found by naming
convention
*
* @param ejbFiles Hashtable of EJB classes (and other) files that will
be
* added to the completed JAR file
@@ -596,6 +608,7 @@
protected boolean needToRebuild(Hashtable ejbFiles, File jarFile) {
if (jarFile.exists()) {
long lastBuild = jarFile.lastModified();
+
if (config.manifest != null && config.manifest.exists() &&
config.manifest.lastModified() > lastBuild) {
log("Build needed because manifest " + config.manifest + "
is out of date",
@@ -660,7 +673,11 @@
InputStream in = null;
Manifest manifest = null;
try {
- if (config.manifest != null) {
+ File manifestFile = new File(getConfig().descriptorDir,
baseName + "-manifest.mf");
+ if (manifestFile.exists()) {
+ in = new FileInputStream(manifestFile);
+ }
+ else if (config.manifest != null) {
in = new FileInputStream(config.manifest);
if ( in == null ) {
throw new BuildException("Could not find manifest
file: " + config.manifest,
@@ -744,106 +761,63 @@
}
} // end of writeJar
+
/**
- * Check if a EJB Class Inherits from a Superclass, and if a Remote
Interface
- * extends an interface other then javax.ejb.EJBObject directly. Then
add those
- * classes to the generic-jar so they dont have to added elsewhere.
- *
+ * Add all available classes, that depend on Remote, Home, Bean, PK
+ * @param checkEntries files, that are extracted from the deployment
descriptor
*/
- protected void checkAndAddInherited(Hashtable checkEntries) throws
BuildException
+ protected void checkAndAddDependants(Hashtable checkEntries)
+ throws BuildException
{
- //Copy hashtable so were not changing the one we iterate through
- Hashtable copiedHash = (Hashtable)checkEntries.clone();
+ Dependencies visitor = new Dependencies();
+ Set set = new TreeSet();
+ Set newSet = new HashSet();
+ final String base = config.srcDir.getAbsolutePath() + File.separator;
+
+ Iterator i = checkEntries.keySet().iterator();
+ while (i.hasNext()) {
+ String entryName = (String)i.next();
+ if (entryName.endsWith(".class"))
+ newSet.add(entryName.substring(0, entryName.length() -
".class".length()).replace(File.separatorChar, '/'));
+ }
+ set.addAll(newSet);
- // Walk base level EJBs and see if they have superclasses or extend
extra interfaces which extend EJBObject
- for (Iterator entryIterator = copiedHash.keySet().iterator();
entryIterator.hasNext(); )
- {
- String entryName = (String)entryIterator.next();
- File entryFile = (File)copiedHash.get(entryName);
+ do {
+ i = newSet.iterator();
+ while (i.hasNext()) {
+ String fileName = base + ((String)i.next()).replace('/',
File.separatorChar) + ".class";
- // only want class files, xml doesnt reflect very well =)
- if (entryName.endsWith(".class"))
- {
- String classname =
entryName.substring(0,entryName.lastIndexOf(".class")).replace(File.separatorChar,'.');
- ClassLoader loader = getClassLoaderForBuild();
try {
- Class c = loader.loadClass(classname);
-
- // No primatives!! sanity check, probably not nessesary
- if (!c.isPrimitive())
- {
- if (c.isInterface()) //get as an interface
- {
- log("looking at interface " + c.getName(),
Project.MSG_VERBOSE);
- Class[] interfaces = c.getInterfaces();
- for (int i = 0; i < interfaces.length; i++){
- log(" implements " +
interfaces[i].getName(), Project.MSG_VERBOSE);
- addInterface(interfaces[i], checkEntries);
- }
+ JavaClass javaClass = new ClassParser(fileName).parse();
+ javaClass.accept(visitor);
}
- else // get as a class
- {
- log("looking at class " + c.getName(),
Project.MSG_VERBOSE);
- Class s = c.getSuperclass();
- addSuperClass(c.getSuperclass(), checkEntries);
- }
- } //if primative
- }
- catch (ClassNotFoundException cnfe) {
- log("Could not load class " + classname + " for super
class check",
- Project.MSG_WARN);
- }
- catch (NoClassDefFoundError ncdfe) {
- log("Could not fully load class " + classname + " for
super class check",
- Project.MSG_WARN);
+ catch (IOException e) {
+ log("exception: " + e.getMessage(), Project.MSG_INFO);
}
- } //if
- } // while
}
+ newSet.clear();
+ newSet.addAll(visitor.getDependencies());
+ visitor.clearDependencies();
- private void addInterface(Class theInterface, Hashtable checkEntries) {
- if (!theInterface.getName().startsWith("java")) // do not add system
interfaces
- {
- File interfaceFile = new File(config.srcDir.getAbsolutePath()
- + File.separatorChar
- +
theInterface.getName().replace('.',File.separatorChar)
- + ".class"
- );
- if (interfaceFile.exists() && interfaceFile.isFile())
- {
-
checkEntries.put(theInterface.getName().replace('.',File.separatorChar)+".class",
- interfaceFile);
- Class[] superInterfaces = theInterface.getInterfaces();
- for (int i = 0; i < superInterfaces.length; i++) {
- addInterface(superInterfaces[i], checkEntries);
- }
- }
+ Dependencies.applyFilter(newSet, new Filter() {
+ public boolean accept(Object object) {
+ String fileName = base +
((String)object).replace('/', File.separatorChar) + ".class";
+ return new File(fileName).exists();
}
+ });
+ newSet.removeAll(set);
+ set.addAll(newSet);
}
+ while (newSet.size() > 0);
- private void addSuperClass(Class superClass, Hashtable checkEntries) {
-
- if (!superClass.getName().startsWith("java"))
- {
- File superClassFile = new File(config.srcDir.getAbsolutePath()
- + File.separatorChar
- +
superClass.getName().replace('.',File.separatorChar)
- + ".class");
- if (superClassFile.exists() && superClassFile.isFile())
- {
-
checkEntries.put(superClass.getName().replace('.',File.separatorChar) +
".class",
- superClassFile);
-
- // now need to get super classes and interfaces for this
class
- Class[] superInterfaces = superClass.getInterfaces();
- for (int i = 0; i < superInterfaces.length; i++) {
- addInterface(superInterfaces[i], checkEntries);
+ i = set.iterator();
+ while (i.hasNext()) {
+ String next = ((String)i.next()).replace('/',
File.separatorChar);
+ checkEntries.put(next + ".class", new File(base + next +
".class"));
+ log("dependent class: " + next + ".class" + " - " + base + next
+ ".class", Project.MSG_VERBOSE);
}
-
- addSuperClass(superClass.getSuperclass(), checkEntries);
- }
}
- }
+
/**
* Returns a Classloader object which parses the passed in generic
EjbJar classpath.
1.1
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java
Index: WebsphereDeploymentTool.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowasegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowasegement may appear in the software itself,
* if and wherever such third-party acknowasegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;
import java.io.*;
import java.util.jar.*;
import java.util.*;
import java.net.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.apache.tools.ant.*;
import org.apache.tools.ant.taskdefs.*;
import org.apache.tools.ant.types.*;
import org.apache.tools.ant.taskdefs.ExecTask;
/**
* Websphere deployment tool that augments the ejbjar task.
* @author <mailto:[EMAIL PROTECTED]>Maneesh Sahu</mailto>
*/
public class WebsphereDeploymentTool extends GenericDeploymentTool {
/**
* Enumerated attribute with the values for the database vendor types
*/
public static class DBVendor extends EnumeratedAttribute {
public String[] getValues() {
return new String[] {
"SQL92", "SQL99", "DB2UDBWIN_V71", "DB2UDBOS390_V6",
"DB2UDBAS400_V4R5",
"ORACLE_V8", "INFORMIX_V92", "SYBASE_V1192", "MSSQLSERVER_V7",
"MYSQL_V323"
};
}
}
public static final String PUBLICID_EJB11
= "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN";
public static final String PUBLICID_EJB20
= "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN";
protected static final String SCHEMA_DIR = "Schema/";
protected static final String WAS_EXT = "ibm-ejb-jar-ext.xmi";
protected static final String WAS_BND = "ibm-ejb-jar-bnd.xmi";
protected static final String WAS_CMP_MAP = "Map.mapxmi";
protected static final String WAS_CMP_SCHEMA = "Schema.dbxmi";
/** Instance variable that stores the suffix for the websphere jarfile. */
private String jarSuffix = ".jar";
/** Instance variable that stores the location of the ejb 1.1 DTD file. */
private String ejb11DTD;
/** Instance variable that determines whether generic ejb jars are kept.
*/
private boolean keepgenerated = false;
private String additionalArgs = "";
private boolean keepGeneric = false;
private String compiler = null;
private boolean alwaysRebuild = true;
private boolean ejbdeploy = true;
/**
* Indicates if the old CMP location convention is to be used.
*/
private boolean newCMP = false;
/** The classpath to the websphere classes. */
private Path wasClasspath = null;
/** The DB Vendor name, the EJB is persisted against */
private String dbVendor;
/** The name of the database to create. (For top-down mapping only) */
private String dbName;
/** The name of the schema to create. (For top-down mappings only) */
private String dbSchema;
/** true - Only generate the deployment code, do not run RMIC or Javac */
private boolean codegen;
/** true - Only output error messages, suppress informational messages */
private boolean quiet = true;
/** true - Disable the validation steps */
private boolean novalidate;
/** true - Disable warning and informational messages */
private boolean nowarn;
/** true - Disable informational messages */
private boolean noinform;
/** true - Enable internal tracing */
private boolean trace;
/** Additional options for RMIC */
private String rmicOptions;
/** true- Use the WebSphere 3.5 compatible mapping rules */
private boolean use35MappingRules;
/** the scratchdir for the ejbdeploy operation */
private String tempdir = "_ejbdeploy_temp";
/**
* Get the classpath to the websphere classpaths
*/
public Path createWASClasspath() {
if (wasClasspath == null) {
wasClasspath = new Path(getTask().getProject());
}
return wasClasspath.createPath();
}
public void setWASClasspath(Path wasClasspath) {
this.wasClasspath = wasClasspath;
}
/**
* Sets the DB Vendor for the Entity Bean mapping
*/
public void setDbvendor(DBVendor dbvendor) {
this.dbVendor = dbvendor.getValue();
}
/**
* Sets the name of the Database to create
* @param String
*/
public void setDbname(String dbName) {
this.dbName = dbName;
}
/**
* Sets the name of the schema to create
* @param String
*/
public void setDbschema(String dbSchema) {
this.dbSchema = dbSchema;
}
/**
* (true) Only generate the deployment code, do not run RMIC or Javac
* @param boolean
*/
public void setCodegen(boolean codegen) {
this.codegen = codegen;
}
/**
* (true) Only output error messages, suppress informational messages
* @param boolean
*/
public void setQuiet(boolean quiet) {
this.quiet = quiet;
}
/**
* (true) Disable the validation steps
* @param boolean
*/
public void setNovalidate(boolean novalidate) {
this.novalidate = novalidate;
}
/**
* (true) Disable warning and informational messages
* @param boolean
*/
public void setNowarn(boolean nowarn) {
this.nowarn = nowarn;
}
/**
* (true) Disable informational messages
* @param boolean
*/
public void setNoinform(boolean noinfom) {
this.noinform = noinform;
}
/**
* (true) Enable internal tracing
* @param boolean
*/
public void setTrace(boolean trace) {
this.trace = trace;
}
/**
* (true) Use the WebSphere 3.5 compatible mapping rules
* @param boolean
*/
public void setUse35(boolean attr) {
use35MappingRules = attr;
}
/**
* The compiler (switch <code>-compiler</code>) to use
*/
public void setCompiler(String compiler) {
this.compiler = compiler;
}
/**
* Set the rebuild flag to false to only update changes in the
* jar rather than rerunning ejbdeploy
*/
public void setRebuild(boolean rebuild) {
this.alwaysRebuild = rebuild;
}
/**
* Setter used to store the suffix for the generated websphere jar file.
* @param inString the string to use as the suffix.
*/
public void setSuffix(String inString) {
this.jarSuffix = inString;
}
/**
* Setter used to store the value of keepGeneric
* @param inValue a string, either 'true' or 'false'.
*/
public void setKeepgeneric(boolean inValue) {
this.keepGeneric = inValue;
}
/**
* Sets whether -keepgenerated is passed to ejbdeploy (that is,
* the .java source files are kept).
* @param inValue either 'true' or 'false'
*/
public void setKeepgenerated(String inValue) {
this.keepgenerated = Boolean.valueOf(inValue).booleanValue();
}
/**
* Decide, wether ejbdeploy should be called or not
* @param ejbdeploy
*/
public void setEjbdeploy(boolean ejbdeploy) {
this.ejbdeploy = ejbdeploy;
}
/**
* sets some additional args to send to ejbdeploy.
*/
public void setArgs(String args) {
this.additionalArgs = args;
}
/**
* Setter used to store the location of the Sun's Generic EJB DTD.
* This can be a file on the system or a resource on the classpath.
* @param inString the string to use as the DTD location.
*/
public void setEJBdtd(String inString) {
this.ejb11DTD = inString;
}
/**
* Set the value of the oldCMP scheme. This is an antonym for
* newCMP
*/
public void setOldCMP(boolean oldCMP) {
this.newCMP = !oldCMP;
}
/**
* Set the value of the newCMP scheme. The old CMP scheme locates the
* websphere CMP descriptor based on the naming convention where the
* websphere CMP file is expected to be named with the bean name as the
prefix.
*
* Under this scheme the name of the CMP descriptor does not match the
name
* actually used in the main websphere EJB descriptor. Also, descriptors
which
* contain multiple CMP references could not be used.
*
*/
public void setNewCMP(boolean newCMP) {
this.newCMP = newCMP;
}
/**
* Sets the temporary directory for the ejbdeploy task
*/
public void setTempdir(String tempdir) {
this.tempdir = tempdir;
}
protected DescriptorHandler getDescriptorHandler(File srcDir) {
DescriptorHandler handler = new DescriptorHandler(getTask(), srcDir);
// register all the DTDs, both the ones that are known and
// any supplied by the user
handler.registerDTD(PUBLICID_EJB11, ejb11DTD);
for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation)i.next();
handler.registerDTD(dtdLocation.getPublicId(),
dtdLocation.getLocation());
}
return handler;
}
protected DescriptorHandler getWebsphereDescriptorHandler(final File
srcDir) {
DescriptorHandler handler = new DescriptorHandler(getTask(), srcDir) {
protected void processElement() {
}
};
for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation)i.next();
handler.registerDTD(dtdLocation.getPublicId(),
dtdLocation.getLocation());
}
return handler;
}
/**
* Add any vendor specific files which should be included in the
* EJB Jar.
*/
protected void addVendorFiles(Hashtable ejbFiles, String baseName) {
String ddPrefix = (usingBaseJarName() ? "" : baseName);
String dbPrefix = (dbVendor == null)? "": dbVendor + "-";
// Get the Extensions document
File websphereEXT = new File(getConfig().descriptorDir, ddPrefix +
WAS_EXT);
if (websphereEXT.exists()) {
ejbFiles.put(META_DIR + WAS_EXT,
websphereEXT);
} else {
log("Unable to locate websphere extensions. It was expected to be
in " +
websphereEXT.getPath(), Project.MSG_VERBOSE);
}
File websphereBND = new File(getConfig().descriptorDir, ddPrefix +
WAS_BND);
if (websphereBND.exists()) {
ejbFiles.put(META_DIR + WAS_BND,
websphereBND);
}else {
log("Unable to locate websphere bindings. It was expected to be in
" +
websphereBND.getPath(), Project.MSG_VERBOSE);
}
if (!newCMP) {
log("The old method for locating CMP files has been DEPRECATED.",
Project.MSG_VERBOSE);
log("Please adjust your websphere descriptor and set
newCMP=\"true\" " +
"to use the new CMP descriptor inclusion mechanism. ",
Project.MSG_VERBOSE);
}
else {
// We attempt to put in the MAP and Schema files of CMP beans
try
{
// Add the Map file
File websphereMAP = new File(getConfig().descriptorDir,
ddPrefix + dbPrefix +
WAS_CMP_MAP);
if (websphereMAP.exists()) {
ejbFiles.put(META_DIR + WAS_CMP_MAP,
websphereMAP);
} else {
log("Unable to locate the websphere Map: " +
websphereMAP.getPath(), Project.MSG_VERBOSE);
}
File websphereSchema = new File(getConfig().descriptorDir,
ddPrefix + dbPrefix +
WAS_CMP_SCHEMA);
if (websphereSchema.exists()) {
ejbFiles.put(META_DIR + SCHEMA_DIR + WAS_CMP_SCHEMA,
websphereSchema);
} else {
log("Unable to locate the websphere Schema: " +
websphereSchema.getPath(), Project.MSG_VERBOSE);
}
// Theres nothing else to see here...keep
moving sonny
}
catch(Exception e)
{
String msg = "Exception while adding Vendor specific files:
" +
e.toString();
throw new BuildException(msg, e);
}
}
}
/**
* Get the vendor specific name of the Jar that will be output. The
modification date
* of this jar will be checked against the dependent bean classes.
*/
File getVendorOutputJarFile(String baseName) {
return new File(getDestDir(), baseName + jarSuffix);
}
/**
* Gets the options for the EJB Deploy operation
* @return String
*/
protected String getOptions() {
// Set the options
StringBuffer options = new StringBuffer();
if (dbVendor != null) {
options.append(" -dbvendor ").append(dbVendor);
}
if (dbName != null) {
options.append(" -dbname \"").append(dbName).append("\"");
}
if (dbSchema != null) {
options.append(" -dbschema \"").append(dbSchema).append("\"");
}
if (codegen) {
options.append(" -codegen");
}
if (quiet) {
options.append(" -quiet");
}
if (novalidate) {
options.append(" -novalidate");
}
if (nowarn) {
options.append(" -nowarn");
}
if (noinform) {
options.append(" -noinform");
}
if (trace) {
options.append(" -trace");
}
if (use35MappingRules) {
options.append(" -35");
}
if (rmicOptions != null) {
options.append(" -rmic \"").append(rmicOptions).append("\"");
}
return options.toString();
} // end getOptions
/**
* Helper method invoked by execute() for each websphere jar to be built.
* Encapsulates the logic of constructing a java task for calling
* websphere.ejbdeploy and executing it.
* @param sourceJar java.io.File representing the source (EJB1.1) jarfile.
* @param destJar java.io.File representing the destination, websphere
* jarfile.
*/
private void buildWebsphereJar(File sourceJar, File destJar) {
try {
if (ejbdeploy) {
String args =
" " + sourceJar.getPath() +
" " + tempdir +
" " + destJar.getPath() +
" " + getOptions();
if (getCombinedClasspath() != null &&
getCombinedClasspath().toString().length() > 0)
args += " -cp " + getCombinedClasspath();
// Why do my ""'s get stripped away???
log("EJB Deploy Options: " + args, Project.MSG_VERBOSE);
Java javaTask = (Java)getTask().getProject().createTask("java");
// Set the JvmArgs
javaTask.createJvmarg().setValue("-Xms64m");
javaTask.createJvmarg().setValue("-Xmx128m");
// Set the Environment variable
Environment.Variable var = new Environment.Variable();
var.setKey("websphere.lib.dir");
var.setValue(getTask().getProject().getProperty("websphere.home") + "/lib");
javaTask.addSysproperty(var);
// Set the working directory
javaTask.setDir(new
File(getTask().getProject().getProperty("websphere.home")));
// Set the Java class name
javaTask.setTaskName("ejbdeploy");
javaTask.setClassname("com.ibm.etools.ejbdeploy.EJBDeploy");
Commandline.Argument arguments = javaTask.createArg();
arguments.setLine(args);
Path classpath = wasClasspath;
if (classpath == null) {
classpath = getCombinedClasspath();
}
if (classpath != null) {
javaTask.setClasspath(classpath);
javaTask.setFork(true);
}
else {
javaTask.setFork(true);
}
log("Calling websphere.ejbdeploy for " + sourceJar.toString(),
Project.MSG_VERBOSE);
javaTask.execute();
}
}
catch (Exception e) {
// Have to catch this because of the semantics of calling main()
String msg = "Exception while calling ejbdeploy. Details: " +
e.toString();
throw new BuildException(msg, e);
}
}
/**
* Method used to encapsulate the writing of the JAR file. Iterates over
the
* filenames/java.io.Files in the Hashtable stored on the instance
variable
* ejbFiles.
*/
protected void writeJar(String baseName, File jarFile, Hashtable files,
String publicId)
throws BuildException
{
if (ejbdeploy) {
// create the -generic.jar, if required
File genericJarFile = super.getVendorOutputJarFile(baseName);
super.writeJar(baseName, genericJarFile, files, publicId);
// create the output .jar, if required
if (alwaysRebuild || isRebuildRequired(genericJarFile, jarFile)) {
buildWebsphereJar(genericJarFile, jarFile);
}
if (!keepGeneric) {
log("deleting generic jar " + genericJarFile.toString(),
Project.MSG_VERBOSE);
genericJarFile.delete();
}
}
else {
// create the "undeployed" output .jar, if required
super.writeJar(baseName, jarFile, files, publicId);
}
/*
// need to create a generic jar first.
File genericJarFile = super.getVendorOutputJarFile(baseName);
super.writeJar(baseName, genericJarFile, files, publicId);
if (alwaysRebuild || isRebuildRequired(genericJarFile, jarFile)) {
buildWebsphereJar(genericJarFile, jarFile);
}
if (!keepGeneric) {
log("deleting generic jar " + genericJarFile.toString(),
Project.MSG_VERBOSE);
genericJarFile.delete();
}
*/
}
/**
* Called to validate that the tool parameters have been configured.
*
*/
public void validateConfigured() throws BuildException {
super.validateConfigured();
}
/**
* Helper method to check to see if a websphere EBJ1.1 jar needs to be
rebuilt using
* ejbdeploy. Called from writeJar it sees if the "Bean" classes are
the only thing that needs
* to be updated and either updates the Jar with the Bean classfile or
returns true,
* saying that the whole websphere jar needs to be regened with
ejbdeploy. This allows faster
* build times for working developers.
* <p>
* The way websphere ejbdeploy works is it creates wrappers for the
publicly defined methods as
* they are exposed in the remote interface. If the actual bean changes
without changing the
* the method signatures then only the bean classfile needs to be updated
and the rest of the
* websphere jar file can remain the same. If the Interfaces, ie. the
method signatures change
* or if the xml deployment dicriptors changed, the whole jar needs to be
rebuilt with ejbdeploy.
* This is not strictly true for the xml files. If the JNDI name changes
then the jar doesnt
* have to be rebuild, but if the resources references change then it
does. At this point the
* websphere jar gets rebuilt if the xml files change at all.
*
* @param genericJarFile java.io.File The generic jar file.
* @param websphereJarFile java.io.File The websphere jar file to check
to see if it needs to be rebuilt.
*/
protected boolean isRebuildRequired(File genericJarFile, File
websphereJarFile)
{
boolean rebuild = false;
JarFile genericJar = null;
JarFile wasJar = null;
File newwasJarFile = null;
JarOutputStream newJarStream = null;
try
{
log("Checking if websphere Jar needs to be rebuilt for jar " +
websphereJarFile.getName(),
Project.MSG_VERBOSE);
// Only go forward if the generic and the websphere file both
exist
if (genericJarFile.exists() && genericJarFile.isFile()
&& websphereJarFile.exists() && websphereJarFile.isFile())
{
//open jar files
genericJar = new JarFile(genericJarFile);
wasJar = new JarFile(websphereJarFile);
Hashtable genericEntries = new Hashtable();
Hashtable wasEntries = new Hashtable();
Hashtable replaceEntries = new Hashtable();
//get the list of generic jar entries
for (Enumeration e = genericJar.entries();
e.hasMoreElements();)
{
JarEntry je = (JarEntry)e.nextElement();
genericEntries.put(je.getName().replace('\\',
'/'), je);
}
//get the list of websphere jar entries
for (Enumeration e = wasJar.entries() ;
e.hasMoreElements();)
{
JarEntry je = (JarEntry)e.nextElement();
wasEntries.put(je.getName(), je);
}
//Cycle Through generic and make sure its in
websphere
ClassLoader genericLoader =
getClassLoaderFromJar(genericJarFile);
for (Enumeration e = genericEntries.keys();
e.hasMoreElements();)
{
String filepath = (String)e.nextElement();
if (wasEntries.containsKey(filepath)) //
File name/path match
{
// Check files see if same
JarEntry genericEntry =
(JarEntry)genericEntries.get(filepath);
JarEntry wasEntry =
(JarEntry)wasEntries.get(filepath);
if ((genericEntry.getCrc() !=
wasEntry.getCrc()) || // Crc's Match
(genericEntry.getSize() !=
wasEntry.getSize()) ) // Size Match
{
if
(genericEntry.getName().endsWith(".class"))
{
//File are different
see if its an object or an interface
String classname =
genericEntry.getName().replace(File.separatorChar,'.');
classname =
classname.substring(0,classname.lastIndexOf(".class"));
Class genclass =
genericLoader.loadClass(classname);
if
(genclass.isInterface())
{
//Interface
changed rebuild jar.
log("Interface
" + genclass.getName() + " has changed",Project.MSG_VERBOSE);
rebuild = true;
break;
}
else
{
//Object class
Changed update it.
replaceEntries.put(filepath, genericEntry);
}
}
else
{
// is it the manifest.
If so ignore it
if
(!genericEntry.getName().equals("META-INF/MANIFEST.MF")) {
//File other then
class changed rebuild
log("Non class file
" + genericEntry.getName() + " has changed",Project.MSG_VERBOSE);
rebuild = true;
}
break;
}
}
}
else // a file doesnt exist rebuild
{
log("File " + filepath + " not present
in websphere jar",Project.MSG_VERBOSE);
rebuild = true;
break;
}
}
if (!rebuild)
{
log("No rebuild needed - updating
jar",Project.MSG_VERBOSE);
newwasJarFile = new
File(websphereJarFile.getAbsolutePath() + ".temp");
if (newwasJarFile.exists()) {
newwasJarFile.delete();
}
newJarStream = new JarOutputStream(new
FileOutputStream(newwasJarFile));
newJarStream.setLevel(0);
//Copy files from old websphere jar
for (Enumeration e = wasEntries.elements() ;
e.hasMoreElements();)
{
byte[] buffer = new byte[1024];
int bytesRead;
InputStream is;
JarEntry je = (JarEntry)e.nextElement();
if (je.getCompressedSize() == -1 ||
je.getCompressedSize() ==
je.getSize()) {
newJarStream.setLevel(0);
}
else {
newJarStream.setLevel(9);
}
// Update with changed Bean class
if
(replaceEntries.containsKey(je.getName()))
{
log("Updating Bean class from
generic Jar " + je.getName(),
Project.MSG_VERBOSE);
// Use the entry from the
generic jar
je =
(JarEntry)replaceEntries.get(je.getName());
is =
genericJar.getInputStream(je);
}
else //use fle from original websphere
jar
{
is = wasJar.getInputStream(je);
}
newJarStream.putNextEntry(new
JarEntry(je.getName()));
while ((bytesRead = is.read(buffer)) !=
-1)
{
newJarStream.write(buffer,0,bytesRead);
}
is.close();
}
}
else
{
log("websphere Jar rebuild needed due to
changed interface or XML",Project.MSG_VERBOSE);
}
}
else
{
rebuild = true;
}
}
catch(ClassNotFoundException cnfe)
{
String cnfmsg = "ClassNotFoundException while processing
ejb-jar file"
+ ". Details: "
+ cnfe.getMessage();
throw new BuildException(cnfmsg, cnfe);
}
catch(IOException ioe) {
String msg = "IOException while processing ejb-jar file "
+ ". Details: "
+ ioe.getMessage();
throw new BuildException(msg, ioe);
}
finally {
// need to close files and perhaps rename output
if (genericJar != null) {
try {
genericJar.close();
}
catch (IOException closeException) {}
}
if (wasJar != null) {
try {
wasJar.close();
}
catch (IOException closeException) {}
}
if (newJarStream != null) {
try {
newJarStream.close();
}
catch (IOException closeException) {}
websphereJarFile.delete();
newwasJarFile.renameTo(websphereJarFile);
if (!websphereJarFile.exists()) {
rebuild = true;
}
}
}
return rebuild;
}
/**
* Helper method invoked by isRebuildRequired to get a ClassLoader for
* a Jar File passed to it.
*
* @param classjar java.io.File representing jar file to get classes from.
*/
protected ClassLoader getClassLoaderFromJar(File classjar) throws
IOException
{
Path lookupPath = new Path(getTask().getProject());
lookupPath.setLocation(classjar);
Path classpath = getCombinedClasspath();
if (classpath != null) {
lookupPath.append(classpath);
}
return new AntClassLoader(getTask().getProject(), lookupPath);
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>