diff --git a/modules/groovy/src/main/java/org/jpos/groovy/GroovyRequestListener.java b/modules/groovy/src/main/java/org/jpos/groovy/GroovyRequestListener.java
index 2895ba6fe2..74a365c92c 100644
--- a/modules/groovy/src/main/java/org/jpos/groovy/GroovyRequestListener.java
+++ b/modules/groovy/src/main/java/org/jpos/groovy/GroovyRequestListener.java
@@ -31,6 +31,7 @@
import java.io.File;
import java.io.IOException;
+import java.net.URL;
import java.util.Arrays;
import java.util.HashSet;
@@ -147,6 +148,10 @@ public void setConfiguration (Configuration cfg)
@Override
public void setConfiguration(Element e) throws ConfigurationException
{
+ ClassLoader thisCL= this.getClass().getClassLoader();
+ URL scriptURL= thisCL.getResource("org/jpos/groovy/JPOSGroovyDefaults.groovy");
+ GroovySetup.runScriptOnce(scriptURL);
+
xmlCfg= e;
script= getScript(e.getChild("script"));
diff --git a/modules/groovy/src/main/java/org/jpos/q2/qbean/Groovy.java b/modules/groovy/src/main/java/org/jpos/q2/qbean/Groovy.java
index 596f93db3c..7bca2b0802 100644
--- a/modules/groovy/src/main/java/org/jpos/q2/qbean/Groovy.java
+++ b/modules/groovy/src/main/java/org/jpos/q2/qbean/Groovy.java
@@ -21,9 +21,11 @@
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import org.jdom2.Element;
+import org.jpos.groovy.GroovySetup;
import org.jpos.q2.QBeanSupport;
import java.io.File;
+import java.net.URL;
/**
* Groovy Interpreter QBean.
@@ -36,6 +38,10 @@ public void startService() {
public void run() {
try {
+ ClassLoader thisCL= this.getClass().getClassLoader();
+ URL scriptURL= thisCL.getResource("org/jpos/groovy/JPOSGroovyDefaults.groovy");
+ GroovySetup.runScriptOnce(scriptURL);
+
Element e = getPersist();
Binding binding = new Binding();
binding.setVariable("qbean", this);
diff --git a/modules/groovy/src/main/java/org/jpos/transaction/participant/GroovyParticipant.java b/modules/groovy/src/main/java/org/jpos/transaction/participant/GroovyParticipant.java
index 9d341c6d50..ccc05925f6 100644
--- a/modules/groovy/src/main/java/org/jpos/transaction/participant/GroovyParticipant.java
+++ b/modules/groovy/src/main/java/org/jpos/transaction/participant/GroovyParticipant.java
@@ -110,7 +110,7 @@ public class GroovyParticipant extends Log
private TransactionManager tm;
protected Configuration cfg;
- private final String groovyShellKey = ".groovy-" + Integer.toString(hashCode());
+ private final String groovyShellKey = ".groovy-" + hashCode();
@SuppressWarnings("unchecked")
@@ -197,7 +197,7 @@ public void setConfiguration(Configuration cfg) throws ConfigurationException {
@Override
public void setConfiguration(Element e) throws ConfigurationException {
ClassLoader thisCL= this.getClass().getClassLoader();
- URL scriptURL= thisCL.getResource("org/jpos/transaction/ContextDefaults.groovy");
+ URL scriptURL= thisCL.getResource("org/jpos/groovy/JPOSGroovyDefaults.groovy");
GroovySetup.runScriptOnce(scriptURL);
compiled= cfg.getBoolean("compiled", true);
diff --git a/modules/groovy/src/main/resources/org/jpos/groovy/JPOSGroovyDefaults.groovy b/modules/groovy/src/main/resources/org/jpos/groovy/JPOSGroovyDefaults.groovy
new file mode 100644
index 0000000000..987368f461
--- /dev/null
+++ b/modules/groovy/src/main/resources/org/jpos/groovy/JPOSGroovyDefaults.groovy
@@ -0,0 +1,106 @@
+/*
+ * jPOS Project [http://jpos.org]
+ * Copyright (C) 2000-2020 jPOS Software SRL
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.jpos.groovy
+
+import groovy.transform.CompileStatic
+import groovy.transform.Field
+
+import org.jpos.transaction.Context
+import org.jpos.util.Caller
+
+
+// ### Groovy initialization to spice up Context object
+
+def ctxmc= Context.metaClass
+
+ctxmc.getProperty= { String name ->
+ return delegate.get(name)
+}
+
+ctxmc.setProperty= { String name, Object val ->
+ delegate.put(name, val)
+}
+
+
+ctxmc.getAt= { Object key ->
+ return delegate.get(key)
+}
+
+ctxmc.putAt= { Object key, Object val ->
+ delegate.put(key, val)
+}
+
+
+// ### Groovy alternatives for org.jpos.util.Caller#info() methods
+
+
+// We want to ignore stack elements belonging to these classes
+// This list and the shouldExclude method are inspired by org.codehaus.groovy.runtime.StackTraceUtils.isApplicationClass()
+@Field static final List filter= [
+ "groovy.lang.", "org.codehaus.groovy.", "org.apache.groovy.", "gjdk.groovy.",
+ "sun.reflect.", "java.lang.reflect.",
+ "org.jpos.groovy.JPOSGroovyDefaults." ]
+@CompileStatic
+private static boolean shouldExclude(String className)
+{
+ for (String f in filter)
+ {
+ if (className.startsWith(f))
+ return true
+ }
+ return false
+}
+
+
+/* Based on org.jpos.util.Caller.info(int) */
+@CompileStatic
+private static String info(int pos)
+{
+ StackTraceElement [] stels= Thread.currentThread().getStackTrace()
+ StackTraceElement st= stels[stels.length - 1] // avoid jumping out of the stack
+
+ // Find the useful stack position, when ignoring internal groovy and java reflection stuff
+ int wantedPos= pos + 3
+ pos= 0
+ for (StackTraceElement el : stels)
+ {
+ if (!shouldExclude(el.getClassName()))
+ {
+ if (pos++ == wantedPos)
+ {
+ st= el // found it!
+ break
+ }
+ }
+ }
+
+ String clazz = st.getClassName()
+ StringBuilder sb = new StringBuilder(Caller.shortClassName(clazz))
+ return sb.append(".").append(st.getMethodName())
+ .append(':')
+ .append(Integer.toString(st.getLineNumber()))
+ .toString()
+}
+
+
+def callermc= Caller.metaClass
+
+callermc.static.info = { int p -> info(p) }
+callermc.static.info = { -> info(0) }
+
diff --git a/modules/groovy/src/main/resources/org/jpos/transaction/ContextDefaults.groovy b/modules/groovy/src/main/resources/org/jpos/transaction/ContextDefaults.groovy
deleted file mode 100644
index b8bd0e1b07..0000000000
--- a/modules/groovy/src/main/resources/org/jpos/transaction/ContextDefaults.groovy
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * jPOS Project [http://jpos.org]
- * Copyright (C) 2000-2017 jPOS Software SRL
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-
-// Groovy initialization to spice up Context object
-
-import org.jpos.transaction.*
-
-
-def ctxmc= Context.metaClass
-
-ctxmc.getProperty= { String name ->
- return delegate.get(name)
-}
-
-ctxmc.setProperty= { String name, Object val ->
- delegate.put(name, val)
-}
-
-
-ctxmc.getAt= { Object key ->
- return delegate.get(key)
-}
-
-ctxmc.putAt= { Object key, Object val ->
- delegate.put(key, val)
-}
-
-
-return ctxmc