You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2017/03/23 07:52:04 UTC
[1/2] tinkerpop git commit: Fixed a bug in how global bindings were
tracked/applied.
Repository: tinkerpop
Updated Branches:
refs/heads/master 14a2b2811 -> 95c027001
Fixed a bug in how global bindings were tracked/applied.
There were several problems here (which ultimately affected the 3.3.0 branch), but mainly global bindings were being re-applied to the ScriptContext given to eval() and thus making them both engine and global bindings which then led to local variables getting assigned to the global scope. Also, getGlobalBindings() on GremlinExecutor is no longer necessary and is deprecated as the global bindings should be manipulated directly on the GremlinScriptEngine. CTR
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/42dc0c7d
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/42dc0c7d
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/42dc0c7d
Branch: refs/heads/master
Commit: 42dc0c7de0ad26e3602faebf0c10ee8795bee971
Parents: a052b1f
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Mar 23 02:51:08 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Mar 23 02:51:08 2017 -0400
----------------------------------------------------------------------
.../DefaultGremlinScriptEngineManager.java | 7 +-
.../gremlin/groovy/engine/GremlinExecutor.java | 5 +
.../groovy/engine/GremlinExecutorTest.java | 109 ++++++++++++++++++-
3 files changed, 116 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/42dc0c7d/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultGremlinScriptEngineManager.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultGremlinScriptEngineManager.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultGremlinScriptEngineManager.java
index c8b77e6..09862be 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultGremlinScriptEngineManager.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultGremlinScriptEngineManager.java
@@ -478,8 +478,11 @@ public class DefaultGremlinScriptEngineManager implements GremlinScriptEngineMan
// registered by certain GremlinScriptEngine instances (pretty much talking about gremlin-groovy here)
// where type checking is made important. this may not be a good generic way to handled this in the
// long run, but for now we only have two GremlinScriptEngines to be concerned about so thus far it
- // presents no real pains
- final Object initializedBindings = engine.eval(initScript, getBindings());
+ // presents no real pains. global bindings are applied automatically to the context via
+ // AbstractScriptEngine.getScriptContext() - passing them again here to eval() will just make the
+ // global bindings behave as engine bindings and then you get weird things happening (like local vars
+ // becoming global).
+ final Object initializedBindings = engine.eval(initScript);
if (initializedBindings != null && initializedBindings instanceof Map)
((Map<String,Object>) initializedBindings).forEach((k,v) -> put(k,v));
} catch (Exception ex) {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/42dc0c7d/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
index 8fdb86e..8802793 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
@@ -388,6 +388,11 @@ public class GremlinExecutor implements AutoCloseable {
return scheduledExecutorService;
}
+ /**
+ * @deprecated As of release 3.2.5, replaced by {@link #getScriptEngineManager()} to add global scoped bindings
+ * directly to that object.
+ */
+ @Deprecated
public Bindings getGlobalBindings() {
return globalBindings;
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/42dc0c7d/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
index a56f805..8aed8a6 100644
--- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
+++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
@@ -23,6 +23,8 @@ import org.apache.tinkerpop.gremlin.TestHelper;
import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.ThreadInterruptCustomizerProvider;
import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.TimedInterruptCustomizerProvider;
import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.TimedInterruptTimeoutException;
+import org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin;
+import org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin;
import org.javatuples.Pair;
import org.junit.Test;
@@ -70,6 +72,22 @@ public class GremlinExecutorTest {
public static Map<String, String> PATHS = new HashMap<>();
private final BasicThreadFactory testingThreadFactory = new BasicThreadFactory.Builder().namingPattern("test-gremlin-executor-%d").build();
+ /**
+ * Temporary "useless" plugin definition to force GremlinExecutor to use GremlinScriptEngineManager - will be
+ * removed when the old functionality of ScriptEngines is removed.
+ */
+ private final Map<String, Map<String,Object>> triggerPlugin = new HashMap<String, Map<String,Object>>() {{
+ put(ImportGremlinPlugin.class.getName(), new HashMap<String,Object>() {{
+ put("classImports", Collections.singletonList("java.lang.Math"));
+ }});
+ }};
+
+ private final Map<String, Map<String,Object>> scriptFilePlugin = new HashMap<String, Map<String,Object>>() {{
+ put(ScriptFileGremlinPlugin.class.getName(), new HashMap<String,Object>() {{
+ put("files", Collections.singletonList(PATHS.get("GremlinExecutorInit.groovy")));
+ }});
+ }};
+
static {
try {
final List<String> groovyScriptResources = Collections.singletonList("GremlinExecutorInit.groovy");
@@ -213,7 +231,7 @@ public class GremlinExecutorTest {
}
@Test
- public void shouldGetGlobalBindings() throws Exception {
+ public void shouldGetGlobalBindingsDeprecated() throws Exception {
final Bindings b = new SimpleBindings();
final Object bound = new Object();
b.put("x", bound);
@@ -223,6 +241,18 @@ public class GremlinExecutorTest {
}
@Test
+ public void shouldGetGlobalBindings() throws Exception {
+ final Bindings b = new SimpleBindings();
+ final Object bound = new Object();
+ b.put("x", bound);
+ final GremlinExecutor gremlinExecutor = GremlinExecutor.build().
+ addPlugins("gremlin-groovy", triggerPlugin).
+ globalBindings(b).create();
+ assertEquals(bound, gremlinExecutor.getScriptEngineManager().getBindings().get("x"));
+ gremlinExecutor.close();
+ }
+
+ @Test
public void shouldEvalScriptWithGlobalAndLocalBindings() throws Exception {
final Bindings g = new SimpleBindings();
g.put("x", 1);
@@ -509,7 +539,7 @@ public class GremlinExecutorTest {
}
@Test
- public void shouldInitializeWithScriptAndMakeGlobalBinding() throws Exception {
+ public void shouldInitializeWithScriptAndMakeGlobalBindingDeprecated() throws Exception {
final GremlinExecutor gremlinExecutor = GremlinExecutor.build()
.addEngineSettings("gremlin-groovy",
Collections.emptyList(),
@@ -528,6 +558,21 @@ public class GremlinExecutorTest {
}
@Test
+ public void shouldInitializeWithScriptAndMakeGlobalBinding() throws Exception {
+ final GremlinExecutor gremlinExecutor = GremlinExecutor.build()
+ .addPlugins("gremlin-groovy", scriptFilePlugin)
+ .create();
+
+ assertEquals(2, gremlinExecutor.eval("add(1,1)").get());
+ assertThat(gremlinExecutor.getScriptEngineManager().getBindings().keySet(), contains("name"));
+ assertThat(gremlinExecutor.getScriptEngineManager().getBindings().keySet(), not(hasItem("someSet")));
+
+ assertEquals("stephen", gremlinExecutor.getScriptEngineManager().getBindings().get("name"));
+
+ gremlinExecutor.close();
+ }
+
+ @Test
public void shouldContinueToEvalScriptsEvenWithTimedInterrupt() throws Exception {
final Map<String,List<Object>> compilerCustomizerConfig = new HashMap<>();
final List<Object> args = new ArrayList<>();
@@ -694,7 +739,7 @@ public class GremlinExecutorTest {
}
@Test
- public void shouldAllowConcurrentModificationOfGlobals() throws Exception {
+ public void shouldAllowConcurrentModificationOfGlobalsDeprecated() throws Exception {
// this test simulates a scenario that likely shouldn't happen - where globals are modified by multiple
// threads. globals are created in a synchronized fashion typically but it's possible that someone
// could do something like this and this test validate that concurrency exceptions don't occur as a
@@ -748,4 +793,62 @@ public class GremlinExecutorTest {
assertThat(t.getValue1().get(3).intValue(), greaterThan(-1));
});
}
+
+ @Test
+ public void shouldAllowConcurrentModificationOfGlobals() throws Exception {
+ // this test simulates a scenario that likely shouldn't happen - where globals are modified by multiple
+ // threads. globals are created in a synchronized fashion typically but it's possible that someone
+ // could do something like this and this test validate that concurrency exceptions don't occur as a
+ // result
+ final ExecutorService service = Executors.newFixedThreadPool(8, testingThreadFactory);
+ final Bindings globals = new SimpleBindings();
+ globals.put("g", -1);
+ final GremlinExecutor gremlinExecutor = GremlinExecutor.build()
+ .addPlugins("gremlin-groovy", triggerPlugin)
+ .globalBindings(globals).create();
+
+ final AtomicBoolean failed = new AtomicBoolean(false);
+ final int max = 512;
+ final List<Pair<Integer, List<Integer>>> futures = Collections.synchronizedList(new ArrayList<>(max));
+ IntStream.range(0, max).forEach(i -> {
+ final int yValue = i * 2;
+ final Bindings b = new SimpleBindings();
+ b.put("x", i);
+ b.put("y", yValue);
+ final int zValue = i * -1;
+
+ final String script = "z=" + zValue + ";[x,y,z,g]";
+ try {
+ service.submit(() -> {
+ try {
+ // modify the global in a separate thread
+ gremlinExecutor.getScriptEngineManager().put("g", i);
+ gremlinExecutor.getScriptEngineManager().put(Integer.toString(i), i);
+ gremlinExecutor.getScriptEngineManager().getBindings().keySet().stream().filter(s -> i % 2 == 0 && !s.equals("g")).findFirst().ifPresent(globals::remove);
+ final List<Integer> result = (List<Integer>) gremlinExecutor.eval(script, b).get();
+ futures.add(Pair.with(i, result));
+ } catch (Exception ex) {
+ failed.set(true);
+ }
+ });
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ });
+
+ service.shutdown();
+ assertThat(service.awaitTermination(60000, TimeUnit.MILLISECONDS), is(true));
+
+ // likely a concurrency exception if it occurs - and if it does then we've messed up because that's what this
+ // test is partially designed to protected against.
+ assertThat(failed.get(), is(false));
+
+ assertEquals(max, futures.size());
+ futures.forEach(t -> {
+ assertEquals(t.getValue0(), t.getValue1().get(0));
+ assertEquals(t.getValue0() * 2, t.getValue1().get(1).intValue());
+ assertEquals(t.getValue0() * -1, t.getValue1().get(2).intValue());
+ assertThat(t.getValue1().get(3).intValue(), greaterThan(-1));
+ });
+ }
}
[2/2] tinkerpop git commit: Merge branch 'tp32'
Posted by sp...@apache.org.
Merge branch 'tp32'
Conflicts:
gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/95c02700
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/95c02700
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/95c02700
Branch: refs/heads/master
Commit: 95c02700191a702e03d8d09025d05793a52d04ab
Parents: 14a2b28 42dc0c7
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Mar 23 03:51:16 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Mar 23 03:51:16 2017 -0400
----------------------------------------------------------------------
docs/src/upgrade/release-3.3.x.asciidoc | 1 +
.../DefaultGremlinScriptEngineManager.java | 7 ++-
.../gremlin/groovy/engine/GremlinExecutor.java | 4 --
.../groovy/engine/GremlinExecutorTest.java | 48 +++++++++++++-------
.../server/util/ServerGremlinExecutor.java | 6 +--
5 files changed, 41 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/95c02700/docs/src/upgrade/release-3.3.x.asciidoc
----------------------------------------------------------------------
diff --cc docs/src/upgrade/release-3.3.x.asciidoc
index 4604320,0000000..ab2339d
mode 100644,000000..100644
--- a/docs/src/upgrade/release-3.3.x.asciidoc
+++ b/docs/src/upgrade/release-3.3.x.asciidoc
@@@ -1,309 -1,0 +1,310 @@@
+////
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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.
+////
+
+TinkerPop 3.3.0
+===============
+
+image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/images/gremlin-mozart.png[width=225]
+
+*Gremlin Symphony #40 in G Minor*
+
+TinkerPop 3.3.0
+---------------
+
+*Release Date: NOT OFFICIALLY RELEASED YET*
+
+Please see the link:https://github.com/apache/tinkerpop/blob/3.3.3/CHANGELOG.asciidoc#release-3-3-0[changelog] for a complete list of all the modifications that are part of this release.
+
+Upgrading for Users
+~~~~~~~~~~~~~~~~~~~
+
+GraphSON 2.0
+^^^^^^^^^^^^
+
+Both TinkerGraph and Gremlin Server have been defaulted to work with GraphSON 2.0. For TinkerGraph this means that
+the following commands:
+
+[source,java]
+----
+Graph graph = TinkerFactory.createModern();
+graph.io(IoCore.graphson()).writeGraph("tinkerpop-modern.json");
+
+final Graph newGraph = TinkerGraph.open();
+newGraph.io(IoCore.graphson()).readGraph("tinkerpop-modern.json");
+----
+
+will write and read GraphSON 2.0 format rather than 1.0. To use 1.0 format simply set the `version()` on the
+appropriate builder methods:
+
+[source,java]
+----
+Graph graph = TinkerFactory.createModern();
+GraphSONMapper mapper = graph.io(IoCore.graphson()).mapper().version(GraphSONVersion.V1_0).create()
+try (OutputStream os = new FileOutputStream("tinkerpop-modern.json")) {
+ graph.io(IoCore.graphson()).writer().mapper(mapper).create().writeGraph(os, graph)
+}
+
+final Graph newGraph = TinkerGraph.open();
+try (InputStream stream = new FileInputStream("tinkerpop-modern.json")) {
+ newGraph.io(IoCore.graphson()).reader().mapper(mapper).vertexIdKey("name").create().readGraph(stream, newGraph);
+}
+----
+
+For Gremlin Server, this change means that the `application/json` mime type no longer returns GraphSON 1.0 without
+type embedding. Instead, Gremlin Server will return GraphSON 2.0 with partial types enabled (i.e. which is equivalent
+to `application/vnd.gremlin-v2.0+json`). The `serializers` section the sample Gremlin Server YAML files now typically
+look like this:
+
+[source,yaml]
+----
+serializers:
+ - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { useMapperFromGraph: graph }} # application/vnd.gremlin-v1.0+gryo
+ - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoLiteMessageSerializerV1d0, config: { useMapperFromGraph: graph }} # application/vnd.gremlin-v1.0+gryo-lite
+ - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { serializeResultToString: true }} # application/vnd.gremlin-v1.0+gryo-stringd
+ - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV1d0, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistry] }} # application/vnd.gremlin-v1.0+json
+ - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV2d0, config: { useMapperFromGraph: graph }} # application/vnd.gremlin-v2.0+json
+ - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV2d0, config: { useMapperFromGraph: graph }} # application/json
+----
+
+It is possible to bring back the original configuration for `application/json` by changing the last entry as follows:
+
+[source,yaml]
+----
+serializers:
+ - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { useMapperFromGraph: graph }} # application/vnd.gremlin-v1.0+gryo
+ - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoLiteMessageSerializerV1d0, config: { useMapperFromGraph: graph }} # application/vnd.gremlin-v1.0+gryo-lite
+ - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { serializeResultToString: true }} # application/vnd.gremlin-v1.0+gryo-stringd
+ - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV1d0, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistry] }} # application/vnd.gremlin-v1.0+json
+ - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV2d0, config: { useMapperFromGraph: graph }} # application/vnd.gremlin-v2.0+json
+ - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0, config: { useMapperFromGraph: graph }} # application/json
+----
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1414[TINKERPOP-1414]
+
+GraphTraversal Has-Methods Re-Organized
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+`GraphTraversal.hasXXX()`, where `XXX` is `Id`, `Label`, `Key`, `Value`, was faulty in that they relied on calling an
+intermediate method for flattening `Object[]` arguments and thus, yielding a non 1-to-1 correspondence between `GraphTraversal`
+and `Bytecode`. This has been remedied. Most users will not notice this change. Perhaps only some users that may use
+Java reflection over `GraphTraversal` might have a simple problem.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1520[TINKERPOP-1520]
+
+Changes to IO
+^^^^^^^^^^^^^
+
+*WILL NEED TO WRITE SOMETHING MORE COHESIVE HERE - JUST LISTING STUFF FOR RIGHT NOW*
+
+* Gryo incompatibilities with 3.2.x:
+** `RequestMessage`
+** `ResponseMessage`
+
+SelectStep Defaults to Pop.last
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+`SelectStep` and `SelectOneStep` (`select()`) are the only `Scoping` steps that default to `Pop.mixed` as their labeled path
+selection criteria. All other steps, like `match()`, `where()` and `dedup()`, use `Pop.last`. In order to better enable optimizations
+around total `Pop.last` traversals, the `select()`-steps now default to `Pop.last`. Most users will not notice a difference as
+it is rare for repeated labels to be used in practice. However, formal backwards compatibility is possible as outlined below.
+
+Assuming that `x` is not a `Pop` argument:
+
+1. Change all `select(x,y,z)` calls to `selectV3d2(x,y,z)` calls.
+2. Change all `select(x,y,z)`-step calls to `select(Pop.mixed,x,y,z)`.
+
+If an explicit `Pop` argument is provided, then no changes are required.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1541[TINKERPOP-1541]
+
+OptionalStep and Side-Effects
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The `optional()`-step was previously implemented using `ChooseStep`. However, if the optional branch contained side-effects,
+then unexpected behaviors can emerge. Thus, a potential backwards compatibility issue arises if side-effects were being
+used in `optional()`. However, the behavior would be unpredictable so this backwards incompatibility is desirable.
+
+See link:https://issues.apache.org/jira/browse/TINKERPOP-1506[TINKERPOP-1506]
+
+Gremlin Console Script Execution
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+It is no longer possible to run a script in execution mode in the Gremlin Console from the terminal without use of `-e`.
+In other words, prior versions allowed:
+
+[source,text]
+bin/gremlin.sh gremlin.groovy
+
+Such a command must now be written as:
+
+[source,text]
+bin/gremlin.sh -e gremlin.groovy
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1283[TINKERPOP-1283]
+
+GraphTraversal valueMap() Signature Updated
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+`GraphTraversal.valueMap(includeTokens,propertyKeys...)` now returns a `Map<Object,E>` to account for the presence of `T.id` or `T.label` if you pass `true` to it.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1283[TINKERPOP-1483]
+
+HADOOP_GREMLIN_LIBS and Spark
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The TinkerPop reference documentation has always mentioned that the `gremlin-spark` `/lib` directory needed to be
+added to `HADOOP_GREMLIN_LIBS` environment variable. In reality, that was not truly necessary. With Spark 1.x having
+`gremlin-spark` in `HADOOP_GREMLIN_LIBS` hasn't been a problem, but Spark 2.0 introduces a check for duplicate jars
+on the path which will cause job initialization to fail. As a result, going forward with TinkerPop 3.3.0, the
+`gremlin-spark` `lib` directory should not be included in `HADOOP_GREMLIN_LIBS`.
+
+Deprecation Removal
+^^^^^^^^^^^^^^^^^^^
+
+The following deprecated classes, methods or fields have been removed in this version:
+
+* `giraph-gremlin`
+** org.apache.tinkerpop.gremlin.giraph.groovy.plugin.GiraphGremlinPlugin
+* `gremlin-console`
+** `org.apache.tinkerpop.gremlin.console.Console(String)`
+** `org.apache.tinkerpop.gremlin.console.ConsoleImportCustomizerProvider`
+** `org.apache.tinkerpop.gremlin.console.plugin.*`
+** `org.apache.tinkerpop.gremlin.console.groovy.plugin.DriverGremlinPlugin`
+** `org.apache.tinkerpop.gremlin.console.groovy.plugin.DriverRemoteAcceptor`
+** `org.apache.tinkerpop.gremlin.console.groovy.plugin.GephiGremlinPlugin`
+** `org.apache.tinkerpop.gremlin.console.groovy.plugin.UtilitiesGremlinPlugin`
+* `gremlin-core`
+** `org.apache.tinkerpop.gremlin.jsr223.CoreGremlinModule`
+** `org.apache.tinkerpop.gremlin.jsr223.GremlinModule`
+** `org.apache.tinkerpop.gremlin.jsr223.GremlinScriptEngineManager#addModule(GremlinModule)`
+** `org.apache.tinkerpop.gremlin.jsr223.console.PluginAcceptor`
+** `org.apache.tinkerpop.gremlin.structure.Graph.OptIn#SUITE_GROOVY_PROCESS_STANDARD`
+** `org.apache.tinkerpop.gremlin.structure.Graph.OptIn#SUITE_GROOVY_PROCESS_COMPUTER`
+** `org.apache.tinkerpop.gremlin.structure.Graph.OptIn#SUITE_GROOVY_ENVIRONMENT`
+** `org.apache.tinkerpop.gremlin.structure.Graph.OptIn#SUITE_GROOVY_ENVIRONMENT_INTEGRATE`
+* `gremlin-groovy`
+** `org.apache.tinkerpop.gremlin.groovy.AbstractImportCustomizerProvider`
+** `org.apache.tinkerpop.gremlin.groovy.CompilerCustomizerProvider`
+** `org.apache.tinkerpop.gremlin.groovy.DefaultImportCustomizerProvider`
+** `org.apache.tinkerpop.gremlin.groovy.EmptyImportCustomizerProvider`
+** `org.apache.tinkerpop.gremlin.groovy.ImportCustomizerProvider`
+** `org.apache.tinkerpop.gremlin.groovy.NoImportCustomizerProvider`
+** `org.apache.tinkerpop.gremlin.groovy.engine.ConcurrentBindings`
+** `org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor#build(String,List,List,List,Map)`
+** `org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor#getScriptEngines()`
++** `org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor#getGlobalBindings()`
+** `org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor.Builder#enabledPlugins(Set)
+** `org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor.Builder#addEngineSettings(String,List,List,List,Map)`
+** `org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor.Builder#engineSettings(Map)`
+** `org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor.Builder#use(List)`
+** `org.apache.tinkerpop.gremlin.groovy.engine.ScriptEngines`
+** `org.apache.tinkerpop.gremlin.groovy.function.*`
+** `org.apache.tinkerpop.gremlin.groovy.plugin.*`
+** `org.apache.tinkerpop.gremlin.groovy.plugin.credential.*`
+** `org.apache.tinkerpop.gremlin.groovy.jsr223.DependencyManager`
+** `org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine(ImportCustomizerProvider)`
+** `org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine(CompilerCustomizerProvider)`
+** `org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine#plugins()`
+** `org.apache.tinkerpop.gremlin.groovy.jsr223.ScriptExecutor`
+** `org.apache.tinkerpop.gremlin.groovy.jsr223.ScriptEnginePluginAcceptor`
+** `org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.SandboxExtension`
+** `org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.*`
+** `org.apache.tinkerpop.gremlin.groovy.util.DependencyGrabber#deleteDependenciesFromPath(org.apache.tinkerpop.gremlin.groovy.plugin.Artifact)`
+** `org.apache.tinkerpop.gremlin.groovy.util.DependencyGrabber#copyDependenciesToPath(org.apache.tinkerpop.gremlin.groovy.plugin.Artifact)`
+* `gremlin-server`
+** `org.apache.tinkerpop.gremlin.server.Settings#plugins`
+** `org.apache.tinkerpop.gremlin.server.op.control.*`
+* `spark-gremlin`
+** `org.apache.tinkerpop.gremlin.spark.groovy.plugin.SparkGremlinPlugin`
+* `tinkergraph-gremlin`
+** `org.apache.tinkerpop.gremlin.tinkergraph.groovy.plugin.TinkerGraphGremlinPlugin`
+
+Please see the javadoc deprecation notes or upgrade documentation specific to when the deprecation took place to
+understand how to resolve this breaking change.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1283[TINKERPOP-1283], link:https://issues.apache.org/jira/browse/TINKERPOP-1420[TINKERPOP-1420],
+link:https://issues.apache.org/jira/browse/TINKERPOP-1421[TINKERPOP-1421], link:https://issues.apache.org/jira/browse/TINKERPOP-833[TINKERPOP-833],
+link:https://issues.apache.org/jira/browse/TINKERPOP-1040[TINKERPOP-1040], link:https://issues.apache.org/jira/browse/TINKERPOP-1612[TINKERPOP-1612],
+link:https://issues.apache.org/jira/browse/TINKERPOP-1622[TINKERPOP-1622]
+
+Upgrading for Providers
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Graph Database Providers
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Test Suite Removal
+++++++++++++++++++
+
+A number of test suites that were previously deprecated have been removed which should reduce the burden on graph
+providers who are implementing TinkerPop. Test suites related to perfrmance based on `junit-benchmarks` have been
+removed as have the suites in `gremlin-groovy-test` (in fact, this entire module has been removed). Specifically,
+providers should be concerned with breaking changes related to the removal of:
+
+* `StructurePerformanceSuite`
+* `ProcessPerformanceSuite`
+* `GroovyEnvironmentPerformanceSuite`
+* `GroovyProcessStandardSuite`
+* `GroovyProcessComputerSuite`
+* `GroovyEnvironmentSuite`
+* `GroovyEnvironmentIntegrateSuite`
+
+Those graph providers who relied on these tests should simply remove them from their respective test suites. Beware of
+`OptOut` annotations that reference tests in these suites as test failure will occur if those references are not
+removed.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1235[TINKERPOP-1235], link:https://issues.apache.org/jira/browse/TINKERPOP-1612[TINKERPOP-1612]
+
+Gremlin-server.sh and Init Scripts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+`gremlin-server.sh` is now also an init script and can no longer be started without parameters. To start it in the
+foreground with defaults like previous usage, please use the `console` parameter. Also, `gremlin-server.sh` will
+continue to start in the foreground when provided a yaml configuration file.
+
+How to install as a service has been added to the link:http://tinkerpop.apache.org/docs/3.3.0/reference/#_as_a_service[Reference Documentation - As A Service].
+
+The switch name has changed for installing dependencies. `-i` has been deprecated and replaced by `install`.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-980[TINKERPOP-980], link:http://tinkerpop.apache.org/docs/3.3.0/reference/#_configuring_2[Reference Documentation - Server Configuration].
+
+Gremlin-server.bat
+^^^^^^^^^^^^^^^^^^
+
+The switch name has changed for installing dependencies. `-i` has been deprecated and replaced by `install`.
+
+SparkGraphComputer GryoRegistrator
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Historically, `SparkGraphComputer` has used `GryoSerializer` to handle the serialization of objects in Spark. The reason
+this exists is because TinkerPop uses a shaded version of Kryo and thus, couldn't use the standard `KryoSerializer`-model
+provided by Spark. However, a "shim model" was created which allows for the shaded and unshaded versions of Kryo to
+interact with one another. To this end, `KryoSerializer` can now be used with a `GryoRegistrator`. The properties file
+for a `SparkGraphComputer` now looks as follows:
+
+```
+spark.serializer=org.apache.spark.serializer.KryoSerializer
+spark.kryo.registrator=org.apache.tinkerpop.gremlin.spark.structure.io.gryo.GryoRegistrator
+```
+
+If the old `GryoSerializer` model is desired, then the properties file should simply look as before:
+
+```
+spark.serializer=org.apache.tinkerpop.gremlin.spark.structure.io.gryo.GryoSerializer
+```
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1389
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/95c02700/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/DefaultGremlinScriptEngineManager.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/95c02700/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
----------------------------------------------------------------------
diff --cc gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
index 2d04fb2,8802793..114085d
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
@@@ -351,11 -388,16 +351,7 @@@ public class GremlinExecutor implement
return scheduledExecutorService;
}
- public Bindings getGlobalBindings() {
- return globalBindings;
- }
-
/**
- * @deprecated As of release 3.2.5, replaced by {@link #getScriptEngineManager()} to add global scoped bindings
- * directly to that object.
- */
- @Deprecated
- public Bindings getGlobalBindings() {
- return globalBindings;
- }
-
- /**
* {@inheritDoc}
* <p/>
* Executors are only closed if they were not supplied externally in the
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/95c02700/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
----------------------------------------------------------------------
diff --cc gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
index 9aef783,8aed8a6..86150d4
--- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
+++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java
@@@ -20,9 -20,11 +20,10 @@@ package org.apache.tinkerpop.gremlin.gr
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.tinkerpop.gremlin.TestHelper;
-import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.ThreadInterruptCustomizerProvider;
-import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.TimedInterruptCustomizerProvider;
-import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.TimedInterruptTimeoutException;
+ import org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin;
+ import org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin;
+import org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyCompilerGremlinPlugin;
+import org.apache.tinkerpop.gremlin.groovy.jsr223.TimedInterruptTimeoutException;
- import org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin;
import org.javatuples.Pair;
import org.junit.Test;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/95c02700/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
index a212fdc,56e78fb..cac7b36
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java
@@@ -154,12 -167,12 +154,12 @@@ public class ServerGremlinExecutor<T ex
// script engine init may have altered the graph bindings or maybe even created new ones - need to
// re-apply those references back
-- gremlinExecutor.getGlobalBindings().entrySet().stream()
++ gremlinExecutor.getScriptEngineManager().getBindings().entrySet().stream()
.filter(kv -> kv.getValue() instanceof Graph)
.forEach(kv -> this.graphManager.getGraphs().put(kv.getKey(), (Graph) kv.getValue()));
// script engine init may have constructed the TraversalSource bindings - store them in Graphs object
-- gremlinExecutor.getGlobalBindings().entrySet().stream()
++ gremlinExecutor.getScriptEngineManager().getBindings().entrySet().stream()
.filter(kv -> kv.getValue() instanceof TraversalSource)
.forEach(kv -> {
logger.info("A {} is now bound to [{}] with {}", kv.getValue().getClass().getSimpleName(), kv.getKey(), kv.getValue());
@@@ -168,7 -181,7 +168,7 @@@
// determine if the initialization scripts introduced LifeCycleHook objects - if so we need to gather them
// up for execution
-- hooks = gremlinExecutor.getGlobalBindings().entrySet().stream()
++ hooks = gremlinExecutor.getScriptEngineManager().getBindings().entrySet().stream()
.filter(kv -> kv.getValue() instanceof LifeCycleHook)
.map(kv -> (LifeCycleHook) kv.getValue())
.collect(Collectors.toList());