Project

General

Profile

Defect #1364

Executing a function with an integer parameter appears to evaluate to a floating number

Added by Joe Collins over 5 years ago. Updated over 5 years ago.

Status:
New
Priority:
Normal
Assignee:
-
Start date:
08/23/2018
Due date:
% Done:

0%

Estimated time:
Browser (if web client):

Description

BarTender operates with an OLE COM interface among others.

When the GetDatabase(index) function is executed, an integer index or a database name for a label template will return a database object.

Setting up the databases within a label template:

var DBs = format.getChildJSCOM("Databases");
The correct response when using the known database name of 'barcodelabel':
=>DBs.call('GetDataBase','barcodelabel')
com.jacob.com.Dispatch@45be1754
=>DBs.getChildJSCOM('GetDataBase',['barcodelabel'])
com.servoyguy.plugins.servoycom.RemoteCOM@43c8d419
=>

Then executing either of:

DBs.getChildJSCOM('GetDataBase',[1]) OR
DBs.call('GetDatabase',1)

The error returns from a DBs.getLastError() from the COM object:
"com.jacob.com.ComFailException: Invoke of: GetDataBase
Source: BarTend
Description: Cannot find database 1.000000.
"

It does reference the string and real values:
=>DBs.call('GetDataBase','2')
null
=>DBs.getLastError()
"com.jacob.com.ComFailException: Invoke of: GetDataBase
Source: BarTend
Description: Cannot find database 2.
"

=>DBs.call('GetDataBase',2)
null
=>DBs.getLastError()
"com.jacob.com.ComFailException: Invoke of: GetDataBase
Source: BarTend
Description: Cannot find database 2.000000.
"

=>DBs.call('GetDataBase',2.1)
null
=>DBs.getLastError()
"com.jacob.com.ComFailException: Invoke of: GetDataBase
Source: BarTend
Description: Cannot find database 2.100000.
"

=>DBs.call('GetDataBase',2.0)
null
=>DBs.getLastError()
"com.jacob.com.ComFailException: Invoke of: GetDataBase
Source: BarTend
Description: Cannot find database 2.000000.
"

=>DBs.call('GetDataBase',2.123456789)
null
=>DBs.getLastError()
"com.jacob.com.ComFailException: Invoke of: GetDataBase
Source: BarTend
Description: Cannot find database 2.123457.
"

=>DBs.call('GetDataBase','2.123456789')
null
=>DBs.getLastError()
"com.jacob.com.ComFailException: Invoke of: GetDataBase
Source: BarTend
Description: Cannot find database 2.123456789.
"

It appears that the integer is coming across as a real.

Is there a way to force an argument to another type?

Thanks,
--Joe.

History

#1

Updated by Scott Butler over 5 years ago

The Jacob library does mapping through Variant class. Example here: https://github.com/joval/jacob/blob/master/src/com/jacob/com/VariantUtilities.java

You might try passing in a java object instead of JS object. Like: DBs.call('GetDataBase', new Packages.java.lang.Integer(1))
and play around with some different java classes til you find the matching one it wants.

#2

Updated by Joe Collins over 5 years ago

It looks like the argument must be a VariantInt type. Random searching isn't producing correct results.

Mostly the result returned is

"com.jacob.com.NotImplementedException:
populateVariant () not implemented for class
org.mozilla.javascript.NativeNumber"

I've tried inserting numbers to the COM object, and this produces

"Error during evaluation:
Can't find method com.servoyguy.plugins.servoycom.RemoteCOM.getChildJSCOM (string,number)."

It really desires a String arguments.

Reading the code, a return from some java package requires a Variant.VariantInt type.

There might be a callable utility class in this package, and the search rages on. Certainly, this problem has come and gone before.

#3

Updated by Scott Butler over 5 years ago

I see a ticket related here: https://www.servoyforge.net/issues/655 and we introduced the getChildCOM to fix it.
I also see a forum post using the COM plugin with BarTender here: http://forum.servoy.com/viewtopic.php?f=15&t=20946 (not sure if that was your post?)

on getChildJSCom, it wants an array for the arguments, so would try something like:
getChildJSCOM('GetDataBase', [new Packages.java.lang.Integer(1)])

#4

Updated by Scott Butler over 5 years ago

Also, i'm assuming this is the library you are connecting with? http://help.seagullscientific.com/2016/de/Subsystems/ActiveX/Content/GetDatabase_Method.htm

if so, it seems to show it supports a string or an integer, so those should go through fine. Wondering if there is some different issue causing this? It also shows you can get by name. not sure if that helps.

'Alternatively, use the database's Name property if it is known
'btDb = btFormat.Databases.GetDatabase("bikes")

#5

Updated by Joe Collins over 5 years ago

That is correct. It is the GetDatabase method.

In the above examples, the integer is resolving to a real number which the function is seeking as a Database name.

getChildJSCOM('GetDataBase','1') sends String '1'
getChildJSCOM('GetDataBase',1) sends Real 1.000000
getChildJSCOM('GetDataBase',2.123456789) sends String '2.123456789'
getChildJSCOM('GetDataBase',2.123456789) sends Real 2.123456' not a valid index, but shows that Reals are interpreted as a name, not an index.

getChildJSCOM('GetDataBase',['barcodelabel']) sends String 'barcodelabel', so yes the name works.

In either 'call' or 'getChildJSCOM', the integer is being interpreted as Real, and then as a String, since it is not an integer. Strongly typed due to nature of programming language they chose?

In each case, it returns 'Cannot find database', unless the real database name is requested instead of an index.

I could use a real database name, if I knew it beforehand. The database name varies by template and, programmatically, the database is not known in advance but generally there is only 1 database in the template. Without knowing the database name, I cannot retrieve the database properties needed to execute a label print through the COM interface. I must use the index into the database name. It works fine from FoxPro, so it is a tried and true interface for the GetDatabase call.

For some reason, the library is sending a real number to the GetDatabase function.

I have a call in with Seagull Scientific to discuss the issue, as well. And check for resolution on that side.

#6

Updated by Scott Butler over 5 years ago

Their docs state the index can be a string or number, so maybe try it as a string.

Databases.GetDatabase(Index)
Where Index can be either an integer or a string specifying the database name.

Parameters in getChildJSCOM to the COM are always passed in as an array, so it would be:
getChildJSCOM('GetDataBase', ['1'])

The methods available are:
getChildJSCOM(String key)
getChildJSCOM(String key, Object[] value)
getChildJSCOM(String key,String progID, Object[] values)

so the values for parameters are always in an array. If you pass something besides an array, its going to use it as the progID in the getChildJSCOM function. Keep in mind thats different than the call function, so if you do comObject.call(methodName, arg1, arg2, ect) the arguments get passed separately. However with getChildJSCOM the args are in the array.

PS. You might try it as numeric as well, as maybe the issue is just that you weren't using an array, like: getChildJSCOM('GetDataBase', [1])

#7

Updated by Joe Collins over 5 years ago

That was the first of many attempted permutations.

Have even tried call (GetDatabase,'1') and other variations.

Even with a non-array, the function is still aware of the Database search name, but doesn't resolve as an index.
Result

"Cannot find database 1.
"

#8

Updated by Joe Collins over 5 years ago

I did further testing, and have asked the community if they've encountered this issue. No response yet.

The COM server is particular about a database name versus a database index. If the index is not an integer, it is resolved to be a String which locates the database name, based on the index passed into the COM Server, from the COM bridge which is a Real number. There is no database name represented by the generated Real number index string. There is a request open with Seagull Scientific, but no response yet.

If an index is specified as an integer, always an integer 1 in my case, the COM Server gets 1.000000, and the COM server says database 1.000000 cannot be found. There will not be an index > 1 into the label database above. So index = 2 cannot be tested.

If an index is specified as a String, '1', the COM Server generates the 'cannot find database 1' error.

If an existing database name is entered, then it returns the database object for that name. Yup, that one works.
=>DBs.getChildJSCOM('GetDataBase','',['barcodelabel'])
com.servoyguy.plugins.servoycom.RemoteCOM@52f8cb16

if a (bad) index number of 1.2345678910 is provided, then the database '1.234567' cannot be found.

if a non-existent database name of 1.234567890 is provided, then the database '1.234567890' cannot be found.

That's why it is convincing the Int_to_Real and Real_to_String issue occurs.

It may be that the COM bridge needs an argument of type Variant.VariantInt. Sending something cast to a Number fails since the arguments reject the type Number as an argument type.

In addition, while in the console, typing

=>someVariable = 1
1.0
=>someVariable = 2
2

Is this normal?

If the environment is always giving me a Real number for an integer 1, how is an integer to be passed into any call in the COM bridge? I did test this by passing an array index which resolves to 1 not 1.0.

Also, there's no way of knowing why an integer of two is returned as a 'database not found' by the COM server unless it becomes an invalid index, so an additional attempt is made as a String entry repping as a database name...

So it is being passed an integer, but still changed to Real.

In the code, the check for a Real value is done prior to the Integer value, but the VariantReal test should have thrown an error and proceeded onto the next try...catch following it. Just hoping an ordering of the variant tests may be responsible.

Among the responses:

-------------------------------------------------------------------------------------------------
=>DBs.getChildJSCOM('GetDataBase',[new Packages.java.lang.Integer(1)])//First argument list
null
=>DBs.getLastError()
com.jacob.com. NotImplementedException : populateVariant () not implemented for class org.mozilla.javascript.NativeNumber
-------------------------------------------------------------------------------------------------
=>DBs.call('GetDataBase',new Packages.java.lang.Integer(1))
null
=>DBs.getLastError()
com.jacob.com. NotImplementedException: populateVariant () not implemented for class org.mozilla.javascript.NativeNumber
-------------------------------------------------------------------------------------------------
=>DBs.getChildJSCOM('GetDataBase','',[new Packages.java.lang.Integer(1)])//Second argument list with progId blank
null
=>DBs.getLastError()
com.jacob.com. NotImplementedException: populateVariant() not implemented for class org.mozilla.javascript.NativeNumber
-------------------------------------------------------------------------------------------------
=>DBs.getChildJSCOM("GetDatabase",'',[Math.ceil('1')])
null
=>DBs.getLastError()
"com.jacob.com.ComFailException: Invoke of: GetDatabase
Source: BarTend
Description: Cannot find database 1.000000."
-------------------------------------------------------------------------------------------------
=>m = [0,1]
[0.0,1.0]
=>m.indexOf(1)
1
=>DBs.call('GetDatabase',m.indexOf(1))
null
=>DBs.getLastError()
"com.jacob.com.ComFailException: Invoke of: GetDatabase
Source: BarTend
Description: Cannot find database 1.000000."
-------------------------------------------------------------------------------------------------
=>DBs.getChildJSCOM('GetDatabase',[m.indexOf(1)]) //
null
=>DBs.getLastError()
"com.jacob.com.ComFailException: A COM exception has been encountered:
At Invoke of: GetDatabase
Description: The parameter is incorrect."
-------------------------------------------------------------------------------------------------

Also available in: Atom PDF