On Sun, 7 Apr 2019, Petrus Hyvönen wrote:
Hi,
I am getting inconsistent results and think I may be onto something. I am
doing builds both locally and in a online build server, where there should
be no old versions around. But both locally and there the results between
different runs varies even on same platforms. Sometimes I get the right
return type and for some builds and the same function returns its parents
for other build (same platform).
I have looked at the generated code and there seems to be a difference in
the order of the parameter checking from the working vs non-working (no big
statistical ground however).
For the working one, the child class type is checked before the parent.
Could it be that the parseArgs function gets a positive match when
comparing child with the parent?
I think I understand what's going on but I'm not sure and having a small
piece of code to reproduce the problem would help.
Namely, when you have more than one overload for a given method that is
valid for a given call then the order in which they're considered is
probably (I didn't check) in the order the method signatures were returned
by Java during the JCC compile. JCC sorts the overloads by number of args
but then *does not* sort them by, say, lowest subclass in the tree first.
This could be tricky, or even undecidable (or make things slower at runtime
by trying to find the lowest match based on your python call - at the
moment, the first valid match is returned).
It is a bug for it to be random, however, so I think I should be able to get
JCC to always succeed or fail in the same way, and not let the order of
methods as returned by Java during compilation by JCC determine the
behaviour.
I could be wrong about this (the order returned by Java could be
deterministic and well chosen and later broken by JCC, for example, I didn't
yet check).
You can help in getting this resolved by creating a small example that
exhibits this bug (multiple overloads of a method that differ only in which
piece of a subclass tree is used).
You can also workaround this problem by using different method names to
avoid such confusion with overloads (if that is indeed the problem).
Andi..
Faulty return type (returns PVCoordinates type on TimeStampedPVCoordinates
input)
::org::orekit::utils::PVCoordinates a0((jobject) NULL);
::org::orekit::utils::PVCoordinates result((jobject) NULL);
if (!parseArgs(args, "k",
::org::orekit::utils::PVCoordinates::initializeClass, &a0))
{
OBJ_CALL(result = self->object.transformPVCoordinates(a0));
return ::org::orekit::utils::t_PVCoordinates::wrap_Object
(result);
}
}
{
::org::orekit::utils::TimeStampedPVCoordinates a0((jobject) NULL
);
::org::orekit::utils::TimeStampedPVCoordinates result((jobject)
NULL);
if (!parseArgs(args, "k",
::org::orekit::utils::TimeStampedPVCoordinates::initializeClass, &a0))
{
OBJ_CALL(result = self->object.transformPVCoordinates(a0)); //
Här är det det räknas ut
return ::org::orekit::utils::t_TimeStampedPVCoordinates::
wrap_Object(result);
}
}
And corresponding code in a build that works: (TimeStampedPVCoordinates as
parameter gets return type TimeStampedPVCoordinates)
static PyObject *t_Transform_transformPVCoordinates(t_Transform *self,
PyObject *args)
{
switch (PyTuple_GET_SIZE(args)) {
case 1:
{
::org::orekit::utils::FieldPVCoordinates a0((jobject) NULL);
PyTypeObject **p0;
::org::orekit::utils::FieldPVCoordinates result((jobject) NULL);
if (!parseArgs(args, "K",
::org::orekit::utils::FieldPVCoordinates::initializeClass, &a0, &p0,
::org::orekit::utils::t_FieldPVCoordinates::parameters_))
{
OBJ_CALL(result = self->object.transformPVCoordinates(a0));
return ::org::orekit::utils::t_FieldPVCoordinates::wrap_Object(result);
}
}
{
::org::orekit::utils::TimeStampedPVCoordinates a0((jobject) NULL);
::org::orekit::utils::TimeStampedPVCoordinates result((jobject) NULL);
if (!parseArgs(args, "k",
::org::orekit::utils::TimeStampedPVCoordinates::initializeClass, &a0))
{
OBJ_CALL(result = self->object.transformPVCoordinates(a0));
return ::org::orekit::utils::t_TimeStampedPVCoordinates::wrap_Object
(result);
}
}
{
::org::orekit::utils::TimeStampedFieldPVCoordinates a0((jobject) NULL);
PyTypeObject **p0;
::org::orekit::utils::TimeStampedFieldPVCoordinates result((jobject) NULL);
if (!parseArgs(args, "K",
::org::orekit::utils::TimeStampedFieldPVCoordinates::initializeClass, &a0,
&p0, ::org::orekit::utils::t_TimeStampedFieldPVCoordinates::parameters_))
{
OBJ_CALL(result = self->object.transformPVCoordinates(a0));
return ::org::orekit::utils::t_TimeStampedFieldPVCoordinates::wrap_Object
(result);
}
}
{
::org::orekit::utils::PVCoordinates a0((jobject) NULL);
::org::orekit::utils::PVCoordinates result((jobject) NULL);
if (!parseArgs(args, "k",
::org::orekit::utils::PVCoordinates::initializeClass, &a0))
{
OBJ_CALL(result = self->object.transformPVCoordinates(a0));
return ::org::orekit::utils::t_PVCoordinates::wrap_Object(result);
}
}
}
I guess there could be a zillion other reasons as well, but this would fit
with the random character on when it would work.
I have tried to understand the parseArgs function but it is hard.
Any comments welcome...
With Best Regards
/Petrus
On Sat, Apr 6, 2019 at 3:58 AM Andi Vajda <va...@apache.org> wrote:
Are you sure you're running the code you think you're running ? Your
description sounds like an old version of something may be picked up
instead.
Andi..
On Apr 5, 2019, at 15:04, Petrus Hyvönen <petrus.hyvo...@gmail.com>
wrote:
Hi,
I am having some confusing time with a wrapped class.
The class "Transform" has a function transformPVCoordinates() that has
different options for input parameters. One of these are
TimeStampedPVCoordinates. It is supposed to return a
TimeStampedPVCoordinates object but returns instead a PVCoodinates object
that is its parent class. I cannot cast this to TimeStampedPVCoordinates,
gets an error. On most systems. On python 2.7 it works and only 3.6 under
linux (testing for max, linux and win). It worked also in Python 3.7 on
mac/windows for the JCC 3.0 version.
I've checked the code being generated, and the return type and parameter
type of TimeStampedPVCoord are there, both in c code and .h file.
How/where is the matching of parameters from python call done? I get a
feeling that the parent class is somehow used, but not shure how to
troubleshoot this...
Best Regards
/Petrus
--
_____________________________________________
Petrus Hyvönen, Uppsala, Sweden
Mobile Phone/SMS:+46 73 803 19 00
--
_____________________________________________
Petrus Hyvönen, Uppsala, Sweden
Mobile Phone/SMS:+46 73 803 19 00