You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oozie.apache.org by km...@apache.org on 2019/02/28 10:29:06 UTC
[oozie] branch master updated: OOZIE-3409 Oozie Server : Memory
leak in EL evaluation (asalamon74 via kmarton)
This is an automated email from the ASF dual-hosted git repository.
kmarton pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/oozie.git
The following commit(s) were added to refs/heads/master by this push:
new fe45dc1 OOZIE-3409 Oozie Server : Memory leak in EL evaluation (asalamon74 via kmarton)
fe45dc1 is described below
commit fe45dc17efebb74eb80e817d3123332434097d48
Author: Julia Kinga Marton <km...@apache.org>
AuthorDate: Thu Feb 28 11:28:54 2019 +0100
OOZIE-3409 Oozie Server : Memory leak in EL evaluation (asalamon74 via kmarton)
---
core/pom.xml | 31 ++++++----
.../oozie/command/coord/CoordSubmitXCommand.java | 23 ++++----
.../apache/oozie/util/ELEvaluationException.java | 4 ++
.../java/org/apache/oozie/util/ELEvaluator.java | 67 ++++++----------------
.../java/org/apache/oozie/util/StringUtils.java | 53 +++++++++++++++++
.../apache/oozie/command/wf/TestActionErrors.java | 5 +-
.../org/apache/oozie/util/TestELEvaluator.java | 34 +----------
.../org/apache/oozie/util/TestStringUtils.java | 56 +++++++++++++++++-
examples/pom.xml | 10 ++++
pom.xml | 1 +
release-log.txt | 1 +
src/main/assemblies/distro.xml | 1 -
12 files changed, 180 insertions(+), 106 deletions(-)
diff --git a/core/pom.xml b/core/pom.xml
index c7558a3..6521967 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -122,6 +122,16 @@
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-minicluster</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>tomcat</groupId>
+ <artifactId>jasper-compiler</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>tomcat</groupId>
+ <artifactId>jasper-runtime</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
@@ -266,12 +276,6 @@
</dependency>
<dependency>
- <groupId>commons-el</groupId>
- <artifactId>commons-el</artifactId>
- <scope>compile</scope>
- </dependency>
-
- <dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<scope>compile</scope>
@@ -324,12 +328,6 @@
</dependency>
<dependency>
- <groupId>javax.servlet.jsp</groupId>
- <artifactId>jsp-api</artifactId>
- <scope>compile</scope>
- </dependency>
-
- <dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
@@ -517,6 +515,15 @@
<artifactId>spotbugs-annotations</artifactId>
<scope>provided</scope>
</dependency>
+
+
+ <dependency>
+ <groupId>org.mortbay.jasper</groupId>
+ <artifactId>apache-jsp</artifactId>
+ <version>${apache.jsp.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
</dependencies>
<build>
diff --git a/core/src/main/java/org/apache/oozie/command/coord/CoordSubmitXCommand.java b/core/src/main/java/org/apache/oozie/command/coord/CoordSubmitXCommand.java
index c1c6444..f46f254 100644
--- a/core/src/main/java/org/apache/oozie/command/coord/CoordSubmitXCommand.java
+++ b/core/src/main/java/org/apache/oozie/command/coord/CoordSubmitXCommand.java
@@ -82,6 +82,7 @@ import org.apache.oozie.util.ParamChecker;
import org.apache.oozie.util.ParameterVerifier;
import org.apache.oozie.util.ParameterVerifierException;
import org.apache.oozie.util.PropertiesUtils;
+import org.apache.oozie.util.StringUtils;
import org.apache.oozie.util.XConfiguration;
import org.apache.oozie.util.XmlUtils;
import org.jdom.Attribute;
@@ -143,7 +144,6 @@ public class CoordSubmitXCommand extends SubmitTransitionXCommand {
private ELEvaluator evalNofuncs = null;
private ELEvaluator evalData = null;
private ELEvaluator evalInst = null;
- private ELEvaluator evalAction = null;
private ELEvaluator evalSla = null;
private ELEvaluator evalTimeout = null;
private ELEvaluator evalInitialInstance = null;
@@ -391,8 +391,9 @@ public class CoordSubmitXCommand extends SubmitTransitionXCommand {
instanceValue = instance.getContent(0).toString();
boolean isInvalid = false;
try {
- isInvalid = evalAction.checkForExistence(instanceValue, ",");
- } catch (Exception e) {
+ isInvalid = StringUtils.checkStaticExistence(instanceValue, ",");
+ }
+ catch (Exception e) {
handleELParseException(eventType, dataType, instanceValue);
}
if (isInvalid) { // reaching this block implies instance is not empty i.e. length > 0
@@ -413,8 +414,9 @@ public class CoordSubmitXCommand extends SubmitTransitionXCommand {
instanceValue = instance.getContent(0).toString();
boolean isInvalid = false;
try {
- isInvalid = evalAction.checkForExistence(instanceValue, ",");
- } catch (Exception e) {
+ isInvalid = StringUtils.checkStaticExistence(instanceValue, ",");
+ }
+ catch (Exception e) {
handleELParseException(eventType, dataType, instanceValue);
}
if (isInvalid) { // reaching this block implies start instance is not empty i.e. length > 0
@@ -434,8 +436,9 @@ public class CoordSubmitXCommand extends SubmitTransitionXCommand {
instanceValue = instance.getContent(0).toString();
boolean isInvalid = false;
try {
- isInvalid = evalAction.checkForExistence(instanceValue, ",");
- } catch (Exception e) {
+ isInvalid = StringUtils.checkStaticExistence(instanceValue, ",");
+ }
+ catch (Exception e) {
handleELParseException(eventType, dataType, instanceValue);
}
if (isInvalid) { // reaching this block implies instance is not empty i.e. length > 0
@@ -450,9 +453,10 @@ public class CoordSubmitXCommand extends SubmitTransitionXCommand {
private void handleELParseException(String eventType, String dataType, String instanceValue)
throws CoordinatorJobException {
String correctAction = null;
- if(dataType.equals(COORD_INPUT_EVENTS_DATA_IN)) {
+ if (dataType.equals(COORD_INPUT_EVENTS_DATA_IN)) {
correctAction = "Coordinator app definition should have valid <instance> tag for data-in";
- } else if(dataType.equals(COORD_OUTPUT_EVENTS_DATA_OUT)) {
+ }
+ else if (dataType.equals(COORD_OUTPUT_EVENTS_DATA_OUT)) {
correctAction = "Coordinator app definition should have valid <instance> tag for data-out";
}
throw new CoordinatorJobException(ErrorCode.E1021, eventType + " instance '" + instanceValue
@@ -661,7 +665,6 @@ public class CoordSubmitXCommand extends SubmitTransitionXCommand {
evalFreq = CoordELEvaluator.createELEvaluatorForGroup(conf, "coord-job-submit-freq");
evalNofuncs = CoordELEvaluator.createELEvaluatorForGroup(conf, "coord-job-submit-nofuncs");
evalInst = CoordELEvaluator.createELEvaluatorForGroup(conf, "coord-job-submit-instances");
- evalAction = CoordELEvaluator.createELEvaluatorForGroup(conf, "coord-action-start");
evalTimeout = CoordELEvaluator.createELEvaluatorForGroup(conf, "coord-job-wait-timeout");
evalInitialInstance = CoordELEvaluator.createELEvaluatorForGroup(conf, "coord-job-submit-initial-instance");
}
diff --git a/core/src/main/java/org/apache/oozie/util/ELEvaluationException.java b/core/src/main/java/org/apache/oozie/util/ELEvaluationException.java
index a4df3b5..c4bdf43 100644
--- a/core/src/main/java/org/apache/oozie/util/ELEvaluationException.java
+++ b/core/src/main/java/org/apache/oozie/util/ELEvaluationException.java
@@ -23,6 +23,10 @@ package org.apache.oozie.util;
*/
public class ELEvaluationException extends Exception {
+ public ELEvaluationException(String message) {
+ super(message);
+ }
+
/**
* Create a EL evaluation exception.
*
diff --git a/core/src/main/java/org/apache/oozie/util/ELEvaluator.java b/core/src/main/java/org/apache/oozie/util/ELEvaluator.java
index 90d7977..64f7816 100644
--- a/core/src/main/java/org/apache/oozie/util/ELEvaluator.java
+++ b/core/src/main/java/org/apache/oozie/util/ELEvaluator.java
@@ -18,10 +18,10 @@
package org.apache.oozie.util;
-import org.apache.commons.el.ExpressionEvaluatorImpl;
-import org.apache.commons.el.ExpressionString;
+import javax.el.ELException;
+import org.apache.jasper.el.ExpressionEvaluatorImpl;
-import javax.servlet.jsp.el.ELException;
+import javax.el.ExpressionFactory;
import javax.servlet.jsp.el.ExpressionEvaluator;
import javax.servlet.jsp.el.FunctionMapper;
import javax.servlet.jsp.el.VariableResolver;
@@ -35,6 +35,8 @@ import java.util.Map;
*/
public class ELEvaluator {
+ public static final XLog LOG = XLog.getLog(ELEvaluator.class);
+
/**
* Provides functions and variables for the EL evaluator. <p> All functions and variables in the context of an EL
* evaluator are accessible from EL expressions.
@@ -47,8 +49,8 @@ public class ELEvaluator {
* Create an empty context.
*/
public Context() {
- vars = new HashMap<String, Object>();
- functions = new HashMap<String, Method>();
+ vars = new HashMap<>();
+ functions = new HashMap<>();
}
/**
@@ -122,9 +124,13 @@ public class ELEvaluator {
}
return functions.get(name);
}
+
+ public String toString() {
+ return vars.toString() + " "+functions.toString();
+ }
}
- private static ThreadLocal<ELEvaluator> current = new ThreadLocal<ELEvaluator>();
+ private static ThreadLocal<ELEvaluator> current = new ThreadLocal<>();
/**
* If within the scope of a EL evaluation call, it gives access to the ELEvaluator instance performing the EL
@@ -140,7 +146,8 @@ public class ELEvaluator {
private Context context;
- private ExpressionEvaluatorImpl evaluator = new ExpressionEvaluatorImpl();
+ private ExpressionFactory factory = ExpressionFactory.newInstance();
+ private ExpressionEvaluator evaluator = new ExpressionEvaluatorImpl(factory);
/**
* Creates an ELEvaluator with no functions and no variables defined.
@@ -197,16 +204,17 @@ public class ELEvaluator {
* @throws Exception thrown if an EL function failed due to a transient error or EL expression could not be
* evaluated.
*/
- @SuppressWarnings({"unchecked", "deprecation"})
+ @SuppressWarnings({"unchecked"})
public <T> T evaluate(String expr, Class<T> clazz) throws Exception {
ELEvaluator existing = current.get();
try {
current.set(this);
return (T) evaluator.evaluate(expr, clazz, context, context);
}
- catch (ELException ex) {
- if (ex.getRootCause() instanceof Exception) {
- throw (Exception) ex.getRootCause();
+ catch (RuntimeException ex) {
+ if (ex.getCause() instanceof Exception) {
+ LOG.debug("Unfolding exception", ex);
+ throw (Exception) ex.getCause();
}
else {
throw ex;
@@ -217,41 +225,4 @@ public class ELEvaluator {
}
}
- /**
- * Check if the input expression contains sequence statically. for example
- * identify if "," is present outside of a function invocation in the given
- * expression. Ex "${func('abc')},${func('def'}",
- *
- * @param expr - Expression string
- * @param sequence - char sequence to check in the input expression
- * @return true if present
- * @throws Exception Exception thrown if an EL function failed due to a
- * transient error or EL expression could not be parsed
- */
- public boolean checkForExistence(String expr, String sequence)
- throws Exception {
- try {
- Object exprString = evaluator.parseExpressionString(expr);
- if (exprString instanceof ExpressionString) {
- for (Object element : ((ExpressionString)exprString).getElements()) {
- if (element instanceof String &&
- element.toString().contains(sequence)) {
- return true;
- }
- }
- } else if (exprString instanceof String) {
- if (((String)exprString).contains(sequence)) {
- return true;
- }
- }
- return false;
- } catch (ELException ex) {
- if (ex.getRootCause() instanceof Exception) {
- throw (Exception) ex.getRootCause();
- }
- else {
- throw ex;
- }
- }
- }
}
diff --git a/core/src/main/java/org/apache/oozie/util/StringUtils.java b/core/src/main/java/org/apache/oozie/util/StringUtils.java
index 26079be..af7ccd6 100644
--- a/core/src/main/java/org/apache/oozie/util/StringUtils.java
+++ b/core/src/main/java/org/apache/oozie/util/StringUtils.java
@@ -49,5 +49,58 @@ public class StringUtils {
}
return str.intern();
}
+
+ /**
+ * Check if the input expression contains sequence statically. for example
+ * identify if "," is present outside of a function invocation in the given
+ * expression. Ex "${func('abc')},${func('def'}",
+ *
+ * @param expr - Expression string
+ * @param sequence - char sequence to check in the input expression
+ * @return true if present
+ */
+ public static boolean checkStaticExistence(String expr, String sequence) throws ELEvaluationException {
+ int curlyBracketDept = 0;
+ int functionDepth = 0;
+ int index = 0;
+ boolean foundSequence = false;
+ while (index < expr.length()) {
+ String substring = expr.substring(index);
+ if (substring.startsWith("${")) {
+ ++curlyBracketDept;
+ }
+ else if (substring.startsWith("}")) {
+ --curlyBracketDept;
+ if (curlyBracketDept < 0) {
+ throw new ELEvaluationException("Invalid curly bracket closing");
+ }
+ }
+ if (curlyBracketDept > 0) {
+ if (substring.startsWith("(")) {
+ ++functionDepth;
+ }
+ else if (substring.startsWith(")")) {
+ --functionDepth;
+ if (functionDepth < 0) {
+ throw new ELEvaluationException("Invalid function closing");
+ }
+ }
+ }
+ if (curlyBracketDept == 0 && substring.startsWith(sequence)) {
+ foundSequence = true;
+ }
+ if (curlyBracketDept > 0 && functionDepth == 0 && substring.startsWith(sequence)) {
+ foundSequence = true;
+ }
+ ++index;
+ }
+ if (curlyBracketDept != 0) {
+ throw new ELEvaluationException("Unclosed curly brackets");
+ }
+ if (functionDepth != 0) {
+ throw new ELEvaluationException("Unfinished function calling");
+ }
+ return foundSequence;
+ }
}
diff --git a/core/src/test/java/org/apache/oozie/command/wf/TestActionErrors.java b/core/src/test/java/org/apache/oozie/command/wf/TestActionErrors.java
index 519b384..c6fa540 100644
--- a/core/src/test/java/org/apache/oozie/command/wf/TestActionErrors.java
+++ b/core/src/test/java/org/apache/oozie/command/wf/TestActionErrors.java
@@ -259,9 +259,8 @@ public class TestActionErrors extends XDataTestCase {
public void testKillNodeErrorMessageError() throws Exception {
WorkflowActionBean killAction = _testKillNodeErrorMessage("wf-test-kill-node-message-error.xml");
assertEquals("E0756", killAction.getErrorCode());
- assertEquals("E0756: Exception parsing Kill node message [Encountered \"{\", expected one of [<INTEGER_LITERAL>, " +
- "<FLOATING_POINT_LITERAL>, <STRING_LITERAL>, \"true\", \"false\", \"null\", \"(\", \"-\", \"not\", " +
- "\"!\", \"empty\", <IDENTIFIER>]]", killAction.getErrorMessage());
+ assertTrue("Incorrect error message",
+ killAction.getErrorMessage().startsWith("E0756: Exception parsing Kill node message"));
assertEquals(WorkflowAction.Status.ERROR, killAction.getStatus());
}
diff --git a/core/src/test/java/org/apache/oozie/util/TestELEvaluator.java b/core/src/test/java/org/apache/oozie/util/TestELEvaluator.java
index 04a869c..260ca1d 100644
--- a/core/src/test/java/org/apache/oozie/util/TestELEvaluator.java
+++ b/core/src/test/java/org/apache/oozie/util/TestELEvaluator.java
@@ -18,14 +18,14 @@
package org.apache.oozie.util;
-import org.apache.oozie.test.XTestCase;
+import junit.framework.TestCase;
-import javax.servlet.jsp.el.ELException;
+import javax.el.ELException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
-public class TestELEvaluator extends XTestCase {
+public class TestELEvaluator extends TestCase {
public static String functionA() {
assertEquals("A", ELEvaluator.getCurrent().getVariable("a"));
@@ -170,33 +170,5 @@ public class TestELEvaluator extends XTestCase {
catch (ELEvaluationException ex) {
//nop
}
- catch (ELException ex) {
- fail();
- }
- }
-
- public void testCheckForExistence() throws Exception {
- ELEvaluator.Context support = new ELEvaluator.Context();
- support.setVariable("a", "A");
- support.addFunction("a", "a", functionA);
- support.addFunction("a", "d", functionD);
- ELEvaluator evaluator = new ELEvaluator(support);
- assertNull(ELEvaluator.getCurrent());
- assertEquals("a", evaluator.evaluate("${a:a()}", String.class));
- assertEquals("a,a", evaluator.evaluate("${a:a()},${a:a()}", String.class));
- try {
- evaluator.evaluate("${a:a(), a:a()}", String.class);
- fail("Evaluated bad expression");
- } catch (ELException ignore) { }
- assertTrue(evaluator.checkForExistence("${a:a()}${a:a()}!", "!"));
- assertTrue(evaluator.checkForExistence("${a:a()},${a:a()}", ","));
- assertFalse(evaluator.checkForExistence("${a:d('foo', 'bar')}", ","));
- try {
- evaluator.checkForExistence("${a:a(), a:a()}", ",");
- fail("Parsed bad expression");
- } catch (ELException ignore) { }
-
- assertNull(ELEvaluator.getCurrent());
}
-
}
diff --git a/core/src/test/java/org/apache/oozie/util/TestStringUtils.java b/core/src/test/java/org/apache/oozie/util/TestStringUtils.java
index 423d6be..427eeef 100644
--- a/core/src/test/java/org/apache/oozie/util/TestStringUtils.java
+++ b/core/src/test/java/org/apache/oozie/util/TestStringUtils.java
@@ -18,14 +18,24 @@
package org.apache.oozie.util;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
-import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
/**
* Test cases for the {@link StringUtils} class.
*/
public class TestStringUtils {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ public static final String ASSERT_MESSAGE_CHECK_STATIC_EXISTENCE = "Invalid checkStaticExistence return value";
+
/**
* Tests if a new line character is replaced by an empty string.
*/
@@ -58,4 +68,48 @@ public class TestStringUtils {
public void testTrimUnmodifiedString() {
assertEquals("A string", StringUtils.trim("A string"));
}
+
+ @Test
+ public void testCheckStaticExistenceWithValidExpressions() throws ELEvaluationException {
+ assertFalse(ASSERT_MESSAGE_CHECK_STATIC_EXISTENCE, StringUtils.checkStaticExistence("ab", ","));
+ assertTrue(ASSERT_MESSAGE_CHECK_STATIC_EXISTENCE, StringUtils.checkStaticExistence("${a:a()}${a:a()}!", "!"));
+ assertTrue(ASSERT_MESSAGE_CHECK_STATIC_EXISTENCE, StringUtils.checkStaticExistence("${a:a()},${a:a()}", ","));
+ assertFalse(ASSERT_MESSAGE_CHECK_STATIC_EXISTENCE, StringUtils.checkStaticExistence("${a:d('foo', 'bar')}", ","));
+ assertTrue(ASSERT_MESSAGE_CHECK_STATIC_EXISTENCE, StringUtils.checkStaticExistence("${a:a(), a:a()}", ","));
+ assertTrue(ASSERT_MESSAGE_CHECK_STATIC_EXISTENCE, StringUtils.checkStaticExistence("a,b", ","));
+ assertTrue(ASSERT_MESSAGE_CHECK_STATIC_EXISTENCE, StringUtils.checkStaticExistence("'a,b'", ","));
+ assertFalse(ASSERT_MESSAGE_CHECK_STATIC_EXISTENCE, StringUtils.checkStaticExistence("${func(a,b)}", ","));
+ assertFalse(ASSERT_MESSAGE_CHECK_STATIC_EXISTENCE, StringUtils.checkStaticExistence("${func('a','b')}", ","));
+ assertTrue(ASSERT_MESSAGE_CHECK_STATIC_EXISTENCE, StringUtils.checkStaticExistence("${func('abc')},${func('def')}", ","));
+ }
+
+ @Test
+ public void testUnclosedCurlyBracket() throws ELEvaluationException {
+ expectedException.expect(ELEvaluationException.class);
+ StringUtils.checkStaticExistence("${", ",");
+ }
+
+ @Test
+ public void testClosingTooManyCurlyBracket() throws ELEvaluationException {
+ expectedException.expect(ELEvaluationException.class);
+ StringUtils.checkStaticExistence("${a:a()}}", ",");
+ }
+
+ @Test
+ public void testUnclosedFunctionCall() throws ELEvaluationException {
+ expectedException.expect(ELEvaluationException.class);
+ StringUtils.checkStaticExistence("${a:a(}", ",");
+ }
+
+ @Test
+ public void testTooManyParanthesisClosing() throws ELEvaluationException {
+ expectedException.expect(ELEvaluationException.class);
+ StringUtils.checkStaticExistence("${a:a())}", ",");
+ }
+
+ @Test
+ public void testSequenceBeforeInvalidPart() throws ELEvaluationException {
+ expectedException.expect(ELEvaluationException.class);
+ StringUtils.checkStaticExistence("${a:a(),b:b(),c:c(}", ",");
+ }
}
diff --git a/examples/pom.xml b/examples/pom.xml
index 8900535..e0e1281 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -41,6 +41,16 @@
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-minicluster</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>tomcat</groupId>
+ <artifactId>jasper-compiler</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>tomcat</groupId>
+ <artifactId>jasper-runtime</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
diff --git a/pom.xml b/pom.xml
index 5449a5b..08b17d3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -106,6 +106,7 @@
<tez.version>0.8.4</tez.version>
<jetty.version>9.3.20.v20170531</jetty.version>
+ <apache.jsp.version>8.0.33</apache.jsp.version>
<jline.version>0.9.94</jline.version>
<openjpa.version>2.4.2</openjpa.version>
diff --git a/release-log.txt b/release-log.txt
index a729806..7e42807 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -1,5 +1,6 @@
-- Oozie 5.2.0 release (trunk - unreleased)
+OOZIE-3409 Oozie Server : Memory leak in EL evaluation (asalamon74 via kmarton)
OOZIE-3441 Upgrade jackson version to 2.6.5 (nobigo via asalamon74)
OOZIE-3326 [action] Sqoop Action should support tez delegation tokens for hive-import (bgoerlitz, dionusos via asalamon74)
OOZIE-3395 [build] Migration from FindBugs to SpotBugs (kmarton via asalamon74)
diff --git a/src/main/assemblies/distro.xml b/src/main/assemblies/distro.xml
index bab0ec2..dd5d90c 100644
--- a/src/main/assemblies/distro.xml
+++ b/src/main/assemblies/distro.xml
@@ -85,7 +85,6 @@
<include>**/jetty*-${jetty.version}.jar</include>
<include>**/mail*.jar</include>
<include>**/apache*.jar</include>
- <include>**/commons-el*.jar</include>
<include>**/javax.servlet-api-3.1.0.jar</include>
<include>**/taglibs-*jar</include>
<include>**/org.eclipse.jdt.core-*jar</include>