Fix JRuby interpreter shutdown issue 50/98450/1
authorliamfallon <liam.fallon@est.tech>
Fri, 15 Nov 2019 13:40:08 +0000 (13:40 +0000)
committerliamfallon <liam.fallon@est.tech>
Fri, 15 Nov 2019 13:42:11 +0000 (13:42 +0000)
The new version of JRuby fixes this issue. Also amended unit test to
check for shutdown and immediate recreation of JRuby interpreter.

Issue-ID: POLICY-1276
Change-Id: I723e0396985d3163b483e52fdaceb4b4fab7274b
Signed-off-by: liamfallon <liam.fallon@est.tech>
plugins/plugins-executor/plugins-executor-jruby/pom.xml
plugins/plugins-executor/plugins-executor-jruby/src/main/java/org/onap/policy/apex/plugins/executor/jruby/JrubyStateFinalizerExecutor.java
plugins/plugins-executor/plugins-executor-jruby/src/main/java/org/onap/policy/apex/plugins/executor/jruby/JrubyTaskExecutor.java
plugins/plugins-executor/plugins-executor-jruby/src/main/java/org/onap/policy/apex/plugins/executor/jruby/JrubyTaskSelectExecutor.java
plugins/plugins-executor/plugins-executor-jruby/src/test/java/org/onap/policy/apex/plugins/executor/jruby/JrubyTaskExecutorTest.java

index 72fd8cc..976166b 100644 (file)
@@ -1,6 +1,7 @@
 <!--
   ============LICENSE_START=======================================================
    Copyright (C) 2018 Ericsson. All rights reserved.
+   Modifications Copyright (C) 2019 Nordix Foundation.
   ================================================================================
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
@@ -33,7 +34,7 @@
         <dependency>
             <groupId>org.jruby</groupId>
             <artifactId>jruby-core</artifactId>
-            <version>9.2.0.0</version>
+            <version>9.2.9.0</version>
             <exclusions>
                 <exclusion>
                     <groupId>org.jruby.extras</groupId>
         <dependency>
             <groupId>org.jruby.extras</groupId>
             <artifactId>bytelist</artifactId>
-            <version>1.0.13</version>
+            <version>1.0.15</version>
         </dependency>
         <dependency>
             <groupId>com.github.jnr</groupId>
             <artifactId>jffi</artifactId>
-            <version>1.2.10</version>
+            <version>1.2.22</version>
         </dependency>
     </dependencies>
 
index d6e9f4d..28e61b6 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -44,8 +45,8 @@ public class JrubyStateFinalizerExecutor extends StateFinalizerExecutor {
     private static final XLogger LOGGER = XLoggerFactory.getXLogger(JrubyStateFinalizerExecutor.class);
 
     // Jruby container
-    private ScriptingContainer container =
-            new ScriptingContainer(LocalContextScope.CONCURRENT, LocalVariableBehavior.TRANSIENT, true);
+    private ScriptingContainer container = new ScriptingContainer(LocalContextScope.CONCURRENT,
+                    LocalVariableBehavior.TRANSIENT, true);
     private EmbedEvalUnit parsedjruby = null;
 
     /**
@@ -60,10 +61,11 @@ public class JrubyStateFinalizerExecutor extends StateFinalizerExecutor {
 
         // Set up the JRuby engine
         container = (container == null)
-                ? new ScriptingContainer(LocalContextScope.CONCURRENT, LocalVariableBehavior.TRANSIENT, true)
-                : container;
-        container.setError(System.err);
-        container.setOutput(System.out);
+                        ? new ScriptingContainer(LocalContextScope.CONCURRENT, LocalVariableBehavior.TRANSIENT, true)
+                        : container;
+
+        // Use the container.setError(System.err) and container.setOutput(System.out) method calls to redirect output
+        // and error to standard output and error for debugging
         container.put("executor", getExecutionContext()); // needed for the compile
         parsedjruby = container.parse(getSubject().getLogic());
     }
@@ -80,7 +82,7 @@ public class JrubyStateFinalizerExecutor extends StateFinalizerExecutor {
      */
     @Override
     public String execute(final long executionId, final Properties executionProperties,
-            final Map<String, Object> incomingFields) throws StateMachineException, ContextException {
+                    final Map<String, Object> incomingFields) throws StateMachineException, ContextException {
         // Do execution pre work
         executePre(executionId, executionProperties, incomingFields);
 
@@ -112,7 +114,7 @@ public class JrubyStateFinalizerExecutor extends StateFinalizerExecutor {
     @Override
     public void cleanUp() throws StateMachineException {
         LOGGER.debug("cleanUp:" + getSubject().getKey().getId() + "," + getSubject().getLogicFlavour() + ","
-                + getSubject().getLogic());
+                        + getSubject().getLogic());
         container.terminate();
         container = null;
     }
index c805597..3944aab 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -44,8 +45,8 @@ public class JrubyTaskExecutor extends TaskExecutor {
     private static final XLogger LOGGER = XLoggerFactory.getXLogger(JrubyTaskExecutor.class);
 
     // Jruby container
-    private ScriptingContainer container =
-            new ScriptingContainer(LocalContextScope.CONCURRENT, LocalVariableBehavior.TRANSIENT, true);
+    private ScriptingContainer container = new ScriptingContainer(LocalContextScope.CONCURRENT,
+                    LocalVariableBehavior.TRANSIENT, true);
     private EmbedEvalUnit parsedjruby = null;
 
     /**
@@ -60,10 +61,11 @@ public class JrubyTaskExecutor extends TaskExecutor {
 
         // Set up the JRuby engine
         container = (container == null)
-                ? new ScriptingContainer(LocalContextScope.CONCURRENT, LocalVariableBehavior.TRANSIENT, true)
-                : container;
-        container.setError(System.err);
-        container.setOutput(System.out);
+                        ? new ScriptingContainer(LocalContextScope.CONCURRENT, LocalVariableBehavior.TRANSIENT, true)
+                        : container;
+
+        // Use the container.setError(System.err) and container.setOutput(System.out) method calls to redirect output
+        // and error to standard output and error for debugging
         container.put("executor", getExecutionContext()); // needed for the compile
         parsedjruby = container.parse(getSubject().getTaskLogic().getLogic());
     }
@@ -80,7 +82,7 @@ public class JrubyTaskExecutor extends TaskExecutor {
      */
     @Override
     public Map<String, Object> execute(final long executionId, final Properties executionProperties,
-            final Map<String, Object> incomingFields) throws StateMachineException, ContextException {
+                    final Map<String, Object> incomingFields) throws StateMachineException, ContextException {
         // Do execution pre work
         executePre(executionId, executionProperties, incomingFields);
 
@@ -112,7 +114,7 @@ public class JrubyTaskExecutor extends TaskExecutor {
     @Override
     public void cleanUp() throws StateMachineException {
         LOGGER.debug("cleanUp:" + getSubject().getKey().getId() + "," + getSubject().getTaskLogic().getLogicFlavour()
-                + "," + getSubject().getTaskLogic().getLogic());
+                        + "," + getSubject().getTaskLogic().getLogic());
         container.terminate();
         container = null;
     }
index 274acbe..2655aa1 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,8 +48,8 @@ public class JrubyTaskSelectExecutor extends TaskSelectExecutor {
     private static final XLogger LOGGER = XLoggerFactory.getXLogger(JrubyTaskSelectExecutor.class);
 
     // Jruby container
-    private ScriptingContainer container =
-            new ScriptingContainer(LocalContextScope.CONCURRENT, LocalVariableBehavior.TRANSIENT, true);
+    private ScriptingContainer container = new ScriptingContainer(LocalContextScope.CONCURRENT,
+                    LocalVariableBehavior.TRANSIENT, true);
     private EmbedEvalUnit parsedjruby = null;
 
     /**
@@ -63,8 +64,12 @@ public class JrubyTaskSelectExecutor extends TaskSelectExecutor {
 
         // Set up the JRuby engine
         container = (container == null)
-                ? new ScriptingContainer(LocalContextScope.CONCURRENT, LocalVariableBehavior.TRANSIENT, true)
-                : container;
+                        ? new ScriptingContainer(LocalContextScope.CONCURRENT, LocalVariableBehavior.TRANSIENT, true)
+                        : container;
+
+        // Use the container.setError(System.err) and container.setOutput(System.out) method calls to redirect output
+        // and error to standard output and error for debugging
+
         container.put("executor", getExecutionContext()); // needed for compile as a placeholder
         parsedjruby = container.parse(getSubject().getTaskSelectionLogic().getLogic());
     }
@@ -81,7 +86,7 @@ public class JrubyTaskSelectExecutor extends TaskSelectExecutor {
      */
     @Override
     public AxArtifactKey execute(final long executionId, final Properties executionProperties,
-            final EnEvent incomingEvent) throws StateMachineException, ContextException {
+                    final EnEvent incomingEvent) throws StateMachineException, ContextException {
         // Do execution pre work
         executePre(executionId, executionProperties, incomingEvent);
 
@@ -113,8 +118,8 @@ public class JrubyTaskSelectExecutor extends TaskSelectExecutor {
     @Override
     public void cleanUp() throws StateMachineException {
         LOGGER.debug("cleanUp:" + getSubject().getKey().getId() + ","
-                + getSubject().getTaskSelectionLogic().getLogicFlavour() + ","
-                + getSubject().getTaskSelectionLogic().getLogic());
+                        + getSubject().getTaskSelectionLogic().getLogicFlavour() + ","
+                        + getSubject().getTaskSelectionLogic().getLogic());
         container.terminate();
         container = null;
     }
index 8b58c38..2309c1e 100644 (file)
@@ -1,6 +1,7 @@
 /*-\r
  * ============LICENSE_START=======================================================\r
  *  Copyright (C) 2019 Nordix Foundation.\r
+ *  Modifications Copyright (C) 2019 Nordix Foundation.\r
  * ================================================================================\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
@@ -69,8 +70,18 @@ public class JrubyTaskExecutorTest {
 \r
     @Test\r
     public void testJrubyTaskExecutor() {\r
+        // Run test twice to check for incorrect shutdown activity\r
+        jrubyExecutorTest();\r
+        jrubyExecutorTest();\r
+    }\r
+\r
+    /**\r
+     * Test the JRuby executor.\r
+     */\r
+    private void jrubyExecutorTest() {\r
         JrubyTaskExecutor jte = new JrubyTaskExecutor();\r
         assertNotNull(jte);\r
+\r
         try {\r
             Field fieldContainer = JrubyTaskExecutor.class.getDeclaredField("container");\r
             fieldContainer.setAccessible(true);\r
@@ -101,11 +112,11 @@ public class JrubyTaskExecutorTest {
             fail("test should throw an exception here");\r
         } catch (Exception jteException) {\r
             assertEquals("execute-post: task logic execution failure on task \"NULL\" in model NULL:0.0.0",\r
-                    jteException.getMessage());\r
+                            jteException.getMessage());\r
         }\r
 \r
-        final String jrubyLogic =\r
-                "if executor.executionId == -1" + "\n return false" + "\n else " + "\n return true" + "\n end";\r
+        final String jrubyLogic = "if executor.executionId == -1" + "\n return false" + "\n else " + "\n return true"\r
+                        + "\n end";\r
         task.getTaskLogic().setLogic(jrubyLogic);\r
 \r
         try {\r
@@ -116,5 +127,14 @@ public class JrubyTaskExecutorTest {
         } catch (Exception jteException) {\r
             fail("test should not throw an exception here");\r
         }\r
+\r
+        try {\r
+            jte.prepare();\r
+            Map<String, Object> returnMap = jte.execute(0, new Properties(), incomingParameters);\r
+            assertEquals(0, returnMap.size());\r
+            jte.cleanUp();\r
+        } catch (Exception jteException) {\r
+            fail("test should not throw an exception here");\r
+        }\r
     }\r
 }\r