diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/pom.xml b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/pom.xml
index 837b579908..10f4ebd58a 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/pom.xml
@@ -72,11 +72,6 @@
ivy
2.5.2
-
- org.python
- jython-standalone
- 2.7.3
-
org.clojure
clojure
@@ -94,12 +89,6 @@
commons-net
commons-net
-
-
- xerces
- xercesImpl
- 2.12.2
-
org.apache.nifi
nifi-mock
@@ -143,7 +132,6 @@
src/test/resources/xmlRecord.xml
- src/test/resources/jython/test_compress.py
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/lookup/script/BaseScriptedLookupService.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/lookup/script/BaseScriptedLookupService.java
index e040389d29..aee8b79a95 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/lookup/script/BaseScriptedLookupService.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/lookup/script/BaseScriptedLookupService.java
@@ -90,14 +90,14 @@ public class BaseScriptedLookupService extends AbstractScriptedControllerService
_temp.addAll(scriptingComponentHelper.getDescriptors());
_temp.remove(scriptingComponentHelper.SCRIPT_ENGINE);
- PropertyDescriptor.Builder jythonLessEngineProp = new PropertyDescriptor
+ PropertyDescriptor.Builder engineProp = new PropertyDescriptor
.Builder().fromPropertyDescriptor(scriptingComponentHelper.SCRIPT_ENGINE);
List filtered = scriptingComponentHelper.getScriptEngineAllowableValues()
- .stream().filter(allowableValue -> !allowableValue.getValue().contains("ython"))
+ .stream()
.collect(Collectors.toList());
- jythonLessEngineProp.allowableValues(filtered.toArray(new AllowableValue[filtered.size()]));
+ engineProp.allowableValues(filtered.toArray(new AllowableValue[filtered.size()]));
- supportedPropertyDescriptors.add(jythonLessEngineProp.build());
+ supportedPropertyDescriptors.add(engineProp.build());
supportedPropertyDescriptors.addAll(_temp);
final ConfigurableComponent instance = lookupService.get();
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/lookup/script/ScriptedLookupService.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/lookup/script/ScriptedLookupService.java
index 34a812e313..9d82964d84 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/lookup/script/ScriptedLookupService.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/lookup/script/ScriptedLookupService.java
@@ -33,10 +33,9 @@ import java.util.Set;
/**
* A Controller service that allows the user to script the lookup operation to be performed (by LookupRecord, e.g.)
*/
-@Tags({"lookup", "record", "script", "invoke", "groovy", "python", "jython"})
+@Tags({"lookup", "record", "script", "invoke", "groovy"})
@CapabilityDescription("Allows the user to provide a scripted LookupService instance in order to enrich records from " +
- "an incoming flow file. Please note, that due to a bug in Jython that remains unresolved, it is not possible to use " +
- "Jython to write a script for this service in Python.")
+ "an incoming flow file.")
@DynamicProperty(name = "Script Engine Binding property", value = "Binding property value passed to Script Runner",
expressionLanguageScope = ExpressionLanguageScope.ENVIRONMENT,
description = "Updates a script engine property specified by the Dynamic Property's key with the value specified by the Dynamic Property's value")
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/lookup/script/SimpleScriptedLookupService.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/lookup/script/SimpleScriptedLookupService.java
index 745fea4a75..9a14b19c9b 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/lookup/script/SimpleScriptedLookupService.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/lookup/script/SimpleScriptedLookupService.java
@@ -33,12 +33,11 @@ import java.util.Set;
/**
* A Controller service that allows the user to script the lookup operation to be performed (by LookupAttribute, e.g.)
*/
-@Tags({"lookup", "script", "invoke", "groovy", "python", "jython"})
+@Tags({"lookup", "script", "invoke", "groovy"})
@CapabilityDescription("Allows the user to provide a scripted LookupService instance in order to enrich records from "
+ "an incoming flow file. The script is expected to return an optional string value rather than an arbitrary object (record, e.g.). "
+ "Also the scripted lookup service should implement StringLookupService, otherwise the getValueType() method must be implemented even "
- + "though it will be ignored, as SimpleScriptedLookupService returns String as the value type on the script's behalf. Please note that due to "
- + "a bug in Jython that remains unresolved, it is not possible to use Jython to write a script for this service in Python.")
+ + "though it will be ignored, as SimpleScriptedLookupService returns String as the value type on the script's behalf.")
@DynamicProperty(name = "Script Engine Binding property", value = "Binding property value passed to Script Runner",
expressionLanguageScope = ExpressionLanguageScope.ENVIRONMENT,
description = "Updates a script engine property specified by the Dynamic Property's key with the value specified by the Dynamic Property's value")
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ExecuteScript.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ExecuteScript.java
index a9ed75eb3e..985957c280 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ExecuteScript.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ExecuteScript.java
@@ -64,7 +64,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-@Tags({"script", "execute", "groovy", "python", "jython", "clojure"})
+@Tags({"script", "execute", "groovy", "clojure"})
@CapabilityDescription("Experimental - Executes a script given the flow file and a process session. The script is responsible for "
+ "handling the incoming flow file (transfer to SUCCESS or remove, e.g.) as well as any flow files created by "
+ "the script. If the handling is incomplete or incorrect, the session will be rolled back. Experimental: "
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/InvokeScriptedProcessor.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/InvokeScriptedProcessor.java
index 1bb973549a..8e8d21b109 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/InvokeScriptedProcessor.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/InvokeScriptedProcessor.java
@@ -68,7 +68,7 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
-@Tags({"script", "invoke", "groovy", "python", "jython"})
+@Tags({"script", "invoke", "groovy"})
@CapabilityDescription("Experimental - Invokes a script engine for a Processor defined in the given script. The script must define "
+ "a valid class that implements the Processor interface, and it must set a variable 'processor' to an instance of "
+ "the class. Processor methods such as onTrigger() will be delegated to the scripted Processor instance. Also any "
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/PythonScriptEvaluator.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/PythonScriptEvaluator.java
deleted file mode 100644
index fb0e9be132..0000000000
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/PythonScriptEvaluator.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.
- */
-package org.apache.nifi.processors.script;
-
-import org.apache.nifi.flowfile.FlowFile;
-import org.apache.nifi.logging.ComponentLog;
-import org.apache.nifi.serialization.record.Record;
-
-import javax.script.Bindings;
-import javax.script.CompiledScript;
-import javax.script.ScriptEngine;
-import javax.script.ScriptException;
-
-class PythonScriptEvaluator implements ScriptEvaluator {
- private final ScriptEngine scriptEngine;
- private final CompiledScript compiledScript;
- private final Bindings bindings;
-
- PythonScriptEvaluator(
- final ScriptEngine scriptEngine,
- final CompiledScript compiledScript,
- final FlowFile flowFile,
- final ComponentLog componentLog
- ) {
- // By pre-compiling the script here, we get significant performance gains. A quick 5-minute benchmark
- // shows gains of about 100x better performance. But even with the compiled script, performance pales
- // in comparison with Groovy.
- this.compiledScript = compiledScript;
- this.scriptEngine = scriptEngine;
- this.bindings = ScriptedTransformRecord.setupBindings(scriptEngine);
-
- bindings.put("attributes", flowFile.getAttributes());
- bindings.put("log", componentLog);
- }
-
- @Override
- public Object evaluate(final Record record, final long index) throws ScriptException {
- bindings.put("record", record);
- bindings.put("recordIndex", index);
-
- compiledScript.eval(bindings);
- return scriptEngine.get("_");
- }
-}
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedFilterRecord.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedFilterRecord.java
index 1f5be5dc11..aa555eb3e0 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedFilterRecord.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedFilterRecord.java
@@ -25,7 +25,7 @@ import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
-@Tags({"record", "filter", "script", "groovy", "jython", "python"})
+@Tags({"record", "filter", "script", "groovy"})
@CapabilityDescription(
"This processor provides the ability to filter records out from FlowFiles using the user-provided script. " +
"Every record will be evaluated by the script which must return with a boolean value. " +
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedPartitionRecord.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedPartitionRecord.java
index f2a6ea65bd..ba64a1261e 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedPartitionRecord.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedPartitionRecord.java
@@ -57,7 +57,7 @@ import java.util.Map;
import java.util.Set;
@SideEffectFree
-@Tags({"record", "partition", "script", "groovy", "jython", "python", "segment", "split", "group", "organize"})
+@Tags({"record", "partition", "script", "groovy", "segment", "split", "group", "organize"})
@CapabilityDescription("Receives Record-oriented data (i.e., data that can be read by the configured Record Reader) and evaluates the user provided script against "
+ "each record in the incoming flow file. Each record is then grouped with other records sharing the same partition and a FlowFile is created for each groups of records. " +
"Two records shares the same partition if the evaluation of the script results the same return value for both. Those will be considered as part of the same partition.")
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedRecordProcessor.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedRecordProcessor.java
index f262f6672a..bd48ca12e8 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedRecordProcessor.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedRecordProcessor.java
@@ -50,7 +50,6 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
abstract class ScriptedRecordProcessor extends AbstractProcessor implements Searchable {
- protected static final String PYTHON_SCRIPT_LANGUAGE = "python";
protected static final Set SCRIPT_OPTIONS = ScriptingComponentUtils.getAvailableEngines();
protected volatile String scriptToRun = null;
@@ -115,11 +114,6 @@ abstract class ScriptedRecordProcessor extends AbstractProcessor implements Sear
}
protected ScriptEvaluator createEvaluator(final ScriptEngine scriptEngine, final FlowFile flowFile) throws ScriptException {
- if (PYTHON_SCRIPT_LANGUAGE.equalsIgnoreCase(scriptEngine.getFactory().getLanguageName())) {
- final CompiledScript compiledScript = getOrCompileScript((Compilable) scriptEngine, scriptToRun);
- return new PythonScriptEvaluator(scriptEngine, compiledScript, flowFile, getLogger());
- }
-
return new InterpretedScriptEvaluator(scriptEngine, scriptToRun, flowFile, getLogger());
}
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedTransformRecord.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedTransformRecord.java
index 2fb32d8189..f5c99b3804 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedTransformRecord.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedTransformRecord.java
@@ -59,7 +59,7 @@ import java.util.concurrent.atomic.AtomicReference;
@SupportsBatching
@SideEffectFree
@InputRequirement(InputRequirement.Requirement.INPUT_REQUIRED)
-@Tags({"record", "transform", "script", "groovy", "jython", "python", "update", "modify", "filter"})
+@Tags({"record", "transform", "script", "groovy", "update", "modify", "filter"})
@Restricted(restrictions = {
@Restriction(requiredPermission = RequiredPermission.EXECUTE_CODE,
explanation = "Provides operator the ability to execute arbitrary code assuming all permissions that NiFi has.")
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedValidateRecord.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedValidateRecord.java
index 3af2d9a5bb..6f19b5cba6 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedValidateRecord.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/processors/script/ScriptedValidateRecord.java
@@ -25,7 +25,7 @@ import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
-@Tags({"record", "validate", "script", "groovy", "jython", "python"})
+@Tags({"record", "validate", "script", "groovy"})
@CapabilityDescription(
"This processor provides the ability to validate records in FlowFiles using the user-provided script. " +
"The script is expected to have a record as incoming argument and return with a boolean value. " +
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/record/script/ScriptedReader.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/record/script/ScriptedReader.java
index 6e194b9107..23253902b8 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/record/script/ScriptedReader.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/record/script/ScriptedReader.java
@@ -47,7 +47,7 @@ import java.util.Map;
/**
* A RecordReader implementation that allows the user to script the RecordReader instance
*/
-@Tags({"record", "recordFactory", "script", "invoke", "groovy", "python", "jython"})
+@Tags({"record", "recordFactory", "script", "invoke", "groovy"})
@CapabilityDescription("Allows the user to provide a scripted RecordReaderFactory instance in order to read/parse/generate records from an incoming flow file.")
@DynamicProperty(name = "Script Engine Binding property", value = "Binding property value passed to Script Runner",
expressionLanguageScope = ExpressionLanguageScope.ENVIRONMENT,
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/record/script/ScriptedRecordSetWriter.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/record/script/ScriptedRecordSetWriter.java
index 6fd24466e4..d59ea30c66 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/record/script/ScriptedRecordSetWriter.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/record/script/ScriptedRecordSetWriter.java
@@ -47,7 +47,7 @@ import java.util.Map;
/**
* A RecordSetWriter implementation that allows the user to script the RecordWriter instance
*/
-@Tags({"record", "writer", "script", "invoke", "groovy", "python", "jython"})
+@Tags({"record", "writer", "script", "invoke", "groovy"})
@CapabilityDescription("Allows the user to provide a scripted RecordSetWriterFactory instance in order to write records to an outgoing flow file.")
@DynamicProperty(name = "Script Engine Binding property", value = "Binding property value passed to Script Runner",
expressionLanguageScope = ExpressionLanguageScope.ENVIRONMENT,
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/record/sink/script/ScriptedRecordSink.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/record/sink/script/ScriptedRecordSink.java
index 1ee93462b9..e74748469f 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/record/sink/script/ScriptedRecordSink.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/record/sink/script/ScriptedRecordSink.java
@@ -50,7 +50,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
-@Tags({"record", "record sink", "script", "invoke", "groovy", "python", "jython"})
+@Tags({"record", "record sink", "script", "invoke", "groovy"})
@CapabilityDescription("Allows the user to provide a scripted RecordSinkService instance in order to transmit records to the desired target. The script must set a variable 'recordSink' to an "
+ "implementation of RecordSinkService.")
@DynamicProperty(name = "Script Engine Binding property", value = "Binding property value passed to Script Runner",
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/reporting/script/ScriptedReportingTask.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/reporting/script/ScriptedReportingTask.java
index 22deb20aec..c90099da36 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/reporting/script/ScriptedReportingTask.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/reporting/script/ScriptedReportingTask.java
@@ -56,7 +56,7 @@ import java.util.Map;
* A Reporting task whose body is provided by a script (via supported JSR-223 script engines)
*/
@SupportsSensitiveDynamicProperties
-@Tags({"reporting", "script", "execute", "groovy", "python", "jython"})
+@Tags({"reporting", "script", "execute", "groovy"})
@CapabilityDescription("Provides reporting and status information to a script. ReportingContext, ComponentLog, and VirtualMachineMetrics objects are made available "
+ "as variables (context, log, and vmMetrics, respectively) to the script for further processing. The context makes various information available such "
+ "as events, provenance, bulletins, controller services, process groups, Java Virtual Machine metrics, etc.")
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/script/ScriptRunnerFactory.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/script/ScriptRunnerFactory.java
index fc263c3529..c6c4c9510f 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/script/ScriptRunnerFactory.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/script/ScriptRunnerFactory.java
@@ -21,7 +21,6 @@ import org.apache.nifi.processors.script.ScriptRunner;
import org.apache.nifi.script.impl.ClojureScriptRunner;
import org.apache.nifi.script.impl.GenericScriptRunner;
import org.apache.nifi.script.impl.GroovyScriptRunner;
-import org.apache.nifi.script.impl.JythonScriptRunner;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
@@ -51,9 +50,6 @@ public class ScriptRunnerFactory {
if ("Groovy".equals(scriptEngineName)) {
return new GroovyScriptRunner(scriptEngine, scriptToRun, null);
}
- if ("python".equals(scriptEngineName)) {
- return new JythonScriptRunner(scriptEngine, scriptToRun, modulePaths);
- }
if ("Clojure".equals(scriptEngineName)) {
return new ClojureScriptRunner(scriptEngine, scriptToRun, null);
}
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/script/ScriptingComponentHelper.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/script/ScriptingComponentHelper.java
index b70b2fd2bf..0ec62e5fc6 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/script/ScriptingComponentHelper.java
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/script/ScriptingComponentHelper.java
@@ -267,11 +267,7 @@ public class ScriptingComponentHelper {
scriptEngineName = context.getProperty(SCRIPT_ENGINE).getValue();
scriptPath = context.getProperty(ScriptingComponentUtils.SCRIPT_FILE).evaluateAttributeExpressions().getValue();
scriptBody = context.getProperty(ScriptingComponentUtils.SCRIPT_BODY).getValue();
- if ("python".equalsIgnoreCase(scriptEngineName)) {
- modules = context.getProperty(ScriptingComponentUtils.MODULES).evaluateAttributeExpressions().asResources();
- } else {
- modules = context.getProperty(ScriptingComponentUtils.MODULES).evaluateAttributeExpressions().asResources().flattenRecursively();
- }
+ modules = context.getProperty(ScriptingComponentUtils.MODULES).evaluateAttributeExpressions().asResources().flattenRecursively();
}
public void stop() {
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/script/impl/JythonScriptRunner.java b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/script/impl/JythonScriptRunner.java
deleted file mode 100644
index 89cb3eebbf..0000000000
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/java/org/apache/nifi/script/impl/JythonScriptRunner.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.
- */
-package org.apache.nifi.script.impl;
-
-import org.python.core.PyString;
-
-import javax.script.Bindings;
-import javax.script.Compilable;
-import javax.script.CompiledScript;
-import javax.script.ScriptEngine;
-import javax.script.ScriptException;
-import java.util.Arrays;
-import java.util.stream.Collectors;
-
-/**
- * A helper class to configure the Jython engine with any specific requirements
- */
-public class JythonScriptRunner extends BaseScriptRunner {
-
- private final CompiledScript compiledScript;
-
- public JythonScriptRunner(ScriptEngine engine, String scriptBody, String[] modulePaths) throws ScriptException {
- super(engine, scriptBody, buildPreloads(modulePaths), modulePaths);
- // Add prefix for import sys and all jython modules
- compiledScript = ((Compilable) engine).compile(this.scriptBody);
- }
-
- private static String buildPreloads(String[] modulePaths) {
- return "import sys\n"
- + Arrays.stream(modulePaths).map((modulePath) -> "sys.path.append(" + PyString.encode_UnicodeEscape(modulePath, true) + ")")
- .collect(Collectors.joining("\n")) + "\n";
- }
-
- @Override
- public String getScriptEngineName() {
- return "python";
- }
-
- @Override
- public ScriptEngine getScriptEngine() {
- return scriptEngine;
- }
-
- @Override
- public void run(Bindings bindings) throws ScriptException {
- if (compiledScript == null) {
- throw new ScriptException("Jython script has not been successfully compiled");
- }
- compiledScript.eval();
- }
-}
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/resources/META-INF/services/org.apache.nifi.processors.script.ScriptEngineConfigurator b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/resources/META-INF/services/org.apache.nifi.processors.script.ScriptEngineConfigurator
index 3d82a2e8ee..a8b9e27b2b 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/resources/META-INF/services/org.apache.nifi.processors.script.ScriptEngineConfigurator
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/resources/META-INF/services/org.apache.nifi.processors.script.ScriptEngineConfigurator
@@ -14,5 +14,4 @@
# limitations under the License.
org.apache.nifi.script.impl.ClojureScriptRunner
-org.apache.nifi.script.impl.JythonScriptRunner
org.apache.nifi.script.impl.GroovyScriptRunner
diff --git a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/resources/docs/org.apache.nifi.processors.script.ExecuteScript/additionalDetails.html b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/resources/docs/org.apache.nifi.processors.script.ExecuteScript/additionalDetails.html
index 42e2c12795..ed292499e7 100644
--- a/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/resources/docs/org.apache.nifi.processors.script.ExecuteScript/additionalDetails.html
+++ b/nifi-nar-bundles/nifi-scripting-bundle/nifi-scripting-processors/src/main/resources/docs/org.apache.nifi.processors.script.ExecuteScript/additionalDetails.html
@@ -45,7 +45,6 @@ td {text-align: left}
Notes:
- - The engine listed as "python" in the list of available script engines is actually Jython, not Python. When using Jython, you cannot import pure (CPython) modules such as pandas
- ExecuteScript uses the JSR-223 Script Engine API to evaluate scripts, so the use of idiomatic language structure is sometimes limited. For example, in the case of Groovy, there is a separate ExecuteGroovyScript processor that allows you to do many more idiomatic Groovy tasks. For example, it's easier to interact with Controller Services via ExecuteGroovyScript vs. ExecuteScript (see the ExecuteGroovyScript documentation for more details)
@@ -101,12 +100,6 @@ td {text-align: left}
flowFile = session.get()
if(!flowFile) return
-Jython
-flowFile = session.get()
-if (flowFile != None):
- # All processing code starts at this indent
-# implicit return at the end
-
Get multiple incoming FlowFiles from the session:
@@ -121,12 +114,6 @@ if(!flowFileList.isEmpty()) {
}
}
-Jython
-flowFileList = session.get(100)
-if not flowFileList.isEmpty():
- for flowFile in flowFileList:
- # Process each FlowFile here
-
Create a new FlowFile
@@ -137,10 +124,6 @@ if not flowFileList.isEmpty():
flowFile = session.create()
// Additional processing here
-Jython
-flowFile = session.create()
-# Additional processing here
-
Create a new FlowFile from a parent FlowFile
@@ -153,12 +136,6 @@ if(!flowFile) return
newFlowFile = session.create(flowFile)
// Additional processing here
-Jython
-flowFile = session.get()
-if (flowFile != None):
- newFlowFile = session.create(flowFile)
- # Additional processing here
-
Add an attribute to a FlowFile
@@ -171,18 +148,11 @@ if (flowFile != None):
if(!flowFile) return
flowFile = session.putAttribute(flowFile, 'myAttr', 'myValue')
-Jython
-flowFile = session.get()
-if (flowFile != None):
- flowFile = session.putAttribute(flowFile, 'myAttr', 'myValue')
-# implicit return at the end
-
Add multiple attributes to a FlowFile
Use Case: You have a FlowFile to which you'd like to add custom attributes.
Approach: Use the putAllAttributes(flowFile, attributeMap) method from the session object. This method updates the given FlowFile's attributes with the key/value pairs from the given Map. NOTE: The "uuid" attribute is fixed for a FlowFile and cannot be modified; if the key is named "uuid", it will be ignored.
-The technique here is to create a Map (aka dictionary in Jython) of the attribute key/value pairs you'd like to update, then call putAllAttributes() on it. This is much more efficient than calling putAttribute() for each key/value pair, as the latter case will cause the framework to create a temporary version of the FlowFile for each attribute added (see above recipe for discussion on FlowFile immutability). The examples show a map of two entries myAttr1 and myAttr2, set to '1' and the language-specific coercion of the number 2 as a String (to adhere to the method signature of requiring String values for both key and value). Note that a session.transfer() is not specified here (so the code snippets below do not work as-is), see the following recipe for that.
Examples:
Groovy
attrMap = ['myAttr1': '1', 'myAttr2': Integer.toString(2)]
@@ -190,13 +160,6 @@ flowFile = session.get()
if(!flowFile) return
flowFile = session.putAllAttributes(flowFile, attrMap)
-Jython
-attrMap = {'myAttr1':'1', 'myAttr2':str(2)}
-flowFile = session.get()
-if (flowFile != None):
- flowFile = session.putAllAttributes(flowFile, attrMap)
-# implicit return at the end
-
Get an attribute from a FlowFile
@@ -208,12 +171,6 @@ if (flowFile != None):
if(!flowFile) return
myAttr = flowFile.getAttribute('filename')
-Jython
-flowFile = session.get()
-if (flowFile != None):
- myAttr = flowFile.getAttribute('filename')
-# implicit return at the end
-
Get all attributes from a FlowFile
@@ -227,13 +184,6 @@ flowFile.getAttributes().each { key,value ->
// Do something with the key/value pair
}
-Jython
-flowFile = session.get()
-if (flowFile != None):
- for key,value in flowFile.getAttributes().iteritems():
- # Do something with key and/or value
-# implicit return at the end
-
Transfer a FlowFile to a relationship
Use Case: After processing a FlowFile (new or incoming), you want to transfer the FlowFile to a relationship ("success" or "failure"). In this simple case let us assume there is a variable called "errorOccurred" that indicates which relationship to which the FlowFile should be transferred. Additional error handling techniques will be discussed in part 2 of this series.
@@ -251,16 +201,6 @@ else {
session.transfer(flowFile, REL_SUCCESS)
}
-Jython
-flowFile = session.get()
-if (flowFile != None):
- # All processing code starts at this indent
- if errorOccurred:
- session.transfer(flowFile, REL_FAILURE)
- else:
- session.transfer(flowFile, REL_SUCCESS)
-# implicit return at the end
-
Send a message to the log at a specified logging level
Use Case: You want to report some event that has occurred during processing to the logging framework.
@@ -269,13 +209,6 @@ if (flowFile != None):
Groovy
log.info('Found these things: {} {} {}', ['Hello',1,true] as Object[])
-Jython
-from java.lang import Object
-from jarray import array
-objArray = ['Hello',1,True]
-javaArray = array(objArray, Object)
-log.info('Found these things: {} {} {}', javaArray)
-
Read the contents of an incoming FlowFile using a callback
@@ -293,25 +226,6 @@ session.read(flowFile, {inputStream ->
text = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
// Do something with text here
} as InputStreamCallback)
-Jython
-
-from org.apache.commons.io import IOUtils
-from java.nio.charset import StandardCharsets
-from org.apache.nifi.processor.io import InputStreamCallback
-
-# Define a subclass of InputStreamCallback for use in session.read()
-class PyInputStreamCallback(InputStreamCallback):
- def __init__(self):
- pass
- def process(self, inputStream):
- text = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
- # Do something with text here
-# end class
-flowFile = session.get()
-if(flowFile != None):
- session.read(flowFile, PyInputStreamCallback())
-# implicit return at the end
-
Write content to an outgoing FlowFile using a callback
@@ -330,24 +244,6 @@ def text = 'Hello world!'
flowFile = session.write(flowFile, {outputStream ->
outputStream.write(text.getBytes(StandardCharsets.UTF_8))
} as OutputStreamCallback)
-Jython
-
-from org.apache.commons.io import IOUtils
-from java.nio.charset import StandardCharsets
-from org.apache.nifi.processor.io import OutputStreamCallback
-
-# Define a subclass of OutputStreamCallback for use in session.write()
-class PyOutputStreamCallback(OutputStreamCallback):
- def __init__(self):
- pass
- def process(self, outputStream):
- outputStream.write(bytearray('Hello World!'.encode('utf-8')))
-# end class
-flowFile = session.get()
-if(flowFile != None):
- flowFile = session.write(flowFile, PyOutputStreamCallback())
-# implicit return at the end
-
Overwrite an incoming FlowFile with updated content using a callback
@@ -371,25 +267,6 @@ flowFile = session.write(flowFile, {inputStream, outputStream ->
} as StreamCallback)
session.transfer(flowFile, REL_SUCCESS)
-Jython
-
-from org.apache.commons.io import IOUtils
-from java.nio.charset import StandardCharsets
-from org.apache.nifi.processor.io import StreamCallback
-
-# Define a subclass of StreamCallback for use in session.write()
-class PyStreamCallback(StreamCallback):
- def __init__(self):
- pass
- def process(self, inputStream, outputStream):
- text = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
- outputStream.write(bytearray('Hello World!'[::-1].encode('utf-8')))
-# end class
-flowFile = session.get()
-if(flowFile != None):
- flowFile = session.write(flowFile, PyStreamCallback())
-# implicit return at the end
-
Handle errors during script processing
@@ -411,19 +288,5 @@ try {
session.transfer(flowFile, REL_FAILURE)
}
-Jython
-
-flowFile = session.get()
-if(flowFile != None):
- try:
- # Something that might throw an exception here
-
- # Last operation is transfer to success (failures handled in the catch block)
- session.transfer(flowFile, REL_SUCCESS)
- except:
- log.error('Something went wrong', e)
- session.transfer(flowFile, REL_FAILURE)
-# implicit return at the end
-