Update mvel2 dependency
This commit is contained in:
parent
830a612bf8
commit
4607d89369
@ -85,7 +85,7 @@
|
|||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mvel</groupId>
|
<groupId>org.thingsboard</groupId>
|
||||||
<artifactId>mvel2</artifactId>
|
<artifactId>mvel2</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@ -22,15 +22,15 @@ import com.google.common.util.concurrent.MoreExecutors;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.mvel2.ExecutionContext;
|
||||||
import org.mvel2.MVEL;
|
import org.mvel2.MVEL;
|
||||||
import org.mvel2.ParserContext;
|
import org.mvel2.ParserContext;
|
||||||
import org.mvel2.optimizers.AccessorOptimizer;
|
import org.mvel2.SandboxedParserContext;
|
||||||
import org.mvel2.optimizers.OptimizerFactory;
|
import org.mvel2.optimizers.OptimizerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.ReflectionUtils;
|
|
||||||
import org.thingsboard.common.util.ThingsBoardExecutors;
|
import org.thingsboard.common.util.ThingsBoardExecutors;
|
||||||
import org.thingsboard.script.api.AbstractScriptInvokeService;
|
import org.thingsboard.script.api.AbstractScriptInvokeService;
|
||||||
import org.thingsboard.script.api.ScriptType;
|
import org.thingsboard.script.api.ScriptType;
|
||||||
@ -101,12 +101,9 @@ public class DefaultMvelInvokeService extends AbstractScriptInvokeService implem
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
super.init();
|
super.init();
|
||||||
Field field = ReflectionUtils.findField(OptimizerFactory.class, "accessorCompilers");
|
OptimizerFactory.setDefaultOptimizer(OptimizerFactory.SAFE_REFLECTIVE);
|
||||||
ReflectionUtils.makeAccessible(field);
|
parserContext = new SandboxedParserContext();
|
||||||
Map<String, AccessorOptimizer> accessorCompilers = (Map<String, AccessorOptimizer>) field.get(null);
|
parserContext.addImport("JSON", TbJson.class);
|
||||||
accessorCompilers.put(OptimizerFactory.SAFE_REFLECTIVE, new TbReflectiveAccessorOptimizer());
|
|
||||||
|
|
||||||
parserContext = new ParserContext(new TbMvelParserConfiguration());
|
|
||||||
executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(2, "mvel-executor"));
|
executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(2, "mvel-executor"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +156,9 @@ public class DefaultMvelInvokeService extends AbstractScriptInvokeService implem
|
|||||||
throw new TbScriptException(scriptId, TbScriptException.ErrorCode.OTHER, null, new RuntimeException("Script not found!"));
|
throw new TbScriptException(scriptId, TbScriptException.ErrorCode.OTHER, null, new RuntimeException("Script not found!"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return MVEL.executeExpression(script.getCompiledScript(), script.createVars(args));
|
ExecutionContext executionContext = new ExecutionContext();
|
||||||
|
// TODO:
|
||||||
|
return MVEL.executeExpression(script.getCompiledScript(), executionContext, script.createVars(args));
|
||||||
} catch (OutOfMemoryError e) {
|
} catch (OutOfMemoryError e) {
|
||||||
Runtime.getRuntime().gc();
|
Runtime.getRuntime().gc();
|
||||||
throw new TbScriptException(scriptId, TbScriptException.ErrorCode.OTHER, script.getScriptBody(), new RuntimeException("Memory error!"));
|
throw new TbScriptException(scriptId, TbScriptException.ErrorCode.OTHER, script.getScriptBody(), new RuntimeException("Memory error!"));
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
package org.thingsboard.script.api.mvel;
|
package org.thingsboard.script.api.mvel;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import org.mvel2.ExecutionContext;
|
||||||
|
import org.mvel2.util.ArgsRepackUtil;
|
||||||
import org.thingsboard.common.util.JacksonUtil;
|
import org.thingsboard.common.util.JacksonUtil;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -28,13 +30,13 @@ public class TbJson {
|
|||||||
return value != null ? JacksonUtil.toString(value) : "null";
|
return value != null ? JacksonUtil.toString(value) : "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object parse(String value) throws IOException {
|
public static Object parse(ExecutionContext ctx, String value) throws IOException {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
JsonNode node = JacksonUtil.toJsonNode(value);
|
JsonNode node = JacksonUtil.toJsonNode(value);
|
||||||
if (node.isObject()) {
|
if (node.isObject()) {
|
||||||
return JacksonUtil.convertValue(node, Map.class);
|
return ArgsRepackUtil.repack(ctx, JacksonUtil.convertValue(node, Map.class));
|
||||||
} else if (node.isArray()) {
|
} else if (node.isArray()) {
|
||||||
return JacksonUtil.convertValue(node, List.class);
|
return ArgsRepackUtil.repack(ctx, JacksonUtil.convertValue(node, List.class));
|
||||||
} else if (node.isDouble()) {
|
} else if (node.isDouble()) {
|
||||||
return node.doubleValue();
|
return node.doubleValue();
|
||||||
} else if (node.isLong()) {
|
} else if (node.isLong()) {
|
||||||
|
|||||||
@ -1,65 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright © 2016-2022 The Thingsboard Authors
|
|
||||||
*
|
|
||||||
* 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.thingsboard.script.api.mvel;
|
|
||||||
|
|
||||||
import org.mvel2.compiler.Accessor;
|
|
||||||
import org.mvel2.compiler.ExecutableAccessor;
|
|
||||||
import org.mvel2.compiler.ExecutableStatement;
|
|
||||||
import org.mvel2.integration.VariableResolverFactory;
|
|
||||||
import org.mvel2.optimizers.impl.refl.collection.ExprValueAccessor;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class TbMapCreator implements Accessor {
|
|
||||||
private Accessor[] keys;
|
|
||||||
private Accessor[] vals;
|
|
||||||
private int size;
|
|
||||||
|
|
||||||
public Object getValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory) {
|
|
||||||
Map map = new HashMap<>(size * 2);
|
|
||||||
for (int i = size - 1; i != -1; i--) {
|
|
||||||
//noinspection unchecked
|
|
||||||
map.put(getKey(i, ctx, elCtx, variableFactory), vals[i].getValue(ctx, elCtx, variableFactory));
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object getKey(int index, Object ctx, Object elCtx, VariableResolverFactory variableFactory) {
|
|
||||||
Accessor keyAccessor = keys[index];
|
|
||||||
if (keyAccessor instanceof ExprValueAccessor) {
|
|
||||||
ExecutableStatement executableStatement = ((ExprValueAccessor) keyAccessor).stmt;
|
|
||||||
if (executableStatement instanceof ExecutableAccessor) {
|
|
||||||
return ((ExecutableAccessor) executableStatement).getNode().getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keys[index].getValue(ctx, elCtx, variableFactory);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TbMapCreator(Accessor[] keys, Accessor[] vals) {
|
|
||||||
this.size = (this.keys = keys).length;
|
|
||||||
this.vals = vals;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object setValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory, Object value) {
|
|
||||||
// not implemented
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class getKnownEgressType() {
|
|
||||||
return Map.class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright © 2016-2022 The Thingsboard Authors
|
|
||||||
*
|
|
||||||
* 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.thingsboard.script.api.mvel;
|
|
||||||
|
|
||||||
import org.mvel2.compiler.AbstractParser;
|
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class TbMvelClassLoader extends URLClassLoader {
|
|
||||||
|
|
||||||
private static final Set<String> allowedClasses = new HashSet<>();
|
|
||||||
private static final Set<String> allowedPackages = new HashSet<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
|
|
||||||
AbstractParser.LITERALS.remove("System");
|
|
||||||
AbstractParser.LITERALS.remove("Runtime");
|
|
||||||
AbstractParser.LITERALS.remove("Class");
|
|
||||||
AbstractParser.LITERALS.remove("ClassLoader");
|
|
||||||
AbstractParser.LITERALS.remove("Thread");
|
|
||||||
AbstractParser.LITERALS.remove("Compiler");
|
|
||||||
AbstractParser.LITERALS.remove("ThreadLocal");
|
|
||||||
AbstractParser.LITERALS.remove("SecurityManager");
|
|
||||||
|
|
||||||
AbstractParser.CLASS_LITERALS.remove("System");
|
|
||||||
AbstractParser.CLASS_LITERALS.remove("Runtime");
|
|
||||||
AbstractParser.CLASS_LITERALS.remove("Class");
|
|
||||||
AbstractParser.CLASS_LITERALS.remove("ClassLoader");
|
|
||||||
AbstractParser.CLASS_LITERALS.remove("Thread");
|
|
||||||
AbstractParser.CLASS_LITERALS.remove("Compiler");
|
|
||||||
AbstractParser.CLASS_LITERALS.remove("ThreadLocal");
|
|
||||||
AbstractParser.CLASS_LITERALS.remove("SecurityManager");
|
|
||||||
AbstractParser.CLASS_LITERALS.put("JSON", TbJson.class);
|
|
||||||
AbstractParser.LITERALS.put("JSON", TbJson.class);
|
|
||||||
|
|
||||||
AbstractParser.CLASS_LITERALS.values().forEach(val -> allowedClasses.add(((Class) val).getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
allowedPackages.add("org.mvel2");
|
|
||||||
allowedPackages.add("java.util");
|
|
||||||
}
|
|
||||||
|
|
||||||
public TbMvelClassLoader() {
|
|
||||||
super(new URL[0], Thread.currentThread().getContextClassLoader());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
|
||||||
if (!classNameAllowed(name)) {
|
|
||||||
throw new ClassNotFoundException();
|
|
||||||
}
|
|
||||||
return super.loadClass(name, resolve);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
|
||||||
if (!classNameAllowed(name)) {
|
|
||||||
throw new ClassNotFoundException();
|
|
||||||
}
|
|
||||||
return super.loadClass(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean classNameAllowed(String name) {
|
|
||||||
if (allowedClasses.contains(name)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (String pkgName : allowedPackages) {
|
|
||||||
if (name.startsWith(pkgName)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright © 2016-2022 The Thingsboard Authors
|
|
||||||
*
|
|
||||||
* 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.thingsboard.script.api.mvel;
|
|
||||||
|
|
||||||
import org.mvel2.ParserConfiguration;
|
|
||||||
import org.mvel2.integration.VariableResolverFactory;
|
|
||||||
|
|
||||||
public class TbMvelParserConfiguration extends ParserConfiguration {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 5558151976348875590L;
|
|
||||||
|
|
||||||
TbMvelParserConfiguration() {
|
|
||||||
setClassLoader(new TbMvelClassLoader());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VariableResolverFactory getVariableFactory(VariableResolverFactory factory) {
|
|
||||||
if (Thread.interrupted()) {
|
|
||||||
throw new RuntimeException("Thread is interrupted!");
|
|
||||||
}
|
|
||||||
return new TbMvelResolverFactory(factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright © 2016-2022 The Thingsboard Authors
|
|
||||||
*
|
|
||||||
* 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.thingsboard.script.api.mvel;
|
|
||||||
|
|
||||||
import org.mvel2.integration.VariableResolver;
|
|
||||||
import org.mvel2.integration.VariableResolverFactory;
|
|
||||||
import org.mvel2.integration.impl.StackResetResolverFactory;
|
|
||||||
|
|
||||||
public class TbMvelResolverFactory extends StackResetResolverFactory {
|
|
||||||
|
|
||||||
public TbMvelResolverFactory(VariableResolverFactory delegate) {
|
|
||||||
super(delegate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VariableResolver getVariableResolver(String name) {
|
|
||||||
if (Thread.interrupted()) {
|
|
||||||
throw new RuntimeException("Thread is interrupted!");
|
|
||||||
}
|
|
||||||
return super.getVariableResolver(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,120 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright © 2016-2022 The Thingsboard Authors
|
|
||||||
*
|
|
||||||
* 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.thingsboard.script.api.mvel;
|
|
||||||
|
|
||||||
import org.mvel2.ParserContext;
|
|
||||||
import org.mvel2.compiler.Accessor;
|
|
||||||
import org.mvel2.integration.VariableResolverFactory;
|
|
||||||
import org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer;
|
|
||||||
import org.mvel2.optimizers.impl.refl.collection.ArrayCreator;
|
|
||||||
import org.mvel2.optimizers.impl.refl.collection.ExprValueAccessor;
|
|
||||||
import org.mvel2.optimizers.impl.refl.collection.ListCreator;
|
|
||||||
import org.mvel2.optimizers.impl.refl.nodes.Union;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.mvel2.util.CompilerTools.expectType;
|
|
||||||
import static org.mvel2.util.ParseTools.findClass;
|
|
||||||
import static org.mvel2.util.ParseTools.getBaseComponentType;
|
|
||||||
import static org.mvel2.util.ParseTools.getSubComponentType;
|
|
||||||
import static org.mvel2.util.ParseTools.repeatChar;
|
|
||||||
|
|
||||||
public class TbReflectiveAccessorOptimizer extends ReflectiveAccessorOptimizer {
|
|
||||||
private Object ctx;
|
|
||||||
private Class returnType;
|
|
||||||
private VariableResolverFactory variableFactory;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Accessor optimizeCollection(ParserContext pCtx, Object o, Class type, char[] property, int start, int offset,
|
|
||||||
Object ctx, Object thisRef, VariableResolverFactory factory) {
|
|
||||||
this.start = this.cursor = start;
|
|
||||||
this.length = start + offset;
|
|
||||||
this.returnType = type;
|
|
||||||
this.ctx = ctx;
|
|
||||||
this.variableFactory = factory;
|
|
||||||
this.pCtx = pCtx;
|
|
||||||
|
|
||||||
Accessor root = _getAccessor(o, returnType);
|
|
||||||
|
|
||||||
if (property != null && length > start) {
|
|
||||||
return new Union(pCtx, root, property, cursor, offset);
|
|
||||||
} else {
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Accessor _getAccessor(Object o, Class type) {
|
|
||||||
if (o instanceof List) {
|
|
||||||
Accessor[] a = new Accessor[((List) o).size()];
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for (Object item : (List) o) {
|
|
||||||
a[i++] = _getAccessor(item, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
returnType = List.class;
|
|
||||||
|
|
||||||
return new ListCreator(a);
|
|
||||||
} else if (o instanceof Map) {
|
|
||||||
Accessor[] k = new Accessor[((Map) o).size()];
|
|
||||||
Accessor[] v = new Accessor[k.length];
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for (Object item : ((Map) o).keySet()) {
|
|
||||||
k[i] = _getAccessor(item, type); // key
|
|
||||||
v[i++] = _getAccessor(((Map) o).get(item), type); // value
|
|
||||||
}
|
|
||||||
|
|
||||||
returnType = Map.class;
|
|
||||||
|
|
||||||
return new TbMapCreator(k, v);
|
|
||||||
} else if (o instanceof Object[]) {
|
|
||||||
Accessor[] a = new Accessor[((Object[]) o).length];
|
|
||||||
int i = 0;
|
|
||||||
int dim = 0;
|
|
||||||
|
|
||||||
if (type != null) {
|
|
||||||
String nm = type.getName();
|
|
||||||
while (nm.charAt(dim) == '[') dim++;
|
|
||||||
} else {
|
|
||||||
type = Object[].class;
|
|
||||||
dim = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class base = getBaseComponentType(type);
|
|
||||||
Class cls = dim > 1 ? findClass(null, repeatChar('[', dim - 1) + "L" + base.getName() + ";", pCtx)
|
|
||||||
: type;
|
|
||||||
|
|
||||||
for (Object item : (Object[]) o) {
|
|
||||||
expectType(pCtx, a[i++] = _getAccessor(item, cls), base, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ArrayCreator(a, getSubComponentType(type));
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new RuntimeException("this error should never throw:" + getBaseComponentType(type).getName(), e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (returnType == null) returnType = Object.class;
|
|
||||||
if (type.isArray()) {
|
|
||||||
return new ExprValueAccessor((String) o, type, ctx, variableFactory, pCtx);
|
|
||||||
} else {
|
|
||||||
return new ExprValueAccessor((String) o, Object.class, ctx, variableFactory, pCtx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
4
pom.xml
4
pom.xml
@ -77,7 +77,7 @@
|
|||||||
<zookeeper.version>3.5.5</zookeeper.version>
|
<zookeeper.version>3.5.5</zookeeper.version>
|
||||||
<protobuf.version>3.17.2</protobuf.version>
|
<protobuf.version>3.17.2</protobuf.version>
|
||||||
<grpc.version>1.42.1</grpc.version>
|
<grpc.version>1.42.1</grpc.version>
|
||||||
<mvel.version>2.4.14.Final</mvel.version>
|
<mvel.version>2.4.16TB</mvel.version>
|
||||||
<lombok.version>1.18.18</lombok.version>
|
<lombok.version>1.18.18</lombok.version>
|
||||||
<paho.client.version>1.2.4</paho.client.version>
|
<paho.client.version>1.2.4</paho.client.version>
|
||||||
<netty.version>4.1.75.Final</netty.version>
|
<netty.version>4.1.75.Final</netty.version>
|
||||||
@ -1575,7 +1575,7 @@
|
|||||||
<version>${grpc.version}</version>
|
<version>${grpc.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mvel</groupId>
|
<groupId>org.thingsboard</groupId>
|
||||||
<artifactId>mvel2</artifactId>
|
<artifactId>mvel2</artifactId>
|
||||||
<version>${mvel.version}</version>
|
<version>${mvel.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user