2024-03-20T09:55:50.834Z [job-425984-jobServer-425984-9:Hello Action(P106.F659.E660):Action] ERROR (com.nolio.platform.shared.datamodel.ActionExecutionState$2:133) - Exception caught: java.lang.NoSuchFieldError: _log
java.lang.NoSuchFieldError: _log
at com.mycompany.testjy7.testjy7b.executeAction(testjy7b.java:43) ~[testjy7.jar:?]
at com.nolio.platform.shared.datamodel.Action.executeAction(Action.java:443) ~[nolio-shared-6.8.3.jar:?]
at com.nolio.platform.shared.datamodel.Action.execute(Action.java:436) ~[nolio-shared-6.8.3.jar:?]
at com.nolio.platform.shared.datamodel.ActionExecutionState.localExecution(ActionExecutionState.java:377) ~[nolio-shared-6.8.3.jar:?]
at com.nolio.platform.shared.datamodel.ActionExecutionState.access$500(ActionExecutionState.java:45) ~[nolio-shared-6.8.3.jar:?]
at com.nolio.platform.shared.datamodel.ActionExecutionState$2.execAction(ActionExecutionState.java:127) ~[nolio-shared-6.8.3.jar:?]
at com.nolio.platform.shared.datamodel.ActionExecutionState.exec(ActionExecutionState.java:413) ~[nolio-shared-6.8.3.jar:?]
at com.nolio.platform.shared.datamodel.Action.run(Action.java:233) ~[nolio-shared-6.8.3.jar:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_332]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_332]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_332]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_332]
at com.nolio.platform.shared.flowcontrol.LocalFlowController$JobBoundThreadFactory$1.run(LocalFlowController.java:835) ~[nolio-shared-6.8.3.jar:?]
at java.lang.Thread.run(Thread.java:750) ~[?:1.8.0_332]
2024-03-20T09:55:50.835Z [job-425984-jobServer-425984-9:Hello Action(P106.F659.E660):Action] DEBUG (com.nolio.platform.shared.datamodel.Action:426) - Next Action Execution State Stopped
In Release Automation 6.7 and earlier, NolioAction interface has _log member defined like this :
static org.apache.log4j.logger _log
In SDK documentation :
But since Release Automation 6.8, _log member has been removed from NolioAction.
The field _log was removed from the interface NolioAction intentionally and permanently, by architectural reasons. Having such static fields in interfaces is a generally bad pattern, making confusions and complications in further development.
The solution is to change the custom SDK codes by adding a member _log for every action class
Add this line :
import org.apache.log4j.Logger;
And create the logger field
protected static transient Logger _log = Logger.getLogger([ActionClassName].class);
In the end we should get something like that:
package my.package.name
import com.nolio.platform.shared.api.*;
import org.apache.log4j.Logger;
/**
*
* <p>Date:
*
* @author
*/
@ActionDescriptor(
name = "Class Name",
description = "",
category="")
public class MyClassName implements NolioAction {
private static final long serialVersionUID = 1L;
protected static transient Logger _log = Logger.getLogger( MyClassName.class);
@Override
public ActionResult executeAction() {
return new ActionResult(true, "Action completed");
}
}
Another solution is to apply patch 6.8.4 and 6.9.1 as _log member will be added again in the class NolioAction.
Example :
- This class was created with SDK and working fine with agent 6.7 but no more with agent 6.8 due to line "_log.debug ("This is a log writing from custom action");"
package com.mycompany.testjy7;
import com.nolio.platform.shared.api.*;
/**
* An example Nolio action
*
* <p>Date: Mar 12, 2024</p>
*
* @author jy
*/
@ActionDescriptor(
name = "Hello Action",
description = "This action receives a name and returns a welcome greeting.",
category="Greeting.Hello" /* Parent category is greeting, and sub category is Hello */)
public class testjy7b implements NolioAction {
private static final long serialVersionUID = 1L;
@ParameterDescriptor(
name = "Username",
description = "The name of the user",
out = false, // Whether parameter is an output.
in = true, // Whether parameter is an input.
nullable = true, // Whether parameter can have a null value. Must be true if a default value exists.
defaultValueAsString = "jy", // Used as the default value of this parameter.
order = 1 // Indicates the order of the parameters in the UI
)
private String username = "jy";
@ParameterDescriptor(
name = "Welcome String",
description = "Welcome greeting",
out = true,
in = false)
private String welcomeString;
@Override
public ActionResult executeAction() {
if ("error".equalsIgnoreCase(username)) {
return new ActionResult(false, "Error occurred. sorry!");
} else {
welcomeString = "Hello " + username;
_log.debug ("This is a log writing from custom action");
return new ActionResult(true, "Hello " + username);
}
}
}
package com.mycompany.testjy7;
import com.nolio.platform.shared.api.*;
import org.apache.log4j.Logger;
/**
* An example Nolio action
*
* <p>Date: Mar 12, 2024</p>
*
* @author jy
*/
@ActionDescriptor(
name = "Hello Action",
description = "This action receives a name and returns a welcome greeting.",
category="Greeting.Hello" /* Parent category is greeting, and sub category is Hello */)
public class testjy7b implements NolioAction {
private static final long serialVersionUID = 1L;
protected static transient Logger _log = Logger.getLogger(testjy7b.class);
@ParameterDescriptor(
name = "Username",
description = "The name of the user",
out = false, // Whether parameter is an output.
in = true, // Whether parameter is an input.
nullable = true, // Whether parameter can have a null value. Must be true if a default value exists.
defaultValueAsString = "jy", // Used as the default value of this parameter.
order = 1 // Indicates the order of the parameters in the UI
)
private String username = "jy";
@ParameterDescriptor(
name = "Welcome String",
description = "Welcome greeting",
out = true,
in = false)
private String welcomeString;
@Override
public ActionResult executeAction() {
if ("error".equalsIgnoreCase(username)) {
return new ActionResult(false, "Error occurred. sorry!");
} else {
welcomeString = "Hello " + username;
_log.debug ("This is a log writing from custom action");
return new ActionResult(true, "Hello " + username);
}
}
}