diff --git a/CHANGELOG.md b/CHANGELOG.md
index dd46e05c9..ec976133c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,7 @@
-------------------------------------------------------------------------------------------------------------
-# 5.4.4 (2020-09-23)
+# 5.4.4 (2020-09-28)
### 新特性
* 【core 】 ServiceLoaderUtil改为使用contextClassLoader(pr#183@Gitee)
@@ -36,6 +36,7 @@
* 【core 】 修复新建默认TreeSet没有默认比较器导致的问题(issue#1101@Github)
* 【core 】 修复Linux下使用Windows路径分隔符导致的解压错误(issue#I1MW0E@Gitee)
* 【core 】 修复Word07Writer写出map问题(issue#I1W49R@Gitee)
+* 【script 】 修复函数库脚本执行问题
-------------------------------------------------------------------------------------------------------------
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java
index 2f0f95a5e..bb5e7af11 100644
--- a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java
@@ -44,13 +44,13 @@ public class NumberUtil {
private static final int DEFAUT_DIV_SCALE = 10;
/**
- * 0-20对应的阶乘,超过20的阶乘会超过Long.MAX_VALUE
- */
- private static final long[] FACTORIALS = new long[]{
- 1L, 1L, 2L, 6L, 24L, 120L, 720L, 5040L, 40320L, 362880L, 3628800L, 39916800L, 479001600L, 6227020800L,
- 87178291200L, 1307674368000L, 20922789888000L, 355687428096000L, 6402373705728000L, 121645100408832000L,
- 2432902008176640000L};
-
+ * 0-20对应的阶乘,超过20的阶乘会超过Long.MAX_VALUE
+ */
+ private static final long[] FACTORIALS = new long[]{
+ 1L, 1L, 2L, 6L, 24L, 120L, 720L, 5040L, 40320L, 362880L, 3628800L, 39916800L, 479001600L, 6227020800L,
+ 87178291200L, 1307674368000L, 20922789888000L, 355687428096000L, 6402373705728000L, 121645100408832000L,
+ 2432902008176640000L};
+
/**
* 提供精确的加法运算
*
@@ -448,7 +448,7 @@ public class NumberUtil {
return BigDecimal.ZERO;
}
- BigDecimal result =new BigDecimal(values[0]);
+ BigDecimal result = new BigDecimal(values[0]);
for (int i = 1; i < values.length; i++) {
result = result.multiply(new BigDecimal(values[i]));
}
@@ -756,13 +756,13 @@ public class NumberUtil {
/**
* 补充Math.ceilDiv() JDK8中添加了和Math.floorDiv()但却没有ceilDiv()
*
- * @param v1 被除数
- * @param v2 除数
+ * @param v1 被除数
+ * @param v2 除数
* @return 两个参数的商
* @since 5.3.3
*/
public static int ceilDiv(int v1, int v2) {
- return (int)Math.ceil((double)v1 / v2);
+ return (int) Math.ceil((double) v1 / v2);
}
// ------------------------------------------------------------------------------------------- round
@@ -1430,50 +1430,49 @@ public class NumberUtil {
* @return 结果
* @since 4.1.0
*/
- public static long factorial(long start, long end) {
- // 负数没有阶乘
- if(start < 0 || end < 0) {
- throw new IllegalArgumentException(String.format("Factorial start and end both must be >= 0, " +
- "but got start=%d, end=%d", start, end));
- }
- if (0L == start || start == end) {
- return 1L;
- }
- if (start < end) {
- return 0L;
- }
- return factorialMultiplyAndCheck(start, factorial(start - 1, end));
- }
-
- /**
- * 计算范围阶乘中校验中间的计算是否存在溢出,factorial提前做了负数和0的校验,因此这里没有校验数字的正负
- * @param a 乘数
- * @param b 被乘数
- * @return 如果 a * b的结果没有溢出直接返回,否则抛出异常
- */
- private static long factorialMultiplyAndCheck(long a, long b) {
- if (a <= Long.MAX_VALUE / b) {
- return a * b;
- }
- throw new IllegalArgumentException(String.format("Overflow in multiplication: {%d} * {%d}", a, b));
- }
+ public static long factorial(long start, long end) {
+ // 负数没有阶乘
+ if (start < 0 || end < 0) {
+ throw new IllegalArgumentException(StrUtil.format("Factorial start and end both must be >= 0, but got start={}, end={}", start, end));
+ }
+ if (0L == start || start == end) {
+ return 1L;
+ }
+ if (start < end) {
+ return 0L;
+ }
+ return factorialMultiplyAndCheck(start, factorial(start - 1, end));
+ }
- /**
- * 计算阶乘
- *
- * n! = n * (n-1) * ... * 2 * 1
- *
- *
- * @param n 阶乘起始
- * @return 结果
- */
- public static long factorial(long n) {
- if (n < 0 || n > 20) {
- throw new IllegalArgumentException(String.format("Factorial must have n >= 0 and n <= 20 for n!, " +
- "but got n = %d", n));
- }
- return FACTORIALS[(int) n];
- }
+ /**
+ * 计算范围阶乘中校验中间的计算是否存在溢出,factorial提前做了负数和0的校验,因此这里没有校验数字的正负
+ *
+ * @param a 乘数
+ * @param b 被乘数
+ * @return 如果 a * b的结果没有溢出直接返回,否则抛出异常
+ */
+ private static long factorialMultiplyAndCheck(long a, long b) {
+ if (a <= Long.MAX_VALUE / b) {
+ return a * b;
+ }
+ throw new IllegalArgumentException(StrUtil.format("Overflow in multiplication: {} * {}", a, b));
+ }
+
+ /**
+ * 计算阶乘
+ *
+ * n! = n * (n-1) * ... * 2 * 1
+ *
+ *
+ * @param n 阶乘起始
+ * @return 结果
+ */
+ public static long factorial(long n) {
+ if (n < 0 || n > 20) {
+ throw new IllegalArgumentException(StrUtil.format("Factorial must have n >= 0 and n <= 20 for n!, but got n = {}", n));
+ }
+ return FACTORIALS[(int) n];
+ }
/**
* 平方根算法
@@ -1736,11 +1735,11 @@ public class NumberUtil {
*/
public static boolean equals(BigDecimal bigNum1, BigDecimal bigNum2) {
//noinspection NumberEquality
- if (bigNum1 == bigNum2){
+ if (bigNum1 == bigNum2) {
// 如果用户传入同一对象,省略compareTo以提高性能。
return true;
}
- if (bigNum1==null || bigNum2==null){
+ if (bigNum1 == null || bigNum2 == null) {
return false;
}
return 0 == bigNum1.compareTo(bigNum2);
@@ -1838,7 +1837,7 @@ public class NumberUtil {
*
* @param numberArray 数字数组
* @return 最小值
- * @see ArrayUtil#min(Comparable[])
+ * @see ArrayUtil#min(Comparable[])
* @since 5.0.8
*/
public static BigDecimal min(BigDecimal... numberArray) {
@@ -2186,17 +2185,17 @@ public class NumberUtil {
public static BigDecimal pow(BigDecimal number, int n) {
return number.pow(n);
}
-
-
- /**
- * 判断一个整数是否是2的幂
- *
- * @param n 待验证的整数
- * @return 如果n是2的幂返回true, 反之返回false
- */
- public static boolean isPowerOfTwo(long n) {
- return (n > 0) && ((n & (n - 1)) == 0);
- }
+
+
+ /**
+ * 判断一个整数是否是2的幂
+ *
+ * @param n 待验证的整数
+ * @return 如果n是2的幂返回true, 反之返回false
+ */
+ public static boolean isPowerOfTwo(long n) {
+ return (n > 0) && ((n & (n - 1)) == 0);
+ }
/**
* 解析转换数字字符串为int型数字,规则如下:
diff --git a/hutool-script/src/main/java/cn/hutool/script/ScriptUtil.java b/hutool-script/src/main/java/cn/hutool/script/ScriptUtil.java
index 7c3061dc1..ec59b47ed 100644
--- a/hutool-script/src/main/java/cn/hutool/script/ScriptUtil.java
+++ b/hutool-script/src/main/java/cn/hutool/script/ScriptUtil.java
@@ -151,7 +151,12 @@ public class ScriptUtil {
}
/**
- * 执行Javascript脚本,返回Invocable
+ * 执行Javascript脚本,返回Invocable,此方法分为两种情况:
+ *
+ *
+ * - 执行的脚本返回值是可执行的脚本方法
+ * - 脚本为函数库,则ScriptEngine本身为可执行方法
+ *
*
* @param script 脚本内容
* @return 执行结果
@@ -159,11 +164,23 @@ public class ScriptUtil {
* @since 5.3.6
*/
public static Invocable evalInvocable(String script) throws ScriptRuntimeException {
- return (Invocable) eval(script);
+ final ScriptEngine jsEngine = getJsEngine();
+ final Object eval;
+ try {
+ eval = jsEngine.eval(script);
+ } catch (ScriptException e) {
+ throw new ScriptRuntimeException(e);
+ }
+ if(eval instanceof Invocable){
+ return (Invocable)eval;
+ } else if(jsEngine instanceof Invocable){
+ return (Invocable)jsEngine;
+ }
+ throw new ScriptRuntimeException("Script is not invocable !");
}
/**
- * 执行Javascript脚本
+ * 执行有返回值的Javascript脚本
*
* @param script 脚本内容
* @return 执行结果
@@ -179,7 +196,7 @@ public class ScriptUtil {
}
/**
- * 执行脚本
+ * 执行有返回值的脚本
*
* @param script 脚本内容
* @param context 脚本上下文
@@ -196,7 +213,7 @@ public class ScriptUtil {
}
/**
- * 执行脚本
+ * 执行有返回值的脚本
*
* @param script 脚本内容
* @param bindings 绑定的参数
diff --git a/hutool-script/src/test/java/cn/hutool/script/test/NashornDeepTest.java b/hutool-script/src/test/java/cn/hutool/script/test/NashornDeepTest.java
new file mode 100644
index 000000000..d74d87ffe
--- /dev/null
+++ b/hutool-script/src/test/java/cn/hutool/script/test/NashornDeepTest.java
@@ -0,0 +1,22 @@
+package cn.hutool.script.test;
+
+
+import cn.hutool.core.io.resource.ResourceUtil;
+import org.junit.Assert;
+
+import javax.script.Invocable;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+public class NashornDeepTest {
+
+ public static void main(String[] args) throws ScriptException, NoSuchMethodException {
+ ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
+
+ engine.eval(ResourceUtil.readUtf8Str("filter1.js"));
+
+ final Object filter1 = ((Invocable) engine).invokeFunction("filter1", 1, 2);
+ Assert.assertFalse((Boolean) filter1);
+ }
+}
diff --git a/hutool-script/src/test/java/cn/hutool/script/test/ScriptUtilTest.java b/hutool-script/src/test/java/cn/hutool/script/test/ScriptUtilTest.java
index 6fcbf57c3..d0fa8714b 100644
--- a/hutool-script/src/test/java/cn/hutool/script/test/ScriptUtilTest.java
+++ b/hutool-script/src/test/java/cn/hutool/script/test/ScriptUtilTest.java
@@ -1,7 +1,9 @@
package cn.hutool.script.test;
+import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.script.ScriptRuntimeException;
import cn.hutool.script.ScriptUtil;
+import org.junit.Assert;
import org.junit.Test;
import javax.script.CompiledScript;
@@ -31,6 +33,12 @@ public class ScriptUtilTest {
ScriptUtil.eval("print('Script test!');");
}
+ @Test
+ public void invokeTest() {
+ final Object result = ScriptUtil.invoke(ResourceUtil.readUtf8Str("filter1.js"), "filter1", 2, 1);
+ Assert.assertTrue((Boolean) result);
+ }
+
@Test
public void pythonTest() throws ScriptException {
final ScriptEngine pythonEngine = ScriptUtil.getPythonEngine();
diff --git a/hutool-script/src/test/resources/filter1.js b/hutool-script/src/test/resources/filter1.js
new file mode 100644
index 000000000..a059e4772
--- /dev/null
+++ b/hutool-script/src/test/resources/filter1.js
@@ -0,0 +1,6 @@
+function filter1(a, b) {
+ if (a > b) {
+ return a > b;
+ }
+ return false;
+}
\ No newline at end of file