I "log verbose" UEL exceptions because the spec dictates that an
exception is thrown whenever a variable isn't found - which happens a
lot in OFBiz.
The expression "orderItemShipGrpInvResAndItemLocation.GZ" would return
null if GZ isn't an element of orderItemShipGrpInvResAndItemLocation.
Let me work on this some more and I'll let you know if I find some other
options.
-Adrian
David E Jones wrote:
Also, is there any way to have UEL complain more? In this case what does
it do when it sees the reference to
"orderItemShipGrpInvResAndItemLocation.GZ"? Does it create a List object
and add it to the Map, or seeing it is part of an arithmetic expression
does it create it as some sort of numeric object? In the old stuff it
would know from context what type of object to create, and if that is
still around and it knows it should be a List then with trying to do an
arithmetic operation on a list it would be nice if it complained.
Is there any place where errors or warnings are being suppressed instead
of being thrown as exceptions... or at least logged?
-David
On Dec 15, 2008, at 2:14 PM, David E Jones wrote:
But in this case it's not missing... there is actually a Map member
(that is a List object) with the key "GZ-2644" and the simple-method
code is try to access it, so we can't just treat it as missing when it
comes back as the wrong type...
In this case, and in many cases where the FlexibleStringExpander and
FlexibleMapAccessor are used we are just trying to get the name of a
"variable" (a Map member really), and we really don't need (or want...
I don't think...) arithmetic operations. Is there any way to turn
those off?
-David
On Dec 15, 2008, at 2:07 PM, Adrian Crum wrote:
The code already expects the possibility that the object doesn't
exist and creates a new one if it's missing. The try-catch block just
treats an invalid object type as a missing object and then everything
runs the same as always.
-Adrian
David E Jones wrote:
How exactly would that fix the problem? Wouldn't it just make the
code fail, but fail with less noise... and possibly fail without any
notice at all, leading to incorrect results that the system treats
as correct.
In this case, we need the "GZ-2644" interpreted as a map key rather
than as a minus operator in the middle of an expression... and
unless there's something amazing going on here that I'm totally
missing (which I acknowledge is possible), I don't think ignoring
the type cast exception would help...
-David
On Dec 15, 2008, at 1:10 PM, Adrian Crum wrote:
David,
Thank you for the detailed description of the problem - that made
it much easier to track down.
Yes it is UEL related, and also related to weak Java code in
mini-language.
The mini-lang code causing the exception is:
<field-to-list field-name="orderItemShipGrpInvResAndItemLocation"
list-name="oiirailByProdMap.${orderItemShipGrpInvResAndItemLocation.productId}"/>
The ${orderItemShipGrpInvResAndItemLocation.productId} expression
is evaluated and returns a String - "GZ-2644". The String is
appended to orderItemShipGrpInvResAndItemLocation and the result is
"orderItemShipGrpInvResAndItemLocation.GZ-2644"
That String is handed off to the JUEL library for evaluation. I
haven't looked into the JUEL code to be sure, but I can assume JUEL
thinks that expression means "Take the
orderItemShipGrpInvResAndItemLocation.GZ variable and subtract 2644
from it." So, JUEL returns -2644.
The exception is thrown in FieldToList.java:
List<Object> toList = listAcsr.get(methodContext);
if (toList == null) {
if (Debug.verboseOn()) Debug.logVerbose("List not found with name
" + listAcsr + ", creating new list", module);
toList = FastList.newInstance();
listAcsr.put(methodContext, toList);
}
Changing that to:
List<Object> toList = null;
try {
toList = listAcsr.get(methodContext);
} catch (Exception e) {}
if (toList == null) {
if (Debug.verboseOn()) Debug.logVerbose("List not found with name
" + listAcsr + ", creating new list", module);
toList = FastList.newInstance();
listAcsr.put(methodContext, toList);
}
fixes the problem. It also makes more sense - because you can't
assume the object returned will always be a List (even without UEL).
Looking through the mini-language Java code, I see that assumption
is made a lot. I'm not sure where to go from here. Surrounding all
of the type casts with try-catch blocks would be a worthwhile
endeavor, but it is also a lot of work.
Anyways, I've made the change to most of the classes and can commit
them, but there are chances this exception might pop up elsewhere.
What do you think?
-Adrian
David E Jones wrote:
To reproduce, from latest OFBiz revision and fresh database with it:
1. in ecommerce (or Order Manager) place a sales order for 10
(anything more than 5) of product "GZ-2644"; this will cause an
inventory reservation against a bulk facility location, therefore
needing a stock move before picking the order
2. place another order for "GZ-2644" so that there are at least 2
reservations against the bulk location
3. go to the Facility -> Stock Moves tab for the facility
WebStoreWarehouse
(https://localhost:8443/facility/control/PickMoveStock?facilityId=WebStoreWarehouse)
When the page renders you'll get an error, the main exception is
(just first couple of lines):
2008-12-15 02:12:58,331 (http-0.0.0.0-8443-1) [
SimpleMethod.java:926:ERROR]
---- runtime exception report
--------------------------------------------------
Error in simple-method operation [<field-to-list
list-name="oiirailByProdMap.${orderItemShipGrpInvResAndItemLocation.productId}"
field-name="orderItemShipGrpInvResAndItemLocation" map-name=""/>]:
java.lang.ClassCastException: java.lang.Long
Exception: java.lang.ClassCastException
Message: java.lang.Long
---- stack trace
---------------------------------------------------------------
java.lang.ClassCastException: java.lang.Long
org.ofbiz.minilang.method.envops.FieldToList.exec(FieldToList.java:79)
org.ofbiz.minilang.SimpleMethod.runSubOps(SimpleMethod.java:921)
This is happening in the StockMoveServices.xml file on line 65.
Somehow the expression
"${oiirailByProdMap.${orderItemShipGrpInvResAndItemLocation.productId}"
is evaluation to "-2,644" as evidenced by adding this log
statement just before line the line 65 mentioned above:
<log level="info"
message="orderItemShipGrpInvResAndItemLocation.productId=${orderItemShipGrpInvResAndItemLocation.productId}
oiirailByProdMap
value=${oiirailByProdMap.${orderItemShipGrpInvResAndItemLocation.productId}"/>
The log shows:
2008-12-15 02:18:46,896 (http-0.0.0.0-8443-1) [
Log.java:110:INFO ] [StockMoveServices.xml#findStockMovesNeeded]
orderItemShipGrpInvResAndItemLocation.productId=GZ-2644
oiirailByProdMap value=
2008-12-15 02:18:46,897 (http-0.0.0.0-8443-1) [
Log.java:110:INFO ] [StockMoveServices.xml#findStockMovesNeeded]
orderItemShipGrpInvResAndItemLocation.productId=GZ-2644
oiirailByProdMap value=-2,644
In other words, on the second line you can see where the
expression that should return a List object instead returns a Long
object with the value of "-2,644" which appears to be the
productId GZ-2644 parsed as an integer...
Any ideas as to how this might be happening? I suspect it is an
issue with the UEL stuff Adrian recently added, since this was
working just a few days ago.
I'm guessing this is happening in other places too...
-David