Вот что я придумал.
Ansible отправляет модули в целевую систему и выполняет их там. Поэтому, если вы меняете модуль локально, ваши изменения вступят в силу при запуске playbook. На моих машинных модулях находятся /usr/lib/python2.7/site-packages/ansible/modules
(ansible-2.1.2.0
). Модуль service
находится в core/system/service.py
. Модули Anisble (экземпляры класса AnsibleModule
, объявленные в module_utils/basic.py
), имеют метод log
, который отправляет сообщения в журнал systemd, если он доступен , или возвращается к syslog
. Итак, запустите journalctl -f
в целевой системе, добавьте операторы отладки (module.log(msg='test')
) в локальный модуль и запустите свою игру. Вы увидите команды отладки под именем ansible-basic.py
.
Кроме того, при запуске ansible-playbook
с -vvv
вы можете увидеть отладочный вывод в журнале systemd
, по крайней мере, сообщения о вызове, и сообщения об ошибках, если они есть.
Еще одна вещь, если вы попытаетесь отладить код, который выполняется локально с pdb
(import pdb; pdb.set_trace()
), скорее всего, вы столкнетесь с BdbQuit
исключением. Это потому, что python
закрывает stdin
при создании потока (ansible
рабочий). Решением здесь является повторное открытие stdin
перед запуском pdb.set_trace()
, как предлагается здесь :
sys.stdin = open('/dev/tty')
import pdb; pdb.set_trace()
Это полный код
import com.crystaldecisions.reports.formulas.FormulaFunction;
import com.crystaldecisions.reports.formulas.FormulaFunctionLibrary;
public class BarcodeLibrary
implements FormulaFunctionLibrary
{
private final FormulaFunction[] functionArray = {new Code39(), new Code39Ascii(), new CodeI2of5(), new Code2of5()
,new CodeC128SetA(),new CodeEAN13()};
public FormulaFunction getFunction(int functionNumber)
{
return this.functionArray[functionNumber];
}
public int size()
{
return this.functionArray.length;
}
}
*************************************************************************
import com.crystaldecisions.reports.common.CrystalResourcesFactory;
import com.crystaldecisions.reports.common.value.FormulaValue;
import com.crystaldecisions.reports.common.value.FormulaValueType;
import com.crystaldecisions.reports.common.value.StringValue;
import com.crystaldecisions.reports.formulas.FormulaFunction;
import com.crystaldecisions.reports.formulas.FormulaFunctionArgumentDefinition;
import com.crystaldecisions.reports.formulas.FormulaFunctionCallException;
import com.crystaldecisions.reports.formulas.FormulaValueReference;
import com.crystaldecisions.reports.formulas.SimpleFormulaFunctionArgumentDefinition;
public abstract class CodeEAN13Base
implements FormulaFunction
{
FormulaFunctionArgumentDefinition[] myArguments = { SimpleFormulaFunctionArgumentDefinition.string };
protected CrystalResourcesFactory resCrystal;
public CodeEAN13Base()
{
this.resCrystal = new CrystalResourcesFactory("Messages");
}
protected final String doTranslation(String inputData,String opz)
{
String returnVal = "";
returnVal = returnVal + translateCharWrapper(inputData,opz);
return returnVal;
}
@Override
public final FormulaValue evaluate(FormulaValueReference[] arguments)
throws FormulaFunctionCallException
{
StringValue dataStringArg = (StringValue)arguments[0].getFormulaValue();
StringValue opzArg =(StringValue)arguments[1].getFormulaValue();
String dataString = dataStringArg.getString();
String opz=opzArg.getString();
String returnVal = doTranslation(dataString,opz);
return StringValue.fromString(returnVal);
}
@Override
public final FormulaFunctionArgumentDefinition[] getArguments()
{
return this.myArguments;
}
@Override
public final FormulaValueType getReturnType()
{
return FormulaValueType.string;
}
protected abstract String translate(String inputData,String opz)
throws InvalidBarcodeDataException;
//protected abstract String translateChar(String inputData)
//throws InvalidBarcodeDataException;
// private String translateCharWrapper(String inputData)
private String translateCharWrapper(String inputData,String opz)
{
String returnString;
try
{
// returnString = translateChar(inputData);
returnString = translate(inputData,opz);
} catch (InvalidBarcodeDataException e) {
returnString = "";
}
return returnString;
}
@Override
public void validateArgumentValues(FormulaValueReference[] arguments)
throws FormulaFunctionCallException
{}
}
*************************************************************************
public class CodeEAN13
extends CodeEAN13Base
{
protected String opz;
@Override
public String getIdentifier()
{
return "barcodeean13";
}
private static String oddBar(String code) {
return String.valueOf((char)(65+Integer.parseInt(code)));
}
private static String evenBar(String code) {
return String.valueOf((char)(75+Integer.parseInt(code)));
}
@Override
protected String translate(String inputData, String opz) throws InvalidBarcodeDataException {
// TODO Auto-generated method stub
Integer checkDigitSubtotal;
String checkDigit;
String temp = null;
String code=inputData;
String azalea_EAN13 = null;
Object opzM=opz;
if(!opzM.equals(null)) {
code=code+opzM;
}
//Calculate the EAN-13 check digit.
checkDigitSubtotal=3*(Integer.parseInt(code.substring(1, 2))+Integer.parseInt(code.substring(3, 4))+Integer.parseInt(code.substring(5, 6))
+Integer.parseInt(code.substring(7, 8))+Integer.parseInt(code.substring(9, 10))
+Integer.parseInt(code.substring(code.length()-1)));
checkDigitSubtotal=checkDigitSubtotal+(Integer.parseInt(code.substring(0,1))+Integer.parseInt(code.substring(2, 3))
+Integer.parseInt(code.substring(4, 5))+Integer.parseInt(code.substring(6, 7))
+Integer.parseInt(code.substring(8, 9))+Integer.parseInt(code.substring(10, 11)));
checkDigit=String.valueOf(300-checkDigitSubtotal);
checkDigit=checkDigit.substring(checkDigit.length()-1);
// Begin building the output string with the 1st character's human-readable, L guard bars & odd parity of 1st digit
temp=(char)(194+Integer.parseInt(code.substring(0,1)))+"x"+oddBar(code.substring(1, 2));
// Build the remainder of left half of symbol's parity is based on 1st digit
switch (code.substring(0,1)) {
case "0":
{
temp=temp+oddBar(code.substring(2, 3));
temp=temp+oddBar(code.substring(3, 4));
temp=temp+oddBar(code.substring(4, 5));
temp=temp+oddBar(code.substring(5, 6));
temp=temp+oddBar(code.substring(6, 7));
}
break;
case "1":
{
temp=temp+oddBar(code.substring(2, 3));
temp=temp+evenBar(code.substring(3, 4));
temp=temp+oddBar(code.substring(4, 5));
temp=temp+evenBar(code.substring(5, 6));
temp=temp+evenBar(code.substring(6, 7));
}
break;
case "2":
{
temp=temp+oddBar(code.substring(2, 3));
temp=temp+evenBar(code.substring(3, 4));
temp=temp+evenBar(code.substring(4, 5));
temp=temp+oddBar(code.substring(5, 6));
temp=temp+evenBar(code.substring(6, 7));
}
break;
case "3":
{
temp=temp+oddBar(code.substring(2, 3));
temp=temp+evenBar(code.substring(3, 4));
temp=temp+evenBar(code.substring(4, 5));
temp=temp+evenBar(code.substring(5, 6));
temp=temp+oddBar(code.substring(6, 7));
}
break;
case "4":
{
temp=temp+evenBar(code.substring(2, 3));
temp=temp+oddBar(code.substring(3, 4));
temp=temp+oddBar(code.substring(4, 5));
temp=temp+evenBar(code.substring(5, 6));
temp=temp+evenBar(code.substring(6, 7));
}
break;
case "5":
{
temp=temp+evenBar(code.substring(2, 3));
temp=temp+evenBar(code.substring(3, 4));
temp=temp+oddBar(code.substring(4, 5));
temp=temp+oddBar(code.substring(5, 6));
temp=temp+evenBar(code.substring(6, 7));
}
break;
case "6":
{
temp=temp+evenBar(code.substring(2, 3));
temp=temp+evenBar(code.substring(3, 4));
temp=temp+evenBar(code.substring(4, 5));
temp=temp+oddBar(code.substring(5, 6));
temp=temp+oddBar(code.substring(6, 7));
}
break;
case "7":
{
temp=temp+evenBar(code.substring(2, 3));
temp=temp+oddBar(code.substring(3, 4));
temp=temp+evenBar(code.substring(4, 5));
temp=temp+oddBar(code.substring(5, 6));
temp=temp+evenBar(code.substring(6, 7));
}
break;
case "8":
{
temp=temp+evenBar(code.substring(2, 3));
temp=temp+oddBar(code.substring(3, 4));
temp=temp+evenBar(code.substring(4, 5));
temp=temp+evenBar(code.substring(5, 6));
temp=temp+oddBar(code.substring(6, 7));
}
break;
case "9":
{
temp=temp+evenBar(code.substring(2, 3));
temp=temp+evenBar(code.substring(3, 4));
temp=temp+oddBar(code.substring(4, 5));
temp=temp+evenBar(code.substring(5, 6));
temp=temp+oddBar(code.substring(6, 7));
}
break;
default:
}
////Add the center guard bars & the build right half of symbol using set C (0-9)
return azalea_EAN13;
}
}
. Проблема была в следующем утверждении:
FormulaFunctionArgumentDefinition[] myArguments = {SimpleFormulaFunctionArgumentDefinition.string };
Правильная конфигурация для параметров:
FormulaFunctionArgumentDefinition[] myArguments = { SimpleFormulaFunctionArgumentDefinition.string,SimpleFormulaFunctionArgumentDefinition.string };
Очевидно, что в моей формуле Crystal Report есть два типа String или один тип String , зависит от формулы. Ниже приведен полный код для определения UFL для функции штрих-кода с двумя параметрами. Этот код устанавливает библиотеку UFL для Crystal Report.
import com.crystaldecisions.reports.common.CrystalResourcesFactory;
import com.crystaldecisions.reports.common.value.FormulaValue;
import com.crystaldecisions.reports.common.value.FormulaValueType;
import com.crystaldecisions.reports.common.value.StringValue;
import com.crystaldecisions.reports.formulas.FormulaFunction;
import com.crystaldecisions.reports.formulas.FormulaFunctionArgumentDefinition;
import com.crystaldecisions.reports.formulas.FormulaFunctionCallException;
import com.crystaldecisions.reports.formulas.FormulaValueReference;
import com.crystaldecisions.reports.formulas.SimpleFormulaFunctionArgumentDefinition;
public abstract class CodeEAN13Base
implements FormulaFunction
{
FormulaFunctionArgumentDefinition[] myArguments = { SimpleFormulaFunctionArgumentDefinition.string,SimpleFormulaFunctionArgumentDefinition.string };
protected CrystalResourcesFactory resCrystal;
public CodeEAN13Base()
{
this.resCrystal = new CrystalResourcesFactory("Messages");
}
protected final String doTranslation(String inputData,String opz)
// protected final String doTranslation(String inputData)
{
String returnVal = "";
// returnVal = returnVal + translateCharWrapper(inputData);
returnVal = returnVal + translateCharWrapper(inputData,opz);
return returnVal;
}
@Override
public final FormulaValue evaluate(FormulaValueReference[] arguments)
throws FormulaFunctionCallException
{
StringValue dataStringArg = (StringValue)arguments[0].getFormulaValue();
StringValue opzArg =(StringValue)arguments[1].getFormulaValue();
String dataString = dataStringArg.getString();
String opz=opzArg.getString();
String returnVal = doTranslation(dataString,opz);
return StringValue.fromString(returnVal);
}
@Override
public final FormulaFunctionArgumentDefinition[] getArguments()
{
return this.myArguments;
}
@Override
public final FormulaValueType getReturnType()
{
return FormulaValueType.string;
}
protected abstract String translate(String inputData,String opz)
throws InvalidBarcodeDataException;
//protected abstract String translate(String inputData)
//throws InvalidBarcodeDataException;
// private String translateCharWrapper(String inputData)
private String translateCharWrapper(String inputData,String opz)
{
String returnString;
try
{
// returnString = translate(inputData);
returnString = translate(inputData,opz);
} catch (InvalidBarcodeDataException e) {
returnString = "";
}
return returnString;
}
@Override
public void validateArgumentValues(FormulaValueReference[] arguments)
throws FormulaFunctionCallException
{}
}
public class CodeEAN13
extends CodeEAN13Base
{
//protected String opz;
@Override
public String getIdentifier()
{
return "barcodeean13";
}
private static String oddBar(String code) {
return String.valueOf((char)(65+Integer.parseInt(code)));
}
private static String evenBar(String code) {
return String.valueOf((char)(75+Integer.parseInt(code)));
}
@Override
protected String translate(String inputData, String opz) throws InvalidBarcodeDataException {
Integer checkDigitSubtotal;
String checkDigit;
String temp = null;
String code=inputData;
String azalea_EAN13 = null;
String opzM=opz;
// if(!opzM.equals(null)) {
// code=code+opzM;
// }
//Calculate the EAN-13 check digit.
checkDigitSubtotal=3*(Integer.parseInt(code.substring(1, 2))+Integer.parseInt(code.substring(3, 4))+Integer.parseInt(code.substring(5, 6))
+Integer.parseInt(code.substring(7, 8))+Integer.parseInt(code.substring(9, 10))
+Integer.parseInt(code.substring(code.length()-1)));
checkDigitSubtotal=checkDigitSubtotal+(Integer.parseInt(code.substring(0,1))+Integer.parseInt(code.substring(2, 3))
+Integer.parseInt(code.substring(4, 5))+Integer.parseInt(code.substring(6, 7))
+Integer.parseInt(code.substring(8, 9))+Integer.parseInt(code.substring(10, 11)));
checkDigit=String.valueOf(300-checkDigitSubtotal);
checkDigit=checkDigit.substring(checkDigit.length()-1);
// Begin building the output string with the 1st character's human-readable, L guard bars & odd parity of 1st digit
temp=(char)(194+Integer.parseInt(code.substring(0,1)))+"x"+oddBar(code.substring(1, 2));
// Build the remainder of left half of symbol's parity is based on 1st digit
switch (code.substring(0,1)) {
case "0":
{
//temp="U|x";
temp=temp+oddBar(code.substring(2, 3));
temp=temp+oddBar(code.substring(3, 4));
temp=temp+oddBar(code.substring(4, 5));
temp=temp+oddBar(code.substring(5, 6));
temp=temp+oddBar(code.substring(6, 7));
}
break;
case "1":
{
//temp="[|x";
temp=temp+oddBar(code.substring(2, 3));
temp=temp+evenBar(code.substring(3, 4));
temp=temp+oddBar(code.substring(4, 5));
temp=temp+evenBar(code.substring(5, 6));
temp=temp+evenBar(code.substring(6, 7));
}
break;
case "2":
{
//temp="V|x";
temp=temp+oddBar(code.substring(2, 3));
temp=temp+evenBar(code.substring(3, 4));
temp=temp+evenBar(code.substring(4, 5));
temp=temp+oddBar(code.substring(5, 6));
temp=temp+evenBar(code.substring(6, 7));
}
break;
case "3":
{
//temp="W|x";
temp=temp+oddBar(code.substring(2, 3));
temp=temp+evenBar(code.substring(3, 4));
temp=temp+evenBar(code.substring(4, 5));
temp=temp+evenBar(code.substring(5, 6));
temp=temp+oddBar(code.substring(6, 7));
}
break;
case "4":
{
//temp="X|x";
temp=temp+evenBar(code.substring(2, 3));
temp=temp+oddBar(code.substring(3, 4));
temp=temp+oddBar(code.substring(4, 5));
temp=temp+evenBar(code.substring(5, 6));
temp=temp+evenBar(code.substring(6, 7));
}
break;
case "5":
{
//temp="Y|x";
temp=temp+evenBar(code.substring(2, 3));
temp=temp+evenBar(code.substring(3, 4));
temp=temp+oddBar(code.substring(4, 5));
temp=temp+oddBar(code.substring(5, 6));
temp=temp+evenBar(code.substring(6, 7));
}
break;
case "6":
{
//temp="Z|x";
temp=temp+evenBar(code.substring(2, 3));
temp=temp+evenBar(code.substring(3, 4));
temp=temp+evenBar(code.substring(4, 5));
temp=temp+oddBar(code.substring(5, 6));
temp=temp+oddBar(code.substring(6, 7));
}
break;
case "7":
{
//temp="u|x";
temp=temp+evenBar(code.substring(2, 3));
temp=temp+oddBar(code.substring(3, 4));
temp=temp+evenBar(code.substring(4, 5));
temp=temp+oddBar(code.substring(5, 6));
temp=temp+evenBar(code.substring(6, 7));
}
break;
case "8":
{
//temp="\\|x";
temp=temp+evenBar(code.substring(2, 3));
temp=temp+oddBar(code.substring(3, 4));
temp=temp+evenBar(code.substring(4, 5));
temp=temp+evenBar(code.substring(5, 6));
temp=temp+oddBar(code.substring(6, 7));
}
break;
case "9":
{
//temp="]|x";
temp=temp+evenBar(code.substring(2, 3));
temp=temp+evenBar(code.substring(3, 4));
temp=temp+oddBar(code.substring(4, 5));
temp=temp+evenBar(code.substring(5, 6));
temp=temp+oddBar(code.substring(6, 7));
}
break;
default:
}
////Add the center guard bars & the build right half of symbol using set C (0-9)
return azalea_EAN13+opzM;
}
}
Часть журнала:
1922 [TSLVReader #1] DEBUG com.crystaldecisions.reports.formulas.Compiler - Compiling formula {@ean13}...
1922 [TSLVReader #1] INFO com.crystaldecisions.reports.formulas.Compiler - Formula {@ean13} did not compile: com.crystaldecisions.reports.formulas.FormulaException: Exception in the formulas '{@ean13}' a 'BarcodeEAN13('412345678901','567')':
the call to a function does not correspond to any overload of barcodeean13.
1922 [TSLVReader #1] WARN com.crystaldecisions.reports.reportdefinition.ReportDefinition - com.crystaldecisions.reports.formulas.FormulaException: Exception in the formulas '{@ean13}' a 'BarcodeEAN13('412345678901','567')':
the call to a function does not correspond to any overload of barcodeean13.
1923 [TSLVReader #1] ERROR com.crystaldecisions.reports.dataengine - Formula error: recompile formulas failed
com.crystaldecisions.reports.formulas.FormulaException: Exception in the formulas '{@ean13}' a 'BarcodeEAN13('412345678901','567')':
the call to a function does not correspond to any overload of barcodeean13.
at com.crystaldecisions.reports.formulas.j.a(SourceFile:3528)
at com.crystaldecisions.reports.formulas.j.a(SourceFile:3507)
at com.crystaldecisions.reports.formulas.c.a(SourceFile:1809)
at com.crystaldecisions.reports.formulas.j.a(SourceFile:3148)
at com.crystaldecisions.reports.formulas.j.a(SourceFile:295)
at com.crystaldecisions.reports.formulas.c.for(SourceFile:1225)
at com.crystaldecisions.reports.formulas.j.a(SourceFile:250)
at com.crystaldecisions.reports.formulas.j.do(SourceFile:74)
at com.crystaldecisions.reports.formulas.c.void(SourceFile:70)
at com.crystaldecisions.reports.formulas.r.a(SourceFile:90)
at com.crystaldecisions.reports.formulas.FormulaInfo.a(SourceFile:570)
at com.crystaldecisions.reports.formulas.FormulaService.compile(SourceFile:347)