Question

I'm using the jtopen/jt400 toolkit to call programs on an IBM i-series r5v4 (aka AS/400) from Java (actually: JRuby, but I've seen the same problem in pure Java). This works just fine for some programs, while for other programs, the output bytes contain all zeroes, which is just wrong and sometimes even invalid (for instance in case of a ZonedDecimal). There are no Messages attached to the ProgramCall, in the JobList or on the SYSOPR.MSGQ. Does anyone know why this happens?

To show some code (I'm sure anyone that has worked with the library can understand this Ruby rendering of the Java):

as400 = AS400.new(host, user, password)
call = ProgramCall.new(as400)
call.program = "/QSYS.LIB/LIBRARY_NAME.LIB/PROGRAM_NAME.PGM"

# Prepare converters
text1_converter = AS400Text.new(1)
text3_converter = AS400Text.new(3)
decimal92_converter = AS400ZonedDecimal.new(11, 2)

# Prepare parameters
call.parameter_list = []

# Input parameters
call.parameter_list << ProgramParameter.new(text1_converter.to_bytes('N'))
call.parameter_list << ProgramParameter.new(decimal92_converter.to_bytes(1500.25))

# Output parameters
call.parameter_list << ProgramParameter.new(text3_converter.byte_length)
call.parameter_list << ProgramParameter.new(decimal92_converter.byte_length)  

# Execute the call    
call.run

# Show the results
puts "Text3 output value: " + text3_converter.to_object(params[2].output_data).to_s
puts "Decimal92 output value: " + decimal92_converter.to_object(params[3].output_data).to_s

As I said, this works just fine for some programs, while for others, params[2].output_data will be a byte array of [0, 0, 0], which is not the intended results. Even worse, params[3].output_data will be [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], which are invalid byte values for a ZonedDecimal.new(9, 2). Can anyone help me out?

Was it helpful?

Solution

It turns out you must always set a valid input_data on the output parameters, even when the values are not used anywhere. If you don't, they will not be initialized and they will contain garbage (but often the memory locations will contain zeroes, as in my case). If the program subsequently doesn't explicitly set the output values, which happened to be the case for my choice of input parameters, then the dictum garbage in equals garbage out holds.

Of course, defensive programming suggests that the programmer initializes such values or makes sure they are set in every path that can be taken through the code, which would have prevented this problem from occurring in the first place. However, it seems the contract is to always set values on the output parameters, so I was wrongly using the API.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top