mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2024-12-23 07:34:31 -06:00
bump source and target to Java 15
This commit is contained in:
parent
2752fa50b5
commit
7e6aa1a2d8
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
- uses: actions/setup-java@v1
|
||||
name: setup java
|
||||
with:
|
||||
java-version: '14'
|
||||
java-version: '15'
|
||||
java-package: jdk
|
||||
architecture: x64
|
||||
|
||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
- name: setup java
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: '14'
|
||||
java-version: '15'
|
||||
java-package: jdk
|
||||
architecture: x64
|
||||
|
||||
|
@ -9,7 +9,8 @@ The latest release of NoSQLBench is always available from github releases.
|
||||
- (be sure to `chmod +x nb` once you download it)
|
||||
- download [the latest release of nb.jar](https://github.com/nosqlbench/nosqlbench/releases/latest/download/nb.jar), a
|
||||
single-jar application.
|
||||
- This requires java 14 or later, make sure your `java -version` command says that you are on Java 14 or later.
|
||||
- This requires java 15 or later, make sure your `java -version
|
||||
` command says that you are on Java 15 or later.
|
||||
|
||||
## Docker
|
||||
|
||||
|
@ -11,11 +11,12 @@ import io.nosqlbench.activitytype.cql.core.ProxyTranslator;
|
||||
import io.nosqlbench.engine.api.activityapi.core.Shutdownable;
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
|
||||
import io.nosqlbench.engine.api.scripting.NashornEvaluator;
|
||||
import io.nosqlbench.engine.api.scripting.ExprEvaluator;
|
||||
import io.nosqlbench.engine.api.scripting.GraalJsEvaluator;
|
||||
import io.nosqlbench.engine.api.util.SSLKsFactory;
|
||||
import io.nosqlbench.nb.api.errors.BasicError;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.File;
|
||||
@ -129,7 +130,7 @@ public class CQLSessionCache implements Shutdownable {
|
||||
if (clusteropts.isPresent()) {
|
||||
try {
|
||||
logger.info("applying cbopts:" + clusteropts.get());
|
||||
NashornEvaluator<DseCluster.Builder> clusterEval = new NashornEvaluator<>(DseCluster.Builder.class);
|
||||
ExprEvaluator<DseCluster.Builder> clusterEval = new GraalJsEvaluator<>(DseCluster.Builder.class);
|
||||
clusterEval.put("builder", builder);
|
||||
String importEnv =
|
||||
"load(\"nashorn:mozilla_compat.js\");\n" +
|
||||
|
@ -19,7 +19,7 @@ import io.nosqlbench.activitytype.cqld4.core.ProxyTranslator;
|
||||
import io.nosqlbench.engine.api.activityapi.core.Shutdownable;
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
|
||||
import io.nosqlbench.engine.api.scripting.NashornEvaluator;
|
||||
import io.nosqlbench.engine.api.scripting.GraalJsEvaluator;
|
||||
import io.nosqlbench.engine.api.util.SSLKsFactory;
|
||||
import org.apache.tinkerpop.gremlin.driver.Cluster;
|
||||
import org.graalvm.options.OptionMap;
|
||||
@ -170,7 +170,7 @@ public class CQLSessionCache implements Shutdownable {
|
||||
if (clusteropts.isPresent()) {
|
||||
try {
|
||||
logger.info("applying cbopts:" + clusteropts.get());
|
||||
NashornEvaluator<CqlSessionBuilder> clusterEval = new NashornEvaluator<>(CqlSessionBuilder.class);
|
||||
GraalJsEvaluator<CqlSessionBuilder> clusterEval = new GraalJsEvaluator<>(CqlSessionBuilder.class);
|
||||
clusterEval.put("builder", builder);
|
||||
String importEnv =
|
||||
"load(\"nashorn:mozilla_compat.js\");\n" +
|
||||
|
@ -23,7 +23,7 @@ import io.nosqlbench.engine.api.activityimpl.ParameterMap;
|
||||
import io.nosqlbench.engine.api.activityimpl.SimpleActivity;
|
||||
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
|
||||
import io.nosqlbench.engine.api.metrics.ExceptionMeterMetrics;
|
||||
import io.nosqlbench.engine.api.scripting.NashornEvaluator;
|
||||
import io.nosqlbench.engine.api.scripting.GraalJsEvaluator;
|
||||
import io.nosqlbench.engine.api.templating.StrInterpolator;
|
||||
import io.nosqlbench.engine.api.util.TagFilter;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@ -188,7 +188,7 @@ public class GraphActivity extends SimpleActivity implements ActivityDefObserver
|
||||
if (clusteropts.isPresent()) {
|
||||
try {
|
||||
logger.info("applying cbopts:" + clusteropts.get());
|
||||
NashornEvaluator<DseCluster.Builder> clusterEval = new NashornEvaluator<>(DseCluster.Builder.class);
|
||||
GraalJsEvaluator<DseCluster.Builder> clusterEval = new GraalJsEvaluator<>(DseCluster.Builder.class);
|
||||
clusterEval.put("builder", builder);
|
||||
String importEnv =
|
||||
"load(\"nashorn:mozilla_compat.js\");\n" +
|
||||
|
@ -49,6 +49,13 @@
|
||||
<artifactId>graal-sdk</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.graalvm.js</groupId>
|
||||
<artifactId>js</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>io.dropwizard.metrics</groupId>
|
||||
<artifactId>metrics-core</artifactId>
|
||||
|
@ -35,7 +35,7 @@ package io.nosqlbench.engine.api.scripting;
|
||||
*
|
||||
* @param <T> The return type that is needed by the caller
|
||||
*/
|
||||
public interface Evaluator<T> {
|
||||
public interface ExprEvaluator<T> {
|
||||
|
||||
/**
|
||||
* Evaluate the provided script, returning the value that it yields
|
||||
@ -45,17 +45,24 @@ public interface Evaluator<T> {
|
||||
T eval();
|
||||
|
||||
/**
|
||||
* @param scriptText Nashorn compatible script text
|
||||
* @return this NahornEvaluator, for method chaining
|
||||
* @param scriptText script text
|
||||
* @return this ExprEvaluator<T>, for method chaining
|
||||
*/
|
||||
NashornEvaluator<T> script(String scriptText);
|
||||
ExprEvaluator<T> script(String scriptText);
|
||||
|
||||
/**
|
||||
* Set the variable environment of the evaluator
|
||||
*
|
||||
* @param varName the variable name to add to the environment
|
||||
* @param var the object to bind to the varname
|
||||
* @return this NashornEvaluator, for method chaining
|
||||
* @return this ExprEvaluator<T>, for method chaining
|
||||
*/
|
||||
NashornEvaluator<T> put(String varName, Object var);
|
||||
ExprEvaluator<T> put(String varName, Object var);
|
||||
|
||||
default ExprEvaluator<T> put(Object... vars) {
|
||||
for (int i = 0; i < vars.length; i += 2) {
|
||||
this.put(vars[i].toString(), vars[i + 1]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package io.nosqlbench.engine.api.scripting;
|
||||
|
||||
import org.graalvm.polyglot.*;
|
||||
|
||||
public class GraalJsEvaluator<T> implements ExprEvaluator<T> {
|
||||
|
||||
private final Class<T> resultType;
|
||||
private Context context;
|
||||
private Source script;
|
||||
|
||||
public GraalJsEvaluator(Class<T> resultType) {
|
||||
this.resultType = resultType;
|
||||
}
|
||||
|
||||
private Context getContext() {
|
||||
if (context == null) {
|
||||
Context.Builder contextSettings = Context.newBuilder("js")
|
||||
.allowHostAccess(HostAccess.ALL)
|
||||
.allowNativeAccess(true)
|
||||
.allowCreateThread(true)
|
||||
.allowIO(true)
|
||||
.allowHostClassLookup(s -> true)
|
||||
.allowHostClassLoading(true)
|
||||
.allowCreateProcess(true)
|
||||
.allowAllAccess(true)
|
||||
.allowEnvironmentAccess(EnvironmentAccess.INHERIT)
|
||||
.allowPolyglotAccess(PolyglotAccess.ALL)
|
||||
.option("js.ecmascript-version", "2020")
|
||||
.option("js.nashorn-compat", "true");
|
||||
context = contextSettings.build();
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T eval() {
|
||||
Value result = getContext().eval(this.script);
|
||||
T asType = result.as(resultType);
|
||||
return asType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExprEvaluator<T> script(String scriptText) {
|
||||
this.script = Source.create("js", scriptText);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExprEvaluator<T> put(String varName, Object var) {
|
||||
getContext().getBindings("js").putMember(varName, var);
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2016 jshook
|
||||
* 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 io.nosqlbench.engine.api.scripting;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import javax.script.*;
|
||||
|
||||
/**
|
||||
* public void setBindings(Bindings bindings, int scope);
|
||||
*
|
||||
* @param <T> generic parameter for return types from this evaluator
|
||||
*/
|
||||
public class NashornEvaluator<T> implements Evaluator<T> {
|
||||
private final static Logger logger = LogManager.getLogger(NashornEvaluator.class);
|
||||
|
||||
private static final ScriptEngineManager engineManager = new ScriptEngineManager();
|
||||
private final ScriptEngine scriptEngine;
|
||||
private final SimpleBindings bindings = new SimpleBindings();
|
||||
private String script = "";
|
||||
private final Class<? extends T> resultType;
|
||||
private CompiledScript compiled;
|
||||
|
||||
/**
|
||||
* Create a new NashornEvaluator.
|
||||
*
|
||||
* @param resultType The required class of the result type, which must extend generic parameter type t.
|
||||
* @param vars Optional pairs of names and values. vars[0] is a name, vars[1] is a value, ...
|
||||
*/
|
||||
public NashornEvaluator(Class<? extends T> resultType, Object... vars) {
|
||||
this.scriptEngine = engineManager.getEngineByName("nashorn");
|
||||
this.scriptEngine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
|
||||
this.resultType = resultType;
|
||||
for (int i = 0; i < vars.length; i += 2) {
|
||||
this.put(vars[i].toString(), vars[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the script that will be evaluated.
|
||||
* @param scriptText Nashorn compatible script text
|
||||
* @return this NashornEvaluator, for method chaining
|
||||
*/
|
||||
@Override
|
||||
public NashornEvaluator<T> script(String scriptText) {
|
||||
this.script = scriptText;
|
||||
try {
|
||||
Object result = null;
|
||||
if (scriptEngine instanceof Compilable) {
|
||||
logger.info("Using direct script compilation");
|
||||
Compilable compilableEngine = (Compilable) scriptEngine;
|
||||
compiled = compilableEngine.compile(script);
|
||||
logger.trace("Compiled script:" + script);
|
||||
} else {
|
||||
logger.trace("Did not compile script: " + script);
|
||||
}
|
||||
} catch (ScriptException e) {
|
||||
throw new RuntimeException("Script compilation error for " + scriptText + ": ", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Evaluate the compiled script if it is compiled, or the raw script text otherwise.
|
||||
* It is not an error to call this without setting the script to something other than the default of "",
|
||||
* but it not very useful in most cases.
|
||||
* @return The value produced by the script, compiled or not
|
||||
*/
|
||||
@Override
|
||||
public T eval() {
|
||||
T result = null;
|
||||
try {
|
||||
Object evaled = null;
|
||||
if (compiled != null) {
|
||||
evaled = compiled.eval();
|
||||
} else {
|
||||
evaled = scriptEngine.eval(script);
|
||||
}
|
||||
result = convert(resultType, evaled);
|
||||
} catch (ScriptException e) {
|
||||
throw new RuntimeException("Script error while evaluating result for '" + script + "':", e);
|
||||
} catch (Exception o) {
|
||||
throw new RuntimeException("Non-Script error while evaluating result for '" + script + "':", o);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a varianble into the script environment
|
||||
* @param varName the variable name to add to the environment
|
||||
* @param var the object to bind to the varname
|
||||
* @return this NashornEvaluator, for method chaining
|
||||
*/
|
||||
@Override
|
||||
public NashornEvaluator<T> put(String varName, Object var) {
|
||||
bindings.put(varName, var);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert some basic types from the script to the requested type. This makes it easier
|
||||
* to deal with issues across the type systems, with the risk of unintended conversions.
|
||||
* Be choosy about what you support here. Less is more.
|
||||
* @param expectedType the wanted type to return
|
||||
* @param result the result produced by the script
|
||||
* @return the converted value
|
||||
*/
|
||||
private T convert(Class<? extends T> expectedType, Object result) {
|
||||
if (expectedType.isAssignableFrom(result.getClass())) {
|
||||
return expectedType.cast(result);
|
||||
}
|
||||
String desiredClass = expectedType.getSimpleName();
|
||||
Class<?> resultClass = result.getClass();
|
||||
|
||||
if (resultClass == Double.class) {
|
||||
switch (desiredClass) {
|
||||
case "Long":
|
||||
return expectedType.cast(((Double) result).longValue());
|
||||
case "Integer":
|
||||
return expectedType.cast(((Double) result).intValue());
|
||||
case "Float":
|
||||
return expectedType.cast(((Double) result).floatValue());
|
||||
default:
|
||||
throw new RuntimeException("Incompatible result type requested for conversion from " + resultClass + " to " + desiredClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (resultClass == Long.class) {
|
||||
switch (desiredClass) {
|
||||
case "Integer":
|
||||
return expectedType.cast(((Long) result).intValue());
|
||||
default:
|
||||
throw new RuntimeException("Incompatible result type requested for conversion from " + resultClass + " to " + desiredClass);
|
||||
}
|
||||
}
|
||||
throw new RuntimeException(
|
||||
"Incompatible input type for conversion from evaluator:" + result.getClass() + ", " +
|
||||
"when type " + expectedType.getSimpleName() + " was needed.");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -23,19 +23,19 @@ import java.util.Date;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class NashornEvaluatorTest {
|
||||
public class GraalJsEvaluatorTest {
|
||||
|
||||
@Test
|
||||
public void testBasicOperations() {
|
||||
NashornEvaluator<Long> ne = new NashornEvaluator<>(Long.class);
|
||||
ne.put("one",1L).put("two",2L);
|
||||
GraalJsEvaluator<Long> ne = new GraalJsEvaluator<>(Long.class);
|
||||
ne.put("one", 1L).put("two", 2L);
|
||||
Long sum = ne.script("one + two;").eval();
|
||||
assertThat(sum).isEqualTo(3L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaReturnType() {
|
||||
NashornEvaluator<Date> dateEval = new NashornEvaluator<>(Date.class);
|
||||
GraalJsEvaluator<Date> dateEval = new GraalJsEvaluator<>(Date.class);
|
||||
dateEval.script("var d = new java.util.Date(234); d;");
|
||||
Date aDate = dateEval.eval();
|
||||
assertThat(aDate).isEqualTo(new Date(234));
|
||||
@ -43,7 +43,8 @@ public class NashornEvaluatorTest {
|
||||
|
||||
@Test
|
||||
public void testOneLiner() {
|
||||
String result = new NashornEvaluator<String>(String.class, "fname", "afirstname", "lname", "alastname")
|
||||
String result = new GraalJsEvaluator<String>(String.class)
|
||||
.put("fname", "afirstname", "lname", "alastname")
|
||||
.script("fname + lname").eval();
|
||||
assertThat(result).isEqualTo("afirstnamealastname");
|
||||
}
|
@ -403,9 +403,8 @@ public class NBCLIOptions {
|
||||
arglist.removeFirst();
|
||||
break;
|
||||
case NASHORN_ENGINE:
|
||||
engine = Scenario.Engine.Nashorn;
|
||||
arglist.removeFirst();
|
||||
break;
|
||||
throw new RuntimeException("The nashorn engine has been deprecated in this major version of " +
|
||||
"NoSQLBench");
|
||||
case COMPILE_SCRIPT:
|
||||
arglist.removeFirst();
|
||||
compileScript = true;
|
||||
|
@ -1,285 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2016 jshook
|
||||
* 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 io.nosqlbench.engine.core.metrics;
|
||||
|
||||
import com.codahale.metrics.*;
|
||||
import com.codahale.metrics.Timer;
|
||||
import io.nosqlbench.engine.core.script.ReadOnlyBindings;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class NashornMetricRegistryBindings extends ReadOnlyBindings implements MetricRegistryListener {
|
||||
|
||||
private final static Logger logger = LogManager.getLogger(NashornMetricRegistryBindings.class);
|
||||
|
||||
private final MetricRegistry registry;
|
||||
private final MetricMap metricMap = new MetricMap("ROOT");
|
||||
private final boolean failfast = true;
|
||||
|
||||
public NashornMetricRegistryBindings(MetricRegistry registry) {
|
||||
this.registry = registry;
|
||||
registry.addListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return metricMap.map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return metricMap.map.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return metricMap.map.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return metricMap.map.containsValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
Object got = metricMap.map.get(key);
|
||||
if (got==null) {
|
||||
throw new RuntimeException("Attempted to get metrics node with name '" + key + "', but it was not found. Perhaps you were looking for one of its children: "
|
||||
+ this.keySet().stream().collect(Collectors.joining(",","[","]")));
|
||||
}
|
||||
return got;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> keySet() {
|
||||
return metricMap.map.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Object> values() {
|
||||
return metricMap.map.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<String, Object>> entrySet() {
|
||||
return metricMap.map.entrySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGaugeAdded(String name, Gauge<?> metric) {
|
||||
MetricMap parent = findParentNodeOf(name);
|
||||
parent.map.put(nodeNameOf(name), metric);
|
||||
}
|
||||
|
||||
private String nodeNameOf(String name) {
|
||||
String[] split = name.split("\\.");
|
||||
return split[split.length - 1];
|
||||
}
|
||||
|
||||
private synchronized void cleanEmptyMaps(MetricMap m) {
|
||||
while (m.isEmpty() && m.parent != null) {
|
||||
logger.debug("removing empty map:" + m.name);
|
||||
MetricMap parent = m.parent;
|
||||
m.parent = null;
|
||||
parent.map.remove(m.name);
|
||||
m = parent;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized MetricMap findParentNodeOf(String fullName) {
|
||||
String[] names = fullName.split("\\.");
|
||||
MetricMap m = metricMap;
|
||||
for (int i = 0; i < names.length - 1; i++) {
|
||||
String edge = names[i];
|
||||
if (m.map.containsKey(edge)) {
|
||||
Object o = m.map.get(edge);
|
||||
if (o instanceof MetricMap) {
|
||||
m = (MetricMap) m.map.get(edge);
|
||||
logger.trace("traversing edge:" + edge + " while pathing to " + fullName);
|
||||
|
||||
} else {
|
||||
String error = "edge exists at level:" + i + ", while pathing to " + fullName;
|
||||
logger.error(error);
|
||||
if (failfast) {
|
||||
throw new RuntimeException(error);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MetricMap newMap = new MetricMap(edge, m);
|
||||
m.map.put(edge, newMap);
|
||||
m = newMap;
|
||||
logger.debug("adding edge:" + edge + " while pathing to " + fullName);
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGaugeRemoved(String name) {
|
||||
MetricMap parent = findParentNodeOf(name);
|
||||
parent.map.remove(nodeNameOf(name));
|
||||
cleanEmptyMaps(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCounterAdded(String name, Counter metric) {
|
||||
MetricMap parent = findParentNodeOf(name);
|
||||
parent.map.put(nodeNameOf(name), metric);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCounterRemoved(String name) {
|
||||
MetricMap parent = findParentNodeOf(name);
|
||||
parent.map.remove(nodeNameOf(name));
|
||||
cleanEmptyMaps(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHistogramAdded(String name, Histogram metric) {
|
||||
MetricMap parent = findParentNodeOf(name);
|
||||
parent.map.put(nodeNameOf(name), metric);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHistogramRemoved(String name) {
|
||||
MetricMap parent = findParentNodeOf(name);
|
||||
parent.map.remove(nodeNameOf(name));
|
||||
cleanEmptyMaps(parent);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMeterAdded(String name, Meter metric) {
|
||||
MetricMap parent = findParentNodeOf(name);
|
||||
parent.map.put(nodeNameOf(name), metric);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMeterRemoved(String name) {
|
||||
MetricMap parent = findParentNodeOf(name);
|
||||
parent.map.remove(nodeNameOf(name));
|
||||
cleanEmptyMaps(parent);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerAdded(String name, Timer metric) {
|
||||
MetricMap parent = findParentNodeOf(name);
|
||||
parent.map.put(nodeNameOf(name), metric);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerRemoved(String name) {
|
||||
MetricMap parent = findParentNodeOf(name);
|
||||
parent.map.remove(nodeNameOf(name));
|
||||
cleanEmptyMaps(parent);
|
||||
|
||||
}
|
||||
|
||||
public Map<String, Metric> getMetrics() {
|
||||
return getMetrics(new LinkedHashMap<String, Metric>(), "metrics", metricMap);
|
||||
}
|
||||
|
||||
private Map<String, Metric> getMetrics(Map<String, Metric> totalMap, String prefix, MetricMap map) {
|
||||
for (Entry<String, Object> mEntry : map.entrySet()) {
|
||||
Object o = mEntry.getValue();
|
||||
String name = prefix + "." + mEntry.getKey();
|
||||
if (o instanceof Metric) {
|
||||
totalMap.put(name, (Metric) o);
|
||||
} else if (o instanceof MetricMap) {
|
||||
getMetrics(totalMap, name, (MetricMap) o);
|
||||
} else {
|
||||
throw new RuntimeException("entry value must be either a Metric or a MetricMap");
|
||||
}
|
||||
}
|
||||
return totalMap;
|
||||
}
|
||||
|
||||
private class MetricMap extends ReadOnlyBindings {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
MetricMap parent = null;
|
||||
public String name;
|
||||
|
||||
MetricMap(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public MetricMap(String name, MetricMap parent) {
|
||||
this.parent = parent;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
boolean containsKey=map.containsKey(key);
|
||||
if (containsKey==false) {
|
||||
throw new RuntimeException("Attempted to get metrics node with name '" + key + "', but it was not found. Perhaps you " +
|
||||
"were looking for one of " + this.map.keySet().stream().collect(Collectors.joining(",","[","]")));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return map.containsValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
Object got=map.get(key);
|
||||
if (got==null) {
|
||||
throw new RuntimeException("Attempted to get metrics node with name '" + key + "', but it was not found. Perhaps you " +
|
||||
"were looking for one of " + this.map.keySet().stream().collect(Collectors.joining(",","[","]")));
|
||||
}
|
||||
return got;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> keySet() {
|
||||
return map.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Object> values() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<String, Object>> entrySet() {
|
||||
return map.entrySet();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ import org.graalvm.polyglot.Value;
|
||||
import org.graalvm.polyglot.proxy.ProxyObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A view of metrics objects as an object tree.
|
||||
@ -124,7 +125,7 @@ public class PolyglotMetricRegistryBindings implements ProxyObject, MetricRegist
|
||||
|
||||
@Override
|
||||
public void onTimerAdded(String name, Timer timer) {
|
||||
metrics.add(name,timer);
|
||||
metrics.add(name, timer);
|
||||
logger.info("timer added: " + name);
|
||||
}
|
||||
|
||||
@ -134,6 +135,10 @@ public class PolyglotMetricRegistryBindings implements ProxyObject, MetricRegist
|
||||
logger.info("timer removed: " + name);
|
||||
}
|
||||
|
||||
public Map<String, Metric> getMetrics() {
|
||||
throw new RuntimeException("implement me");
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public int size() {
|
||||
// return metricMap.map.size();
|
||||
|
@ -19,13 +19,13 @@ import io.nosqlbench.engine.api.activityapi.core.Activity;
|
||||
import io.nosqlbench.engine.api.activityapi.core.ActivityType;
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
|
||||
import io.nosqlbench.engine.core.metrics.NashornMetricRegistryBindings;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import io.nosqlbench.engine.core.metrics.PolyglotMetricRegistryBindings;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.Timer;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
@ -68,7 +68,7 @@ public class MetricsMapper {
|
||||
throw new RuntimeException("Activity type '" + activityDef.getActivityType() + "' does not exist in this runtime.");
|
||||
}
|
||||
Activity activity = activityType.get().getAssembledActivity(activityDef, new HashMap<>());
|
||||
NashornMetricRegistryBindings nashornMetricRegistryBindings = new NashornMetricRegistryBindings(ActivityMetrics.getMetricRegistry());
|
||||
PolyglotMetricRegistryBindings nashornMetricRegistryBindings = new PolyglotMetricRegistryBindings(ActivityMetrics.getMetricRegistry());
|
||||
activity.initActivity();
|
||||
activity.getInputDispenserDelegate().getInput(0);
|
||||
activity.getActionDispenserDelegate().getAction(0);
|
||||
|
@ -24,11 +24,9 @@ import io.nosqlbench.engine.core.PolyglotScenarioController;
|
||||
import io.nosqlbench.engine.core.ScenarioController;
|
||||
import io.nosqlbench.engine.core.ScenarioResult;
|
||||
import io.nosqlbench.engine.core.annotation.Annotators;
|
||||
import io.nosqlbench.engine.core.metrics.NashornMetricRegistryBindings;
|
||||
import io.nosqlbench.engine.core.metrics.PolyglotMetricRegistryBindings;
|
||||
import io.nosqlbench.nb.api.Layer;
|
||||
import io.nosqlbench.nb.api.annotations.Annotation;
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.graalvm.polyglot.Context;
|
||||
@ -87,8 +85,8 @@ public class Scenario implements Callable<ScenarioResult> {
|
||||
private long endedAtMillis = -1L;
|
||||
|
||||
public enum Engine {
|
||||
Nashorn,
|
||||
Graalvm
|
||||
Graalvm,
|
||||
Nashorn
|
||||
}
|
||||
|
||||
public Scenario(
|
||||
@ -153,12 +151,7 @@ public class Scenario implements Callable<ScenarioResult> {
|
||||
|
||||
switch (engine) {
|
||||
case Nashorn:
|
||||
NashornScriptEngineFactory f = new NashornScriptEngineFactory();
|
||||
this.scriptEngine = f.getScriptEngine("--language=es6");
|
||||
|
||||
// engineManager.getEngineByName("nashorn");
|
||||
// TODO: Figure out how to do this in engine bindings: --language=es-6
|
||||
break;
|
||||
throw new RuntimeException("The nashorn engine has been deprecated in this version of NoSQLBench.");
|
||||
case Graalvm:
|
||||
Context.Builder contextSettings = Context.newBuilder("js")
|
||||
.allowHostAccess(HostAccess.ALL)
|
||||
@ -201,7 +194,7 @@ public class Scenario implements Callable<ScenarioResult> {
|
||||
// https://github.com/graalvm/graaljs/blob/master/docs/user/JavaInterop.md
|
||||
if (wantsGraaljsCompatMode) {
|
||||
scriptEngine.put("scenario", scenarioController);
|
||||
scriptEngine.put("metrics", new NashornMetricRegistryBindings(metricRegistry));
|
||||
scriptEngine.put("metrics", new PolyglotMetricRegistryBindings(metricRegistry));
|
||||
scriptEngine.put("activities", new NashornActivityBindings(scenarioController));
|
||||
} else {
|
||||
scriptEngine.put("scenario", new PolyglotScenarioController(scenarioController));
|
||||
@ -209,9 +202,7 @@ public class Scenario implements Callable<ScenarioResult> {
|
||||
scriptEngine.put("activities", new NashornActivityBindings(scenarioController));
|
||||
}
|
||||
} else if (engine == Engine.Nashorn) {
|
||||
scriptEngine.put("scenario", scenarioController);
|
||||
scriptEngine.put("metrics", new NashornMetricRegistryBindings(metricRegistry));
|
||||
scriptEngine.put("activities", new NashornActivityBindings(scenarioController));
|
||||
throw new RuntimeException("The Nashorn engine has been deprecated in this version of NoSQLBench.");
|
||||
} else {
|
||||
throw new RuntimeException("Unsupported engine: " + engine);
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
// This will be the basis for nashorn and timer-based events.
|
||||
|
||||
var Platform = Java.type("javafx.application.Platform");
|
||||
var Timer = Java.type("java.util.Timer");
|
||||
|
||||
function setTimerRequest(handler, delay, interval, args) {
|
||||
handler = handler || function() {};
|
||||
delay = delay || 0;
|
||||
interval = interval || 0;
|
||||
|
||||
var applyHandler = function() handler.apply(this, args);
|
||||
var runLater = function() Platform.runLater(applyHandler);
|
||||
|
||||
var timer = new Timer("setTimerRequest", true);
|
||||
|
||||
if (interval > 0) {
|
||||
timer.schedule(runLater, delay, interval);
|
||||
} else {
|
||||
timer.schedule(runLater, delay);
|
||||
}
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
function clearTimerRequest(timer) {
|
||||
timer.cancel();
|
||||
}
|
||||
|
||||
function setInterval() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var handler = args.shift();
|
||||
var ms = args.shift();
|
||||
|
||||
return setTimerRequest(handler, ms, ms, args);
|
||||
}
|
||||
|
||||
function clearInterval(timer) {
|
||||
clearTimerRequest(timer);
|
||||
}
|
||||
|
||||
function setTimeout() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var handler = args.shift();
|
||||
var ms = args.shift();
|
||||
|
||||
return setTimerRequest(handler, ms, 0, args);
|
||||
}
|
||||
|
||||
function clearTimeout(timer) {
|
||||
clearTimerRequest(timer);
|
||||
}
|
||||
|
||||
function setImmediate() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var handler = args.shift();
|
||||
|
||||
return setTimerRequest(handler, 0, 0, args);
|
||||
}
|
||||
|
||||
function clearImmediate(timer) {
|
||||
clearTimerRequest(timer);
|
||||
}
|
@ -26,7 +26,8 @@ downloading and executing nb, you get an error, please consult the
|
||||
:::
|
||||
|
||||
This documentation assumes you are using the Linux binary initiating NoSqlBench commands with `./nb`. If you are using
|
||||
the jar, just replace `./nb` with `java -jar nb.jar` when running commands. If you are using the jar version, Java 14 is
|
||||
the jar, just replace `./nb` with `java -jar nb.jar` when running
|
||||
commands. If you are using the jar version, Java 15 is
|
||||
recommended, and will be required soon.
|
||||
|
||||
## Run a cluster
|
||||
|
@ -18,7 +18,6 @@
|
||||
package io.nosqlbench.engine.extensions.optimizers;
|
||||
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import org.apache.commons.math3.analysis.MultivariateFunction;
|
||||
import org.apache.commons.math3.optim.*;
|
||||
import org.apache.commons.math3.optim.nonlinear.scalar.GoalType;
|
||||
@ -96,19 +95,12 @@ public class BobyqaOptimizerInstance {
|
||||
}
|
||||
|
||||
public BobyqaOptimizerInstance setObjectiveFunction(Object f) {
|
||||
if (f instanceof ScriptObjectMirror) {
|
||||
ScriptObjectMirror scriptObject = (ScriptObjectMirror) f;
|
||||
if (!scriptObject.isFunction()) {
|
||||
throw new RuntimeException("Unable to setFunction with a non-function object");
|
||||
}
|
||||
this.objectiveFunctionFromScript =
|
||||
new NashornMultivariateObjectScript(logger, params, scriptObject);
|
||||
}
|
||||
|
||||
if (f instanceof Function) {
|
||||
// Function<Object[],Object> function = (Function<Object[],Object>)f;
|
||||
this.objectiveFunctionFromScript =
|
||||
new PolyglotMultivariateObjectScript(logger, params, f);
|
||||
new PolyglotMultivariateObjectScript(logger, params, f);
|
||||
} else {
|
||||
throw new RuntimeException("The objective function must be recognizable as a polyglot Function");
|
||||
}
|
||||
|
||||
return this;
|
||||
|
@ -1,38 +0,0 @@
|
||||
package io.nosqlbench.engine.extensions.optimizers;
|
||||
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import org.apache.commons.math3.analysis.MultivariateFunction;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MultivariateArrayScript implements MultivariateFunction {
|
||||
private final ScriptObjectMirror script;
|
||||
private final MVParams params;
|
||||
private final Logger logger;
|
||||
|
||||
public MultivariateArrayScript(Logger logger, MVParams params, ScriptObjectMirror script) {
|
||||
this.logger = logger;
|
||||
this.script = script;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double value(double[] doubles) {
|
||||
if (doubles.length != params.size()) {
|
||||
throw new InvalidParameterException("Expected " + params.size() + " doubles, not " + doubles.length);
|
||||
}
|
||||
|
||||
Map<Integer,Double> map = new HashMap<>();
|
||||
|
||||
for (int i = 0; i < doubles.length; i++) {
|
||||
map.put(i,doubles[i]);
|
||||
}
|
||||
|
||||
Object result = null;
|
||||
result = this.script.call(script,doubles);
|
||||
return Double.valueOf(result.toString());
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package io.nosqlbench.engine.extensions.optimizers;
|
||||
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import org.apache.commons.math3.analysis.MultivariateFunction;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class MultivariateDynamicScript implements MultivariateFunction {
|
||||
private final ScriptObjectMirror script;
|
||||
private final int varcount;
|
||||
private final Logger logger;
|
||||
|
||||
public MultivariateDynamicScript(Logger logger, int varcount, ScriptObjectMirror script) {
|
||||
this.logger = logger;
|
||||
this.script = script;
|
||||
this.varcount = varcount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double value(double[] doubles) {
|
||||
logger.info("invoking function with " + Arrays.toString(doubles));
|
||||
if (doubles.length != varcount) {
|
||||
throw new InvalidParameterException("Expected " + varcount + " doubles, not " + doubles.length);
|
||||
}
|
||||
Object result = null;
|
||||
if (doubles.length == 1) {
|
||||
result = this.script.call(script,
|
||||
doubles[0]
|
||||
);
|
||||
} else if (doubles.length == 2) {
|
||||
result = this.script.call(script,
|
||||
doubles[0], doubles[1]
|
||||
);
|
||||
} else if (doubles.length == 3) {
|
||||
result = this.script.call(script,
|
||||
doubles[0], doubles[1], doubles[2]
|
||||
);
|
||||
} else if (doubles.length == 4) {
|
||||
result = this.script.call(script,
|
||||
doubles[0], doubles[1], doubles[2], doubles[3]
|
||||
);
|
||||
} else if (doubles.length == 5) {
|
||||
result = this.script.call(script,
|
||||
doubles[0], doubles[1], doubles[2], doubles[3], doubles[4]);
|
||||
}
|
||||
return Double.valueOf(result.toString());
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package io.nosqlbench.engine.extensions.optimizers;
|
||||
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import org.apache.commons.math3.analysis.MultivariateFunction;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class NashornMultivariateObjectScript implements MultivariateFunction {
|
||||
private final ScriptObjectMirror script;
|
||||
private final MVParams params;
|
||||
private final Logger logger;
|
||||
|
||||
public NashornMultivariateObjectScript(Logger logger, MVParams params, ScriptObjectMirror script) {
|
||||
this.logger = logger;
|
||||
this.script = script;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double value(double[] doubles) {
|
||||
if (doubles.length != params.size()) {
|
||||
throw new InvalidParameterException("Expected " + params.size() + " doubles, not " + doubles.length);
|
||||
}
|
||||
|
||||
Map<String,Double> map = new HashMap<>();
|
||||
|
||||
for (int i = 0; i < doubles.length; i++) {
|
||||
map.put(params.get(i).name, doubles[i]);
|
||||
}
|
||||
|
||||
Object object = ScriptObjectMirror.wrap(map, null);
|
||||
Object result = null;
|
||||
result = this.script.call(script,object);
|
||||
return Double.valueOf(result.toString());
|
||||
}
|
||||
}
|
@ -71,7 +71,6 @@
|
||||
<resources.plugin.version>3.1.0</resources.plugin.version>
|
||||
<source.plugin.version>3.0.1</source.plugin.version>
|
||||
<surefire.plugin.version>3.0.0-M4</surefire.plugin.version>
|
||||
<graalvm.version>20.1.0</graalvm.version>
|
||||
</properties>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
@ -417,29 +416,29 @@
|
||||
<dependency>
|
||||
<groupId>org.graalvm.sdk</groupId>
|
||||
<artifactId>graal-sdk</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
<version>20.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.graalvm.js</groupId>
|
||||
<artifactId>js</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
<version>20.3.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.graalvm.js</groupId>
|
||||
<artifactId>js-scriptengine</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
<version>20.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.graalvm.tools</groupId>
|
||||
<artifactId>profiler</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
<version>20.3.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.graalvm.tools</groupId>
|
||||
<artifactId>chromeinspector</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
<version>20.3.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
@ -507,8 +506,8 @@
|
||||
<configuration>
|
||||
<debug>true</debug>
|
||||
<!-- <release>${java.target.version}</release>-->
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
<source>15</source>
|
||||
<target>15</target>
|
||||
<!-- <compilerArgs>-->
|
||||
<!-- --enable-preview-->
|
||||
<!-- </compilerArgs>-->
|
||||
|
@ -37,19 +37,15 @@ then
|
||||
(cd cache && (
|
||||
if [ "$BUILD_OPENJ9" = "true" ]
|
||||
then
|
||||
wget -c https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk14u-2020-04-27-07-27/OpenJDK14U-jre_x64_linux_openj9_linuxXL_2020-04-27-07-27.tar.gz
|
||||
tar xf OpenJDK14U-jre_x64_linux_openj9_linuxXL_2020-04-27-07-27.tar.gz
|
||||
mv jdk-14.0.1+7-jre jre
|
||||
rm OpenJDK14U-jre_x64_linux_openj9_linuxXL_2020-04-27-07-27.tar.gz
|
||||
wget -c wget -c https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk15u-2020-11-19-07-04/OpenJDK15U-jre_x64_linux_openj9_linuxXL_2020-11-19-07-04.tar.gz
|
||||
tar -xf OpenJDK15U-jre_x64_linux_openj9_linuxXL_2020-11-19-07-04.tar.gz
|
||||
mv jdk-15.0.1+9-jre jre
|
||||
rm OpenJDK15U-jre_x64_linux_openj9_linuxXL_2020-11-19-07-04.tar.gz
|
||||
else
|
||||
wget -c https://github.com/AdoptOpenJDK/openjdk14-binaries/releases/download/jdk14u-2020-04-27-07-27/OpenJDK14U-jre_x64_linux_hotspot_2020-04-27-07-27.tar.gz
|
||||
tar xf OpenJDK14U-jre_x64_linux_hotspot_2020-04-27-07-27.tar.gz
|
||||
mv jdk-14.0.1+7-jre jre
|
||||
wget -c https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk15u-2020-11-19-07-04/OpenJDK15U-jre_x64_linux_hotspot_2020-11-19-07-04.tar.gz
|
||||
tar xf OpenJDK15U-jre_x64_linux_hotspot_2020-11-19-07-04.tar.gz
|
||||
mv jdk-15.0.1+9-jre jre
|
||||
fi
|
||||
# wget -c https://github.com/AdoptOpenJDK/openjdk12-binaries/releases/download/jdk-12.0.2%2B10/OpenJDK12U-jre_x64_linux_hotspot_12.0.2_10.tar.gz
|
||||
# tar xf OpenJDK12U-jre_x64_linux_hotspot_12.0.2_10.tar.gz
|
||||
# mv jdk-12.0.2+10-jre jre
|
||||
# rm OpenJDK12U-jre_x64_linux_hotspot_12.0.2_10.tar.gz
|
||||
))
|
||||
fi
|
||||
|
||||
|
@ -32,7 +32,8 @@ appropriate, to ensure that VirtData selects the right functions within the flow
|
||||
## Format
|
||||
|
||||
Apply the Java String.format method to an incoming object. @see
|
||||
[Java 14 String.format(...) javadoc](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/Formatter.html#syntax) Note:
|
||||
[Java 15 String.format(...) javadoc](https://docs.oracle.com/en/java
|
||||
/javase/14/docs/api/java.base/java/util/Formatter.html#syntax) Note:
|
||||
This function can often be quite slow, so more direct methods are generally preferrable.
|
||||
|
||||
- java.lang.Object -> Format(java.lang.String: format) -> java.lang.String
|
||||
|
Loading…
Reference in New Issue
Block a user