[Git][java-team/mvel][master] 8 commits: Switch to debhelper-compat = 12.

Markus Koschany gitlab at salsa.debian.org
Mon Aug 26 22:50:12 BST 2019



Markus Koschany pushed to branch master at Debian Java Maintainers / mvel


Commits:
4886e092 by Markus Koschany at 2019-08-26T19:48:39Z
Switch to debhelper-compat = 12.

- - - - -
75bf8b1e by Markus Koschany at 2019-08-26T19:48:51Z
Declare compliance with Debian Policy 4.4.0.

- - - - -
9bfc5319 by Markus Koschany at 2019-08-26T19:49:20Z
Use canonical VCS URI.

- - - - -
ebeaa511 by Markus Koschany at 2019-08-26T19:49:45Z
Remove get-orig-source target.

- - - - -
4856310a by Markus Koschany at 2019-08-26T19:51:49Z
New upstream version 2.4.4
- - - - -
71a4ef95 by Markus Koschany at 2019-08-26T19:51:54Z
Update upstream source from tag 'upstream/2.4.4'

Update to upstream version '2.4.4'
with Debian dir 43c6d95b5dbd0320573f6b9c52547e3f3b5d6732
- - - - -
20e674f7 by Markus Koschany at 2019-08-26T19:56:00Z
Update changelog

- - - - -
1c71b409 by Markus Koschany at 2019-08-26T20:09:54Z
Do not build libmvel-java-doc anymore. The package is empty because the

javadoc plugin fails to build the documentation. Just ignoring the javadoc
errors is not sufficient anymore.

- - - - -


29 changed files:

- debian/changelog
- − debian/compat
- debian/control
- − debian/libmvel-java-doc.doc-base.api
- − debian/libmvel-java-doc.install
- − debian/patches/java9.patch
- debian/patches/series
- debian/rules
- pom.xml
- src/main/java/org/mvel2/ast/BinaryOperation.java
- src/main/java/org/mvel2/compiler/AbstractParser.java
- src/main/java/org/mvel2/compiler/ExpressionCompiler.java
- src/main/java/org/mvel2/jsr223/MvelScriptEngineFactory.java
- src/main/java/org/mvel2/optimizers/impl/asm/ASMAccessorOptimizer.java
- src/main/java/org/mvel2/optimizers/impl/refl/ReflectiveAccessorOptimizer.java
- src/main/java/org/mvel2/optimizers/impl/refl/nodes/DynamicFunctionAccessor.java
- src/main/java/org/mvel2/util/CompilerTools.java
- src/main/java/org/mvel2/util/FastList.java
- src/main/java/org/mvel2/util/ParseTools.java
- src/main/java/org/mvel2/util/PropertyTools.java
- + src/test/java/org/mvel2/compiler/CollectionElementByIndexTest.java
- + src/test/java/org/mvel2/compiler/MvelCompileExpNullSafeTest.java
- src/test/java/org/mvel2/tests/core/CoreConfidenceTests.java
- src/test/java/org/mvel2/tests/core/FunctionsTest.java
- + src/test/java/org/mvel2/tests/core/MvelArrayTest.java
- + src/test/java/org/mvel2/tests/core/PrimitiveTypesTest.java
- src/test/java/org/mvel2/tests/core/PropertyAccessTests.java
- + src/test/java/org/mvel2/tests/core/res/Member.java
- + src/test/java/org/mvel2/tests/core/res/SharedFuncLib.java


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,16 @@
+mvel (2.4.4-1) unstable; urgency=medium
+
+  * Team upload.
+  * New upstream version 2.4.4.
+  * Switch to debhelper-compat = 12.
+  * Declare compliance with Debian Policy 4.4.0.
+  * Use canonical VCS URI.
+  * Do not build libmvel-java-doc anymore. The package is empty because the
+    javadoc plugin fails to build the documentation. Just ignoring the javadoc
+    errors with Java 9+ is not sufficient anymore.
+
+ -- Markus Koschany <apo at debian.org>  Mon, 26 Aug 2019 21:52:42 +0200
+
 mvel (2.4.0-1) unstable; urgency=medium
 
   * Team upload.


=====================================
debian/compat deleted
=====================================
@@ -1 +0,0 @@
-10


=====================================
debian/control
=====================================
@@ -5,7 +5,7 @@ Maintainer: Debian Java Maintainers <pkg-java-maintainers at lists.alioth.debian.or
 Uploaders:
  Damien Raude-Morvan <drazzib at debian.org>
 Build-Depends:
- debhelper (>= 10),
+ debhelper-compat (= 12),
  default-jdk,
  default-jdk-doc,
  junit4,
@@ -17,9 +17,9 @@ Build-Depends:
  libsurefire-java (>= 2.4.3),
  libxstream-java,
  maven-debian-helper
-Standards-Version: 4.1.2
-Vcs-Git: https://anonscm.debian.org/git/pkg-java/mvel.git
-Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/mvel.git
+Standards-Version: 4.4.0
+Vcs-Git: https://salsa.debian.org/java-team/mvel.git
+Vcs-Browser: https://salsa.debian.org/java-team/mvel
 Homepage: https://github.com/mvel/mvel/
 
 Package: libmvel-java
@@ -36,21 +36,3 @@ Description: expression language for Java-based applications - Library
  In addition to being an expression language, MVEL also comes packaged with an
  templating system similar to Velocity and FreeMarker.
 
-Package: libmvel-java-doc
-Architecture: all
-Section: doc
-Depends:
- ${maven:DocDepends},
- ${misc:Depends}
-Recommends:
- ${maven:DocOptionalDepends}
-Suggests:
- libmvel-java
-Description: expression language for Java-based applications - Javadoc
- MVEL may be useful as an extension to anything from use in JSP Tag Libraries,
- to the configuration facilities of your library/framework.
- .
- In addition to being an expression language, MVEL also comes packaged with an
- templating system similar to Velocity and FreeMarker.
- .
- This package provides the API documentation for libmvel-java.


=====================================
debian/libmvel-java-doc.doc-base.api deleted
=====================================
@@ -1,10 +0,0 @@
-Document: libmvel-java
-Title: API Javadoc for MVEL
-Author: MVEL developers
-Abstract: This is the API Javadoc provided for the
- libmvel-java library.
-Section: Programming
-
-Format: HTML
-Index: /usr/share/doc/libmvel-java/api/index.html
-Files: /usr/share/doc/libmvel-java/api/*


=====================================
debian/libmvel-java-doc.install deleted
=====================================
@@ -1 +0,0 @@
-target/apidocs/* usr/share/doc/libmvel-java/api


=====================================
debian/patches/java9.patch deleted
=====================================
@@ -1,30 +0,0 @@
-From: Markus Koschany <apo at debian.org>
-Date: Sat, 2 Dec 2017 09:54:39 +0100
-Subject: java9
-
-Work around FTBFS with Java 9 by ignoring the doclint errors.
-
-Bug-Debian: https://bugs.debian.org/875775
-Forwarded: no
----
- pom.xml | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/pom.xml b/pom.xml
-index dbed0b0..fdb10b9 100644
---- a/pom.xml
-+++ b/pom.xml
-@@ -80,6 +80,13 @@
-         </extensions>
- 
-         <plugins>
-+            <plugin>
-+                <groupId>org.apache.maven.plugins</groupId>
-+                <artifactId>maven-javadoc-plugin</artifactId>
-+                <configuration>
-+                    <failOnError>false</failOnError>
-+                </configuration>
-+            </plugin>
-             <plugin>
-                 <artifactId>maven-enforcer-plugin</artifactId>
-                 <version>1.0</version>


=====================================
debian/patches/series
=====================================
@@ -1,2 +1 @@
 use_system_asm.diff
-java9.patch


=====================================
debian/rules
=====================================
@@ -8,6 +8,3 @@ export JAVA_HOME = /usr/lib/jvm/default-java
 override_dh_clean:
 	dh_clean
 	rm -Rf META-INF
-
-get-orig-source:
-	uscan --download-current-version --force-download --repack --compression xz


=====================================
pom.xml
=====================================
@@ -5,7 +5,7 @@
     <groupId>org.mvel</groupId>
     <artifactId>mvel2</artifactId>
     <packaging>jar</packaging>
-    <version>2.4.0.Final</version>
+    <version>2.4.4.Final</version>
 
     <name>mvel</name>
     <url>http://mvel.codehaus.org/</url>
@@ -31,7 +31,7 @@
         <connection>scm:git:git at github.com:mvel/mvel.git</connection>
         <url>scm:git:git at github.com:mvel/mvel.git</url>
         <developerConnection>scm:git:git at github.com:mvel/mvel.git</developerConnection>
-        <tag>mvel2-2.4.0.Final</tag>
+        <tag>mvel2-2.4.4.Final</tag>
     </scm>
     <issueManagement>
         <system>jira</system>
@@ -229,6 +229,9 @@
                     <include>build.properties</include>
                 </includes>
             </resource>
+            <resource>
+              <directory>src/main/resources</directory>
+            </resource>
         </resources>
     </build>
 


=====================================
src/main/java/org/mvel2/ast/BinaryOperation.java
=====================================
@@ -73,8 +73,16 @@ public class BinaryOperation extends BooleanNode {
         egressType = getReturnTypeFromOp(operation, this.left.egressType, this.right.egressType);
         if (!ctx.isStrongTyping()) break;
 
-        if (!left.getEgressType().isAssignableFrom(right.getEgressType()) && !right.getEgressType().isAssignableFrom(left.getEgressType())) {
-          if (right.isLiteral() && canConvert(left.getEgressType(), right.getEgressType())) {
+        final boolean leftIsAssignableFromRight = left.getEgressType().isAssignableFrom(right.getEgressType());
+        final boolean rightIsAssignableFromLeft = right.getEgressType().isAssignableFrom(left.getEgressType());
+
+        if (!leftIsAssignableFromRight && !rightIsAssignableFromLeft) {
+
+          // Convert literals only when passing from String to Character or from Float to Double
+          final boolean requiresConversion = right.getEgressType() == String.class || (
+                  right.getEgressType() == Double.class && ( left.getEgressType() == Float.class || left.getEgressType() == float.class ) );
+
+          if (right.isLiteral() && requiresConversion && canConvert(left.getEgressType(), right.getEgressType())) {
             Class targetType = isAritmeticOperation(operation) ? egressType : left.getEgressType();
             this.right = new LiteralNode(convert(right.getReducedValueAccelerated(null, null, null), targetType), pCtx);
           } else if ( !(areCompatible(left.getEgressType(), right.getEgressType()) ||


=====================================
src/main/java/org/mvel2/compiler/AbstractParser.java
=====================================
@@ -113,6 +113,7 @@ public class AbstractParser implements Parser, Serializable {
 
   protected int fields;
 
+  protected static final int OP_NOT_LITERAL = -3;
   protected static final int OP_OVERFLOW = -2;
   protected static final int OP_TERMINATE = -1;
   protected static final int OP_RESET_FRAME = 0;
@@ -2407,8 +2408,6 @@ public class AbstractParser implements Parser, Serializable {
          * need to stop if this is not a literal.
          */
         if (compileMode && !tk.isLiteral()) {
-
-
           splitAccumulator.push(tk, new OperatorNode(operator2, expr, st, pCtx));
           return OP_OVERFLOW;
         }
@@ -2416,6 +2415,7 @@ public class AbstractParser implements Parser, Serializable {
         dStack.push(operator = operator2, tk.getReducedValue(ctx, ctx, variableFactory));
 
         while (true) {
+          ASTNode previousToken = tk;
           // look ahead again
           if ((tk = nextToken()) != null && (operator2 = tk.getOperator()) != -1
               && operator2 != END_OF_STMT && PTABLE[operator2] > PTABLE[operator]) {
@@ -2428,7 +2428,12 @@ public class AbstractParser implements Parser, Serializable {
             /**
              * This operator is of higher precedence, or the same level precedence.  push to the RHS.
              */
-            dStack.push(operator = operator2, nextToken().getReducedValue(ctx, ctx, variableFactory));
+            ASTNode nextToken = nextToken();
+            if (compileMode && !nextToken.isLiteral()) {
+              splitAccumulator.push(nextToken, new OperatorNode(operator2, expr, st, pCtx));
+              return OP_OVERFLOW;
+            }
+            dStack.push(operator = operator2, nextToken.getReducedValue(ctx, ctx, variableFactory));
 
             continue;
           }
@@ -2498,6 +2503,10 @@ public class AbstractParser implements Parser, Serializable {
               }
 
               default:
+                if (compileMode && !tk.isLiteral()) {
+                  stk.push(operator, tk);
+                  return OP_NOT_LITERAL;
+                }
                 stk.push(operator, tk.getReducedValue(ctx, ctx, variableFactory));
             }
           }


=====================================
src/main/java/org/mvel2/compiler/ExpressionCompiler.java
=====================================
@@ -123,7 +123,7 @@ public class ExpressionCompiler extends AbstractParser {
 
       fields |= COMPILE_IMMEDIATE;
 
-      while ((tk = nextToken()) != null) {
+      main_loop: while ((tk = nextToken()) != null) {
         /**
          * If this is a debug symbol, just add it and continue.
          */
@@ -199,7 +199,7 @@ public class ExpressionCompiler extends AbstractParser {
                     stk.push(tkLA2.getLiteralValue(), op = tkOp2.getOperator());
 
                     if (isArithmeticOperator(op)) {
-                      compileReduce(op, astBuild);
+                      if (!compileReduce(op, astBuild)) continue main_loop;
                     }
                     else {
                       reduce();
@@ -327,7 +327,7 @@ public class ExpressionCompiler extends AbstractParser {
 
   private boolean compileReduce(int opCode, ASTLinkedList astBuild) {
     switch (arithmeticFunctionReduction(opCode)) {
-      case -1:
+      case OP_TERMINATE:
         /**
          * The reduction failed because we encountered a non-literal,
          * so we must now back out and cleanup.
@@ -341,7 +341,7 @@ public class ExpressionCompiler extends AbstractParser {
             verify(pCtx, (ASTNode) splitAccumulator.pop())
         );
         return false;
-      case -2:
+      case OP_OVERFLOW:
         /**
          * Back out completely, pull everything back off the stack and add the instructions
          * to the output payload as they are.
@@ -353,6 +353,13 @@ public class ExpressionCompiler extends AbstractParser {
         astBuild.addTokenNode(new LiteralNode(stk.pop(), pCtx), operator);
         astBuild.addTokenNode(rightValue, (OperatorNode) splitAccumulator.pop());
         astBuild.addTokenNode(verify(pCtx, (ASTNode) splitAccumulator.pop()));
+        return false;
+      case OP_NOT_LITERAL:
+        ASTNode tkLA2 = (ASTNode) stk.pop();
+        Integer tkOp2 = (Integer) stk.pop();
+        astBuild.addTokenNode(new LiteralNode(getStackValueResult(), pCtx));
+        astBuild.addTokenNode(new OperatorNode(tkOp2, expr, st, pCtx), verify(pCtx, tkLA2));
+        return false;
     }
     return true;
   }


=====================================
src/main/java/org/mvel2/jsr223/MvelScriptEngineFactory.java
=====================================
@@ -1,6 +1,7 @@
 package org.mvel2.jsr223;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import javax.script.ScriptEngine;
@@ -14,14 +15,25 @@ public class MvelScriptEngineFactory implements ScriptEngineFactory {
     private static final String           LANGUAGE_NAME      = "mvel";
     private static final String           LANGUAGE_VERSION   = MVEL.VERSION;
 
-    private static final List<String>     NAMES              = new ArrayList<String>();
-    private static final List<String>     EXTENSIONS         = new ArrayList<String>();
-    private static final List<String>     MIME_TYPES         = new ArrayList<String>();
+    private static final List<String> NAMES;
+    private static final List<String> EXTENSIONS;
+    private static final List<String> MIME_TYPES;
+
+    static {
+        List<String> n = new ArrayList<String>(1);
+        n.add(LANGUAGE_NAME);
+        NAMES = Collections.unmodifiableList(n);
+
+        EXTENSIONS = NAMES;
+
+        n = new ArrayList<String>(1);
+        n.add("application/x-"+LANGUAGE_NAME);
+        MIME_TYPES = Collections.unmodifiableList(n);
+    }
 
     private static final MvelScriptEngine MVEL_SCRIPT_ENGINE = new MvelScriptEngine();
 
     public MvelScriptEngineFactory() {
-        NAMES.add(LANGUAGE_NAME);
     }
 
     @Override


=====================================
src/main/java/org/mvel2/optimizers/impl/asm/ASMAccessorOptimizer.java
=====================================
@@ -121,7 +121,9 @@ public class ASMAccessorOptimizer extends AbstractOptimizer implements AccessorO
     } else if (javaVersion.startsWith("1.6")
             || javaVersion.startsWith("1.7")
             || javaVersion.startsWith("1.8")
-            || javaVersion.startsWith("9")) {
+            || javaVersion.startsWith("9")
+            || javaVersion.startsWith("10")
+            || javaVersion.startsWith("11")) {
       OPCODES_VERSION = Opcodes.V1_6;
     } else {
       OPCODES_VERSION = Opcodes.V1_2;


=====================================
src/main/java/org/mvel2/optimizers/impl/refl/ReflectiveAccessorOptimizer.java
=====================================
@@ -377,7 +377,7 @@ public class ReflectiveAccessorOptimizer extends AbstractOptimizer implements Ac
           if (cursor < end) {
             if (nullSafe) {
               int os = expr[cursor] == '.' ? 1 : 0;
-              addAccessorNode(new NullSafe(expr, cursor + os, length - cursor - os, pCtx));
+              addAccessorNode(new NullSafe(expr, cursor + os, end - cursor - os, pCtx));
               if (curr == null) break;
             }
             if (curr == null) throw new NullPointerException();
@@ -806,17 +806,16 @@ public class ReflectiveAccessorOptimizer extends AbstractOptimizer implements Ac
 
       return ((CharSequence) ctx).charAt((Integer) idx);
     }
-    else {
+    else if (ctx instanceof Class) {
       TypeDescriptor tDescr = new TypeDescriptor(expr, this.start, length, 0);
       if (tDescr.isArray()) {
         Class cls = getClassReference((Class) ctx, tDescr, variableFactory, pCtx);
         rootNode = new StaticReferenceAccessor(cls);
         return cls;
       }
-
-      throw new CompileException("illegal use of []: unknown type: "
-          + ctx.getClass().getName(), this.expr, this.start);
     }
+    throw new CompileException("illegal use of []: unknown type: "
+            + ctx.getClass().getName(), this.expr, this.start);
   }
 
 


=====================================
src/main/java/org/mvel2/optimizers/impl/refl/nodes/DynamicFunctionAccessor.java
=====================================
@@ -19,6 +19,7 @@
 package org.mvel2.optimizers.impl.refl.nodes;
 
 import org.mvel2.ast.Function;
+import org.mvel2.ast.FunctionInstance;
 import org.mvel2.compiler.Accessor;
 import org.mvel2.integration.VariableResolverFactory;
 
@@ -34,7 +35,12 @@ public class DynamicFunctionAccessor extends BaseAccessor {
   public Object getValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory) {
     Object[] parms = null;
 
-    Function function = (Function) ctx;
+    Function function;
+    if (ctx instanceof FunctionInstance){
+      function = ((FunctionInstance)ctx).getFunction();
+    } else {
+      function = (Function)ctx;
+    }
 
     if (parameters != null && parameters.length != 0) {
       parms = new Object[parameters.length];


=====================================
src/main/java/org/mvel2/util/CompilerTools.java
=====================================
@@ -103,7 +103,7 @@ public class CompilerTools {
             bo = null;
 
             boolean inv = tkOp.isOperator(Operator.SUB);
-            boolean reduc = isReductionOpportunity(tkOp, tk2);
+            boolean reduc = tk.isLiteral() && isReductionOpportunity(tkOp, tk2);
             boolean p_inv = false;
 
             while (reduc) {


=====================================
src/main/java/org/mvel2/util/FastList.java
=====================================
@@ -18,13 +18,17 @@
 
 package org.mvel2.util;
 
-import org.mvel2.ImmutableElementException;
-
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
-import java.util.*;
+import java.util.AbstractList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.mvel2.ImmutableElementException;
 
 public class FastList<E> extends AbstractList<E> implements Externalizable {
   private E[] elements;
@@ -168,14 +172,14 @@ public class FastList<E> extends AbstractList<E> implements Externalizable {
 
   public ListIterator<E> listIterator() {
     return new ListIterator<E>() {
-      private int i = 0;
+      private int i = -1;
 
       public boolean hasNext() {
-        return i < size;
+        return i < size-1;
       }
 
       public E next() {
-        return elements[i++];
+        return elements[++i];
       }
 
       public boolean hasPrevious() {
@@ -183,7 +187,7 @@ public class FastList<E> extends AbstractList<E> implements Externalizable {
       }
 
       public E previous() {
-        return elements[i--];
+        return elements[--i];
       }
 
       public int nextIndex() {


=====================================
src/main/java/org/mvel2/util/ParseTools.java
=====================================
@@ -320,7 +320,7 @@ public class ParseTools {
 
       if (arguments[i] == null) {
         if (!actualParamType.isPrimitive()) {
-          score += 6;
+          score += 7;
         }
         else {
           score = 0;
@@ -328,15 +328,18 @@ public class ParseTools {
         }
       }
       else if (actualParamType == arguments[i]) {
-        score += 7;
+        score += 8;
       }
       else if (actualParamType.isPrimitive() && boxPrimitive(actualParamType) == arguments[i]) {
-        score += 6;
+        score += 7;
       }
       else if (arguments[i].isPrimitive() && unboxPrimitive(arguments[i]) == actualParamType) {
-        score += 6;
+        score += 7;
       }
       else if (actualParamType.isAssignableFrom(arguments[i])) {
+        score += 6;
+      }
+      else if (isPrimitiveSubtype(arguments[i], actualParamType)) {
         score += 5;
       }
       else if (isNumericallyCoercible(arguments[i], actualParamType)) {
@@ -1065,6 +1068,22 @@ public class ParseTools {
     return code;
   }
 
+  private static boolean isPrimitiveSubtype( Class argument, Class<?> actualParamType ) {
+    if (!actualParamType.isPrimitive()) {
+      return false;
+    }
+    Class<?> primitiveArgument = unboxPrimitive(argument);
+    if (!primitiveArgument.isPrimitive()) {
+      return false;
+    }
+    return ( actualParamType == double.class && primitiveArgument == float.class ) ||
+           ( actualParamType == float.class && primitiveArgument == long.class ) ||
+           ( actualParamType == long.class && primitiveArgument == int.class ) ||
+           ( actualParamType == int.class && primitiveArgument == char.class ) ||
+           ( actualParamType == int.class && primitiveArgument == short.class ) ||
+           ( actualParamType == short.class && primitiveArgument == byte.class );
+  }
+
   public static boolean isNumericallyCoercible(Class target, Class parm) {
     Class boxedTarget = target.isPrimitive() ? boxPrimitive(target) : target;
 
@@ -2175,7 +2194,7 @@ public class ParseTools {
 
   public static Class forNameWithInner(String className, ClassLoader classLoader) throws ClassNotFoundException {
     try {
-      return Class.forName(className, true, classLoader);
+      return classLoader.loadClass( className );
     } catch (ClassNotFoundException cnfe) {
       return findInnerClass( className, classLoader, cnfe );
     }
@@ -2185,7 +2204,7 @@ public class ParseTools {
     for (int lastDotPos = className.lastIndexOf('.'); lastDotPos > 0; lastDotPos = className.lastIndexOf('.')) {
       className = className.substring(0, lastDotPos) + "$" + className.substring(lastDotPos+1);
       try {
-        return Class.forName(className, true, classLoader);
+        return classLoader.loadClass( className );
       } catch (ClassNotFoundException e) { /* ignore */ }
     }
     throw cnfe;


=====================================
src/main/java/org/mvel2/util/PropertyTools.java
=====================================
@@ -97,6 +97,13 @@ public class PropertyTools {
     String getter = ReflectionUtil.getGetter(property);
 
     Method candidate = null;
+
+    if (Collection.class.isAssignableFrom(clazz) && "isEmpty".equals(isGet)) {
+      try {
+        return Collection.class.getMethod("isEmpty");
+      } catch (NoSuchMethodException ignore) {}
+    }
+
     for (Method meth : clazz.getMethods()) {
       if ((meth.getModifiers() & PUBLIC) != 0 && (meth.getModifiers() & STATIC) == 0 && meth.getParameterTypes().length == 0
           && (getter.equals(meth.getName()) || property.equals(meth.getName()) || ((isGet.equals(meth.getName()) || simpleIsGet.equals(meth.getName())) && meth.getReturnType() == boolean.class)


=====================================
src/test/java/org/mvel2/compiler/CollectionElementByIndexTest.java
=====================================
@@ -0,0 +1,31 @@
+package org.mvel2.compiler;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mvel2.CompileException;
+import org.mvel2.MVEL;
+
+import static org.junit.internal.matchers.StringContains.containsString;
+
+/**
+ * @author Anton Rybochkin (anton.rybochkin at axibase.com)
+ */
+public class CollectionElementByIndexTest {
+	@Rule
+	public ExpectedException expectException = ExpectedException.none();
+
+	@Test
+	public void testGetElementByIndexInSet() {
+		expectException.expect(CompileException.class);
+		expectException.expectMessage(containsString("unknown type: java.util.Collections$SingletonSet"));
+		final Map<String, Set<String>> map = Collections.singletonMap("set", Collections.singleton("test"));
+		final Serializable ser = MVEL.compileExpression("set[0]");
+		MVEL.executeExpression(ser, map);
+	}
+}


=====================================
src/test/java/org/mvel2/compiler/MvelCompileExpNullSafeTest.java
=====================================
@@ -0,0 +1,133 @@
+package org.mvel2.compiler;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+import org.mvel2.MVEL;
+import org.mvel2.compiler.CompiledExpression;
+import org.mvel2.compiler.ExpressionCompiler;
+
+/**
+ * @author Viswa Ramamoorthy (viswaramamoorthy at yahoo.com)
+ */
+public class MvelCompileExpNullSafeTest
+{
+	@Test
+	public void testMvelCompileNullSafeNullFirst() {
+        String expression = "((parentGroup != null) && ($.?child.firstName in parentGroup.parentList if  $.?child.firstName != null).size() > 0)";
+        ExpressionCompiler compiler = new ExpressionCompiler(expression, true);
+        CompiledExpression compiledExpression = compiler.compile();
+        
+    	ParentGroup pGroup = new ParentGroup();
+    	List<Parent> list = new ArrayList<Parent>();
+    	Parent parent = new Parent();
+    	parent.setChild(null);
+    	list.add(parent);
+    	pGroup.setParentList(list);
+
+    	Boolean result = (Boolean)MVEL.executeExpression(compiledExpression, Collections.<String, Object>singletonMap("parentGroup", pGroup));
+    	assert result == false;
+
+    	Child child = new Child();
+    	child.setFirstName("vlaa");
+
+    	pGroup = new ParentGroup();
+    	list = new ArrayList<Parent>();
+    	parent = new Parent();
+    	parent.setChild(child);
+    	list.add(parent);
+    	child = new Child();
+    	child.setFirstName(null);
+    	parent = new Parent();
+    	parent.setChild(child);
+    	list.add(parent);
+    	pGroup.setParentList(list);
+
+    	result = (Boolean)MVEL.executeExpression(compiledExpression, Collections.<String, Object>singletonMap("parentGroup", pGroup));
+    	assert result == true;
+	}
+
+	@Test
+	public void testMvelCompileNullSafeNullSecond() {
+        String expression = "((parentGroup != null) && ($.?child.firstName in parentGroup.parentList if  $.?child.firstName != null).size() > 0)";
+        ExpressionCompiler compiler = new ExpressionCompiler(expression, true);
+        CompiledExpression compiledExpression = compiler.compile();
+        
+    	Child child = new Child();
+    	child.setFirstName("vlaa");
+
+    	ParentGroup pGroup = new ParentGroup();
+    	List<Parent> list = new ArrayList<Parent>();
+    	Parent parent = new Parent();
+    	parent.setChild(child);
+    	list.add(parent);
+    	child = new Child();
+    	child.setFirstName(null);
+    	parent = new Parent();
+    	parent.setChild(child);
+    	list.add(parent);
+    	pGroup.setParentList(list);
+
+    	Boolean result = (Boolean)MVEL.executeExpression(compiledExpression, Collections.<String, Object>singletonMap("parentGroup", pGroup));
+    	assert result == true;
+
+    	pGroup = new ParentGroup();
+    	list = new ArrayList<Parent>();
+    	parent = new Parent();
+    	parent.setChild(null);
+    	list.add(parent);
+    	pGroup.setParentList(list);
+
+    	result = (Boolean)MVEL.executeExpression(compiledExpression, Collections.<String, Object>singletonMap("parentGroup", pGroup));
+    	assert result == false;
+
+	}
+
+	public class Child {
+		private String firstName;
+		private String lastName;
+		
+		public String getFirstName() {
+			return firstName;
+		}
+
+		public void setFirstName(String firstName) {
+			this.firstName = firstName;
+		}
+		
+		public String getLastName() {
+			return lastName;
+		}
+		
+		public void setLastName(String lastName) {
+			this.lastName = lastName;
+		}
+	}
+
+    public class Parent {
+    	private Child child;
+
+		public Child getChild() {
+			return child;
+		}
+
+		public void setChild(Child child) {
+			this.child = child;
+		}
+    }
+
+    public class ParentGroup {
+    	private List<Parent> parentList;
+
+		public List<Parent> getParentList() {
+			return parentList;
+		}
+
+		public void setParentList(List<Parent> parentList) {
+			this.parentList = parentList;
+		}
+    	
+    }
+}


=====================================
src/test/java/org/mvel2/tests/core/CoreConfidenceTests.java
=====================================
@@ -27,6 +27,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.Vector;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import junit.framework.TestCase;
 import org.mvel2.CompileException;
@@ -82,7 +83,15 @@ import org.mvel2.util.ParseTools;
 import org.mvel2.util.ReflectionUtil;
 
 import static java.util.Collections.unmodifiableCollection;
-import static org.mvel2.MVEL.*;
+
+import static org.mvel2.MVEL.compileExpression;
+import static org.mvel2.MVEL.compileSetExpression;
+import static org.mvel2.MVEL.eval;
+import static org.mvel2.MVEL.evalToBoolean;
+import static org.mvel2.MVEL.executeExpression;
+import static org.mvel2.MVEL.executeSetExpression;
+import static org.mvel2.MVEL.parseMacros;
+import static org.mvel2.MVEL.setProperty;
 import static org.mvel2.util.ParseTools.loadFromFile;
 
 @SuppressWarnings({"ALL"})
@@ -4018,17 +4027,6 @@ public class CoreConfidenceTests extends AbstractTest {
     assertFalse(result);
   }
 
-  public void testDhanji2() {
-    String ex =
-        "name = null;\n" +
-            "$_1 = ?name.?toLowerCase();\n";
-
-
-    Serializable s = MVEL.compileExpression(ex);
-
-    MVEL.executeExpression(s, new HashMap());
-  }
-
   public void testPrimitiveNumberCoercion() {
     final ParserContext parserContext = new ParserContext();
     parserContext.setStrictTypeEnforcement(true);
@@ -4158,6 +4156,44 @@ public class CoreConfidenceTests extends AbstractTest {
     System.out.println(result);
   }
 
+  public void testPrimitiveNumberCoercionDuringDivisionShouldWorkOnBothSide() {
+    final ParserContext parserContext = new ParserContext();
+    parserContext.setStrictTypeEnforcement(true);
+    parserContext.setStrongTyping(true);
+    parserContext.addInput("a", int.class);
+    parserContext.addInput("b", int.class);
+
+    int a = 1;
+    int b = 2;
+    Object res = a / b;
+    System.out.printf("Result class Java: %s\nResult value: %s\n", res.getClass(), res);
+    Object resBoolean = a / b < 0.99;
+    System.out.println("Result Boolean: " + resBoolean);
+
+    Serializable constantDoubleLeft = MVEL.compileExpression("0.99 >= a / b", parserContext);
+    Object resultLeft = MVEL.executeExpression(constantDoubleLeft, new HashMap() {{
+      put("a", 1);
+      put("b", 2);
+    }});
+    assertEquals(true, resultLeft);
+    Serializable constantDoubleRight = MVEL.compileExpression("a / b < 0.99", parserContext);
+    Object resultRight = MVEL.executeExpression(constantDoubleRight, new HashMap() {{
+      put("a", 1);
+      put("b", 2);
+    }});
+    assertEquals(true, resultRight);
+
+    parserContext.addInput("c", double.class);
+    parserContext.addInput("d", double.class);
+    Serializable constantIntRight = MVEL.compileExpression("c / d > 0", parserContext);
+    Object resultRightInt = MVEL.executeExpression(constantIntRight, new HashMap() {{
+      put("c", 1);
+      put("d", 2);
+    }});
+    assertEquals(true, resultRightInt);
+
+  }
+
   public void testUntypedClone() {
     String expression = "obj.clone();";
     ParserContext context = new ParserContext();
@@ -4325,6 +4361,9 @@ public class CoreConfidenceTests extends AbstractTest {
     Map vars = new HashMap() {{ put("ch", 'a'); }};
     assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("ch == \"a\"", pctx), vars));
     assertEquals(false, MVEL.executeExpression(MVEL.compileExpression("ch == \"b\"", pctx), vars));
+
+//    assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("\"a\" == ch", pctx), vars));
+//    assertEquals(false, MVEL.executeExpression(MVEL.compileExpression("\"b\" == ch", pctx), vars));
   }
 
   public void testFieldNameWithUnderscore() {
@@ -4616,4 +4655,45 @@ public class CoreConfidenceTests extends AbstractTest {
       fail("parse of this expression should raise an error");
     } catch (Exception e) { }
   }
+
+  public void testPrimitiveSubtyping() {
+    ParserConfiguration conf = new ParserConfiguration();
+    ParserContext pctx = new ParserContext( conf );
+    pctx.setStrictTypeEnforcement(true);
+    pctx.setStrongTyping(true);
+    BigDecimal result = (BigDecimal)MVEL.executeExpression(MVEL.compileExpression("java.math.BigDecimal.valueOf(100)", pctx), new HashMap());
+    assertEquals("100", result.toString());
+  }
+
+  public void testUseVariableFactoryWithArithmeticOperation() {
+    checkOperation("3 + 4 * i.get()", 43);
+    checkOperation("2 * 3 + 4 * i.get()", 46);
+    checkOperation("1 + 2 * 3 + i.get()", 17);
+    checkOperation("2 * 3 + 4 * i.get()", 46);
+    checkOperation("1 + 2 * 3 + 4 * i.get()", 47);
+    checkOperation("1 + 2 * 3 + i.get() * 4", 47);
+    checkOperation("1 + 2 * 3 + i.get() + 4", 21);
+    checkOperation("4 * i.get() + 5", 45);
+    checkOperation("3 + 4 * i.get() + 5", 48);
+    checkOperation("2 * 3 + 4 * i.get() + 5", 51);
+    checkOperation("1 + 2 * 3 + 4 * i.get() + 5", 52);
+    checkOperation("1 + 2 * 3 + 4 * i.get() * 5", 207);
+    checkOperation("i.get() + 1 + 2 * 3 + 4 * i.get()", 57);
+  }
+
+  private void checkOperation(String expression, int expectedResult) {
+    AtomicInteger i = new AtomicInteger( 10 );
+    VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap<String, Object>());
+    factory.createVariable("i", i);
+
+    ParserConfiguration pconf = new ParserConfiguration();
+    ParserContext pctx = new ParserContext(pconf);
+    pctx.setStrictTypeEnforcement(true);
+    pctx.setStrongTyping(true);
+    pctx.addInput("i", AtomicInteger.class);
+
+    Serializable compiledExpr = MVEL.compileExpression(expression, pctx);
+    int result = (Integer)MVEL.executeExpression(compiledExpr, null, factory);
+    assertEquals(expectedResult, result);
+  }
 }
\ No newline at end of file


=====================================
src/test/java/org/mvel2/tests/core/FunctionsTest.java
=====================================
@@ -10,13 +10,15 @@ import org.mvel2.compiler.ExpressionCompiler;
 import org.mvel2.integration.VariableResolverFactory;
 import org.mvel2.integration.impl.MapVariableResolverFactory;
 import org.mvel2.optimizers.OptimizerFactory;
-import org.mvel2.util.CompilerTools;
-import org.mvel2.util.MVELClassLoader;
+import org.mvel2.tests.core.res.Member;
+import org.mvel2.tests.core.res.SharedFuncLib;
 
 import static org.mvel2.util.CompilerTools.extractAllDeclaredFunctions;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.*;
+import java.util.concurrent.*;
 
 /**
  * @author Dhanji R. Prasanna (dhanji at gmail com)
@@ -200,4 +202,37 @@ public class FunctionsTest extends AbstractTest {
     assertEquals("foobar", MVEL.executeExpression(s, myVarFactory));
   }
 
+
+
+  public void testFunctionReuseMultiThread(){
+    ExecutorService executor = Executors.newFixedThreadPool(4);
+    List<Callable<BigDecimal>> tasks = new ArrayList<Callable<BigDecimal>>();
+    for (int i=0;i<30;i++){
+      tasks.add(new Callable<BigDecimal>() {
+        @Override
+        public BigDecimal call() throws Exception {
+          List<Member> lst = new ArrayList<Member>();
+          lst.add(new Member("a", 18));
+          lst.add(new Member("b", 12));
+          lst.add(new Member("c", 40));
+          lst.add(new Member("d", 66));
+          lst.add(new Member("e", 72));
+          HashMap<String, Object> map = new HashMap<String,Object>();
+          map.put("members",lst);
+          return new SharedFuncLib().eval("round( sum(members,0B, def(p){ return 2B*p.age; }) ,2)", map, BigDecimal.class);
+        }
+      });
+    }
+
+    try {
+      List<Future<BigDecimal>> futures = executor.invokeAll(tasks);
+      for (Future<BigDecimal> future : futures){
+        System.out.println("res=" + future.get().toString());
+      }
+    } catch (InterruptedException ie){
+      throw new RuntimeException(ie);
+    } catch (ExecutionException ee) {
+      throw new RuntimeException(ee);
+    }
+  }
 }


=====================================
src/test/java/org/mvel2/tests/core/MvelArrayTest.java
=====================================
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.mvel2.tests.core;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+import junit.framework.TestCase;
+import org.mvel2.MVEL;
+import org.mvel2.integration.VariableResolverFactory;
+import org.mvel2.integration.impl.MapVariableResolverFactory;
+import org.mvel2.optimizers.OptimizerFactory;
+
+import static org.mvel2.MVEL.executeExpression;
+
+public class MvelArrayTest extends TestCase {
+
+    private final String biglistTestScript =
+            "list = [];\n" +
+            "list.add(1);\n" +
+            "list.add(2);\n" +
+            "list.add(3);\n" +
+            "list.add(null);\n" + // null!
+            "list.add(5);\n" +
+            "list.add(6);\n" +
+            "list.add(7);\n" +
+            "list.add(8);\n" +
+            "list.add(9);\n" +
+            "list.add(10);\n" +
+            "list.add(11);\n" +
+            "list.add(12);\n" +
+            "java.util.Collections.replaceAll( list, null, 25 );\n" + // replace nulls, with a big value
+            "java.util.Collections.max( list );\n";  // return
+
+    public void testAsmOptimizerDiesWithBigList() {
+
+        OptimizerFactory.setDefaultOptimizer("ASM");
+        Serializable compileExpression = MVEL.compileExpression( biglistTestScript );
+        VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap());
+
+        int actual = (Integer) executeExpression(compileExpression, factory);
+        assertEquals( actual, 25);
+    }
+
+    public void testReflectiveOptimizerWorksFine() {
+
+        OptimizerFactory.setDefaultOptimizer("reflective");
+        Serializable compileExpression = MVEL.compileExpression( biglistTestScript );
+        VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap());
+
+        int actual = (Integer) executeExpression(compileExpression, factory);
+        assertEquals( actual, 25);
+    }
+
+    public void testDynamicOptimizerWorksFine() {
+
+        OptimizerFactory.setDefaultOptimizer("dynamic");
+        Serializable compileExpression = MVEL.compileExpression( biglistTestScript );
+        VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap());
+
+        int actual = (Integer) executeExpression(compileExpression, factory);
+        assertEquals( actual, 25);
+    }
+
+    private final String smallListTestScript =
+            "list = [];\n" +
+            "list.add(1);\n" +
+            "list.add(2);\n" +
+            "list.add(3);\n" +
+            "list.add(null);\n" + // null!
+            "list.add(5);\n" +
+            "list.add(6);\n" +
+            "java.util.Collections.replaceAll( list, null, 25 );\n" + // replace nulls, with a big value
+            "java.util.Collections.max( list );\n";  // return
+
+    public void testAsmOptimizerWithSmallListIsFine() {
+
+        OptimizerFactory.setDefaultOptimizer("ASM");
+        Serializable compileExpression = MVEL.compileExpression( smallListTestScript );
+        VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap());
+
+        int actual = (Integer) executeExpression(compileExpression, factory);
+        assertEquals( actual, 25);
+    }
+}
\ No newline at end of file


=====================================
src/test/java/org/mvel2/tests/core/PrimitiveTypesTest.java
=====================================
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.mvel2.tests.core;
+
+import org.mvel2.MVEL;
+import org.mvel2.ParserConfiguration;
+import org.mvel2.ParserContext;
+
+public class PrimitiveTypesTest extends AbstractTest {
+    public static class FactWithFloat {
+
+        private final float floatValue;
+        private final Float floatObjectValue;
+
+        public FactWithFloat(final float floatValue) {
+            this.floatValue = floatValue;
+            this.floatObjectValue = floatValue;
+        }
+
+        public float getFloatValue() {
+            return floatValue;
+        }
+
+        public Float getFloatObjectValue() {
+            return floatObjectValue;
+        }
+    }
+
+    public void testFloatPrimitive() {
+        ParserConfiguration conf = new ParserConfiguration();
+        conf.addImport( FactWithFloat.class );
+        ParserContext pctx = new ParserContext( conf );
+        pctx.setStrictTypeEnforcement(true);
+        pctx.setStrongTyping(true);
+        pctx.addInput("this", FactWithFloat.class);
+        boolean result = ( Boolean ) MVEL.executeExpression(MVEL.compileExpression("floatValue == 15.1", pctx), new FactWithFloat(15.1f));
+        assertTrue( result );
+    }
+
+    public void testFloat() {
+        ParserConfiguration conf = new ParserConfiguration();
+        conf.addImport( FactWithFloat.class );
+        ParserContext pctx = new ParserContext( conf );
+        pctx.setStrictTypeEnforcement(true);
+        pctx.setStrongTyping(true);
+        pctx.addInput("this", FactWithFloat.class);
+        boolean result = ( Boolean ) MVEL.executeExpression(MVEL.compileExpression("floatObjectValue == 15.1", pctx), new FactWithFloat(15.1f));
+        assertTrue( result );
+    }
+}


=====================================
src/test/java/org/mvel2/tests/core/PropertyAccessTests.java
=====================================
@@ -468,6 +468,41 @@ public class PropertyAccessTests extends AbstractTest {
     }
   }
 
+  public final class Data {
+
+    private final Collection<Object> list;
+
+    Data(List<Object> list) {
+      this.list = list;
+    }
+
+    public Collection<Object> getList() {
+      return list;
+    }
+  }
+
+  public void testStaleReflectiveCollectionIsEmptyAccessor() {
+    try
+    {
+      OptimizerFactory.setDefaultOptimizer(OptimizerFactory.SAFE_REFLECTIVE);
+      Serializable getFooExpression = MVEL.compileExpression("list.empty");
+      Map vars = new HashMap();
+
+      // ArrayList -> Colletions.EmptyList
+      assertEquals(true, MVEL.executeExpression(getFooExpression, new Data(new ArrayList<Object>())));
+      assertEquals(true, MVEL.executeExpression(getFooExpression, new Data(Collections.emptyList())));
+
+      // Colletions.EmptyList -> ArrayList
+      assertEquals(true, MVEL.executeExpression(getFooExpression, new Data(Collections.emptyList())));
+      assertEquals(true, MVEL.executeExpression(getFooExpression, new Data(new ArrayList<Object>())));
+      OptimizerFactory.setDefaultOptimizer(OptimizerFactory.DYNAMIC);
+    }
+    finally
+    {
+      OptimizerFactory.setDefaultOptimizer(OptimizerFactory.DYNAMIC);
+    }
+  }
+
   public void testMVEL308() {
     String expression = "foreach(field: updates.entrySet()) { ctx._target[field.key] = field.value; }";
     Serializable compiled = MVEL.compileExpression(expression);


=====================================
src/test/java/org/mvel2/tests/core/res/Member.java
=====================================
@@ -0,0 +1,20 @@
+package org.mvel2.tests.core.res;
+
+public class Member {
+  private String name;
+  private Integer age;
+
+  public Member(String name, Integer age) {
+    super();
+    this.name = name;
+    this.age = age;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public Integer getAge() {
+    return age;
+  }
+}


=====================================
src/test/java/org/mvel2/tests/core/res/SharedFuncLib.java
=====================================
@@ -0,0 +1,26 @@
+package org.mvel2.tests.core.res;
+
+import org.mvel2.MVEL;
+import org.mvel2.integration.VariableResolverFactory;
+import org.mvel2.integration.impl.MapVariableResolverFactory;
+
+import java.util.Map;
+
+public class SharedFuncLib {
+
+  final static VariableResolverFactory functionFactory = new MapVariableResolverFactory();
+
+  static {
+    MVEL.eval(
+    "def round(numValue, decPlaces) { return numValue.setScale(decPlaces,java.math.RoundingMode.HALF_UP) };"
+            + "\n"
+            + "def sum(lst, startValue, accFunc){ s = startValue; foreach (i : lst){ s = s + accFunc(i); } return s;  };",
+    functionFactory);
+  }
+
+  public <T> T eval(String formula, Map<String, Object> context, Class<T> toType) {
+    VariableResolverFactory myVariableResolverFactory = new MapVariableResolverFactory();
+    myVariableResolverFactory.setNextFactory(functionFactory);
+    return MVEL.eval(formula, context, myVariableResolverFactory, toType);
+  }
+}



View it on GitLab: https://salsa.debian.org/java-team/mvel/compare/502131fe1313f21797f751233cbdf0f274d8c126...1c71b40994133d4a6b9ef94d24433d76357a186a

-- 
View it on GitLab: https://salsa.debian.org/java-team/mvel/compare/502131fe1313f21797f751233cbdf0f274d8c126...1c71b40994133d4a6b9ef94d24433d76357a186a
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20190826/f2d8be02/attachment.html>


More information about the pkg-java-commits mailing list