These patches along with additional classes introduce / contain:
o a fileset like depset for use in jar-/zip-task o automatic packaging of dependent class in ejbjar o inclusion of manifest-files in ejbjar based on a naming convention basename-ejb-jar.xml basename-manifest.mf ... Holger
Index:
src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java,v
retrieving revision 1.23
diff -u -r1.23 GenericDeploymentTool.java
---
src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java
2001/10/28 21:30:20 1.23
+++
src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java
2001/11/08 10:20:23
@@ -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,12 @@
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.types.*;
+
+import de.fub.bytecode.classfile.*;
+import de.fub.bytecode.*;
+
import org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Location;
@@ -79,6 +88,7 @@
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.DepSet;
/**
* A deployment tool which creates generic EJB jars. Generic jars contains
@@ -339,8 +349,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 +595,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 +607,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 +672,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 +760,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();
-
- // 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);
-
- // 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);
- }
- }
- 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);
- }
- } //if
- } // while
- }
-
- 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 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);
+
+ do {
+ i = newSet.iterator();
+ while (i.hasNext()) {
+ String fileName = base + ((String)i.next()).replace('/',
File.separatorChar) + ".class";
+
+ try {
+ JavaClass javaClass = new ClassParser(fileName).parse();
+ javaClass.accept(visitor);
+ }
+ catch (IOException e) {
+ log("exception: " + e.getMessage(), Project.MSG_INFO);
+ }
+ }
+ newSet.clear();
+ newSet.addAll(visitor.getDependencies());
+ visitor.clearDependencies();
+
+ 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);
+
+ 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);
+ }
}
-
- 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);
- }
-
- addSuperClass(superClass.getSuperclass(), checkEntries);
- }
- }
- }
+
/**
* Returns a Classloader object which parses the passed in generic EjbJar
classpath.
Index: src/main/org/apache/tools/ant/taskdefs/Zip.java
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Zip.java,v
retrieving revision 1.55
diff -u -r1.55 Zip.java
--- src/main/org/apache/tools/ant/taskdefs/Zip.java 2001/11/01 19:33:13
1.55
+++ src/main/org/apache/tools/ant/taskdefs/Zip.java 2001/11/08 10:20:56
@@ -63,6 +63,7 @@
import java.io.ByteArrayInputStream;
import java.util.Hashtable;
+import java.util.HashSet;
import java.util.Stack;
import java.util.Vector;
@@ -76,6 +77,7 @@
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.ZipFileSet;
import org.apache.tools.ant.types.ZipScanner;
+import org.apache.tools.ant.types.DepSet;
import org.apache.tools.ant.util.SourceFileScanner;
import org.apache.tools.ant.util.MergingMapper;
import org.apache.tools.zip.ZipOutputStream;
@@ -180,6 +182,12 @@
filesets.addElement(set);
}
+ /**
+ * Adds a set of files (nested fileset attribute).
+ */
+ public void addDepset(DepSet set) {
+ filesets.addElement(set);
+ }
/** Possible behaviors when there are no matching files for the task. */
public static class WhenEmpty extends EnumeratedAttribute {
/* * The Apache Software License, Version 1.1 * * Copyright (c) 1999 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 acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements 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.types; import java.io.File; import java.util.Stack; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; /** * A DependSet is a FileSet, that enlists all classes that depend on a * certain class. * * A DependSet extends FileSets and uses another FileSet as input. The * nested FileSet attribute provides the domain, that is used for searching * for dependent classes * * @author <a href="mailto:[EMAIL PROTECTED]">Holger Engels</a> */ public class DepSet extends FileSet { private File baseClass = null; /** * Set the directory for the fileset. Prevents both "dir" and "src" * from being specified. */ public void setBaseClass(File baseClass) throws BuildException { this.baseClass = baseClass; } public void setDir(File dir) throws BuildException { super.setDir(dir); } /** * Return the DirectoryScanner associated with this FileSet. */ public DirectoryScanner getDirectoryScanner(Project p) { DependScanner scanner = new DependScanner(); scanner.setBasedir(getDir(p)); scanner.setBaseClass(baseClass); scanner.scan(); return scanner; } }
package org.apache.tools.ant.types;
import java.io.*;
import java.util.*;
import de.fub.bytecode.classfile.*;
import de.fub.bytecode.*;
public class Dependencies
implements Visitor
{
private boolean verbose = false;
private JavaClass javaClass;
private ConstantPool constantPool;
private Set dependencies = new HashSet();
public void clearDependencies() {
dependencies.clear();
}
public Set getDependencies() {
return dependencies;
}
public void visitCode(Code obj) {}
public void visitCodeException(CodeException obj) {}
public void visitConstantClass(ConstantClass obj) {
if (verbose) {
System.out.println("visit ConstantClass");
System.out.println(obj.getConstantValue(constantPool));
}
dependencies.add("" + obj.getConstantValue(constantPool));
}
public void visitConstantDouble(ConstantDouble obj) {}
public void visitConstantFieldref(ConstantFieldref obj) {}
public void visitConstantFloat(ConstantFloat obj) {}
public void visitConstantInteger(ConstantInteger obj) {}
public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj)
{}
public void visitConstantLong(ConstantLong obj) {}
public void visitConstantMethodref(ConstantMethodref obj) {}
public void visitConstantNameAndType(ConstantNameAndType obj) {}
public void visitConstantPool(ConstantPool obj) {
if (verbose)
System.out.println("visit ConstantPool");
this.constantPool = obj;
// visit constants
for(int idx = 0; idx < constantPool.getLength(); idx++) {
Constant c = constantPool.getConstant(idx);
if (c != null)
c.accept(this);
}
}
public void visitConstantString(ConstantString obj) {}
public void visitConstantUtf8(ConstantUtf8 obj) {}
public void visitConstantValue(ConstantValue obj) {}
public void visitDeprecated(Deprecated obj) {}
public void visitExceptionTable(ExceptionTable obj) {}
public void visitField(Field obj) {
if (verbose) {
System.out.println("visit Field");
System.out.println(obj.getSignature());
}
addClasses(obj.getSignature());
}
public void visitInnerClass(InnerClass obj) {}
public void visitInnerClasses(InnerClasses obj) {}
public void visitJavaClass(JavaClass obj) {
if (verbose)
System.out.println("visit JavaClass");
this.javaClass = obj;
dependencies.add(javaClass.getClassName().replace('.', '/'));
// visit constant pool
javaClass.getConstantPool().accept(this);
// visit fields
Field[] fields = obj.getFields();
for(int i=0; i < fields.length; i++)
fields[i].accept(this);
// visit methods
Method[] methods = obj.getMethods();
for(int i=0; i < methods.length; i++)
methods[i].accept(this);
}
public void visitLineNumber(LineNumber obj) {}
public void visitLineNumberTable(LineNumberTable obj) {}
public void visitLocalVariable(LocalVariable obj) {}
public void visitLocalVariableTable(LocalVariableTable obj) {}
public void visitMethod(Method obj) {
if (verbose) {
System.out.println("visit Method");
System.out.println(obj.getSignature());
}
String signature = obj.getSignature();
int pos = signature.indexOf(")");
addClasses(signature.substring(1, pos));
addClasses(signature.substring(pos + 1));
}
public void visitSourceFile(SourceFile obj) {}
public void visitSynthetic(Synthetic obj) {}
public void visitUnknown(Unknown obj) {}
public void visitStackMap(StackMap obj) {}
public void visitStackMapEntry(StackMapEntry obj) {}
void addClasses(String string) {
StringTokenizer tokens = new StringTokenizer(string, ";");
while (tokens.hasMoreTokens())
addClass(tokens.nextToken());
}
void addClass(String string) {
int pos = string.indexOf('L');
if (pos != -1)
dependencies.add(string.substring(pos+1));
}
public static void main(String[] args) {
try {
Dependencies visitor = new Dependencies();
Set set = new TreeSet();
Set newSet = new HashSet();
int o=0;
String arg = null;
if ("-base".equals(args[0])) {
arg = args[1];
if (!arg.endsWith(File.separator))
arg = arg + File.separator;
o=2;
}
final String base = arg;
for (int i=o; i < args.length; i++) {
String fileName = args[i].substring(0, args[i].length() -
".class".length());
if (base != null && fileName.startsWith(base))
fileName = fileName.substring(base.length());
newSet.add(fileName);
}
set.addAll(newSet);
do {
Iterator i = newSet.iterator();
while (i.hasNext()) {
String fileName = i.next() + ".class";
if (base != null)
fileName = base + fileName;
JavaClass javaClass = new ClassParser(fileName).parse();
javaClass.accept(visitor);
}
newSet.clear();
newSet.addAll(visitor.getDependencies());
visitor.clearDependencies();
applyFilter(newSet, new Filter() {
public boolean accept(Object object) {
String fileName = object + ".class";
if (base != null)
fileName = base + fileName;
return new File(fileName).exists();
}
});
newSet.removeAll(set);
set.addAll(newSet);
}
while (newSet.size() > 0);
Iterator i = set.iterator();
while (i.hasNext()) {
System.out.println(i.next());
}
}
catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace(System.err);
}
}
public static void applyFilter(Collection collection, Filter filter) {
Iterator i = collection.iterator();
while (i.hasNext()) {
Object next = i.next();
if (!filter.accept(next))
i.remove();
}
}
}
/* * 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 acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements 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.types; import java.io.*; import java.util.*; import org.apache.tools.ant.*; import de.fub.bytecode.classfile.*; import de.fub.bytecode.*; /** * An interface used to describe the actions required by any type of * directory scanner. */ public class DependScanner extends DirectoryScanner { File basedir; File baseClass; List included = new LinkedList(); /** * Sets the basedir for scanning. This is the directory that is scanned * recursively. * * @param basedir the (non-null) basedir for scanning */ public void setBasedir(String basedir) { setBasedir(new File(basedir.replace('/',File.separatorChar).replace('\\',File.separatorChar))); } /** * Sets the basedir for scanning. This is the directory that is scanned * recursively. * * @param basedir the basedir for scanning */ public void setBasedir(File basedir) { this.basedir = basedir; } /** * Gets the basedir that is used for scanning. * * @return the basedir that is used for scanning */ public File getBasedir() { return basedir; } /** * Sets the domain, where dependant classes are searched * * @param domain the domain */ public void setBaseClass(File baseClass) { this.baseClass = baseClass; } /** * Get the names of the class files, baseClass depends on * * @return the names of the files */ public String[] getIncludedFiles() { int count = included.size(); String[] files = new String[count]; for (int i = 0; i < count; i++) { files[i] = included.get(i) + ".class"; //System.err.println(" " + files[i]); } return files; } /** * Scans the base directory for files that baseClass depends on * * @exception IllegalStateException when basedir was set incorrecly */ public void scan() { Dependencies visitor = new Dependencies(); Set set = new TreeSet(); Set newSet = new HashSet(); final String base; String start; try { base = basedir.getCanonicalPath() + File.separator; start = baseClass.getCanonicalPath(); } catch (Exception e) { throw new IllegalArgumentException(e.getMessage()); } start = start.substring(base.length(), start.length() - ".class".length()).replace(File.separatorChar, '/'); newSet.add(start); set.add(start); do { Iterator i = newSet.iterator(); while (i.hasNext()) { String fileName = base + ((String)i.next()).replace('/', File.separatorChar) + ".class"; try { JavaClass javaClass = new ClassParser(fileName).parse(); javaClass.accept(visitor); } catch (IOException e) { System.err.println("exception: " + e.getMessage()); } } newSet.clear(); newSet.addAll(visitor.getDependencies()); visitor.clearDependencies(); 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); included.clear(); included.addAll(set); } public void addDefaultExcludes() {} public String[] getExcludedDirectories() { return null; }; public String[] getExcludedFiles() { return null; } public String[] getIncludedDirectories() { return new String[0]; } public String[] getNotIncludedDirectories() { return null; } public String[] getNotIncludedFiles() { return null; } public void setExcludes(String[] excludes) {} public void setIncludes(String[] includes) {} public void setCaseSensitive(boolean isCaseSensitive) {} }
bcel.jar
Description: Zip archive
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
