I have a Birt report with a data set that has one computed column of the type "Java Object". This column takes it's input from the surrounding application as a Java object and later uses this exact object to calculate something.
The computed column's expression:
var result;
try {
result = application.getValueFromApplication(row["id"]);
} catch (err) {
Packages.java.lang.System.out.println("Error getting value " + row["id"] + ": " + err);
result = null;
}
However... there seems to be a bug that Birt converts these values to JavaScript values. That's stupid in the best case, but it gets even worse for numbers. Because all numbers are converted to the same stupid JavaScript "number" type. Yes, even BigDecimaland Long.
So in the above example, getValueFromApplication() returns a BigDecimal, while result is a Javascript number one.
When the time comes to start the calculation, all these values are internally converted back to Double, and now the calculation fails because it requires the value to be what the application gave the report.
So somewhere there is this snippet:
application.doMagic(row["value"]);
Where Birt tries to force it's Double down the method's throat, even though it had a BigDecimal in the beginning.
How do I prevent Birt from mindlessly converting numbers to some JavaScript blob instead of using the concrete Java class?
Related
I am trying to add two variables together. I believe both contain an integer, but when I draw what is stored within $product->mileage, I receive the following error:
A non well formed numeric value encountered
$oilchange = $request->oilchange_at_kms;
$product = Product::find($request->product_id);
$mileage = $product->mileage; // Error within this variable, but it is an int
$total = $mileage + $oilchange;
How can I test this, or how can I find the problem in my code?
This error usually pops up when you try to add an integer with a string or some type of non numeric field.
You can test this by using the PHP gettype() method:
dump(gettype($product->mileage));
dd(gettype($oilchange));
If it turns out that one of these is a string (possibly from a form response), you can cast it to an int if you are certain that the value will always be an int.
$mileage = (int)$product->mileage;
Not really recommending this, as you should try to resolve the types within the variables first, but it may help you in testing.
I pass Integer.MIN_VALUE in some Javascript that just returns the input. However, it seems that when I compare the result of the Javascript by using ScriptValueConverter.unwrapValue(returnedObject), the value is the same but the type is a double while I am expecting an integer.
However when I pass Integer.MAX_VALUE in, I do get an integer.
From what I understand, Nashorn uses optimistic type casting so in my eyes, MIN_VALUE can still be an int, there's no need for it to be a double
I suppose that the problem is not Nashorn itself but the javascript code you are running or the third party converter you are using (ScriptValueConverter is neither a javax.script nor a jdk.nashorn class).
I've run the following code:
ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName("nashorn");
jsEngine.eval("function identity(x) {return x;}");
System.out.println("Integer.MIN_VALUE:" + ((Invocable) jsEngine).invokeFunction("identity", Integer.MIN_VALUE).getClass());
System.out.println("Integer.MAX_VALUE:" +((Invocable) jsEngine).invokeFunction("identity", Integer.MAX_VALUE).getClass());
and the output is:
Integer.MIN_VALUE: class java.lang.Integer
Integer.MAX_VALUE: class java.lang.Integer
Here you can find a brief explanation about nashorn type conversions.
I have seen when coding in LINQ that when a value is assigned to a field sometimes is in this way Table["Field"] and any others like this Table.Field but can somebody explain me what's the difference please?
For example when modifying a field:
var ttAbccode_xRow =
(from ttAbccode_Row in ds.ABCCode select ttAbccode_Row).FirstOrDefault();
if (ttAbccode_xRow != null) {
ttAbccode_xRow["PI"] = 3.1416;
}
or
if (ttAbccode_xRow != null) {
ttAbccode_xRow.PI = 3.1416;
}
Accessing field via indexer (square brackets) returns object data type. That means that your compiler cannot detect data types incompatibility. You could assing for example string value (eg. "abcd") and you won't get error at design time, but as late as at runtime.
Second method (if available in your result set) is much more safe. Your property will have proper data type hence compiler will detect data types incompatibility at design time.
If I had both access methods available I would always prefer second one. It is less error prone.
i am using this code for passing datetime.
Convert.ToDateTime(textBox1.Text)
but the compiler show an error that string was not recognized as a valid datetime. so how to avoid this error and is a datetime field in my database.
Convert.ToDateTime(textBox1.Text)
This code will throw an exception if the string value in textBox1.Text doesn't represent a valid DateTime (or at least can't be parsed into one with default functionality in C#). You can add some defensive programming to handle errors like this.
The DateTime type (as well as most, if not all, common value types in .NET) has a method on it called TryParse() specifically for the purpose to attempting to parse a value into that type without throwing an exception. The method returns true if the parse was successful, false otherwise. And it accepts an out parameter to hold the resulting parsed value (or the original value if parsing is unsuccessful).
So instead of this:
var dateTimeValue = Convert.ToDateTime(textBox1.Text);
You could use something like this:
var dateTimeValue = DateTime.MinValue;
if (DateTime.TryParse(textBox1.Text, out dateTimeValue))
// use the value for something
I'm formatting a ResultSet to output to a CSV file. As such I really don't care about the Java types of the result set, beyond maybe knowing if it's text or numbers.
Does JDBC guarantee getString will always give a string representation of the values,atleast for single values (I don't need to concern myself about java.sql.Types.ARRAY,java.sql.Types.JAVA_OBJECT and a few others).
e.g. given resultSetMetaData.getColumnType(i) is a Types.FLOAT or a Types.BIGDECIMAL. will rs.GetString(i) always yield some String ?
i.e. Are there cases getString will throw an SQLException or return null when a getXXX would give me the value ?
Yup, check this : http://java.sun.com/docs/books/tutorial/jdbc/basics/retrieving.html
JDBC allows a lot of latitude as far as which getXXX methods you can use to retrieve the different SQL types. For example, the method getInt can be used to retrieve any of the numeric or character types. The data it retrieves will be converted to an int; that is, if the SQL type is VARCHAR , JDBC will attempt to parse an integer out of the VARCHAR. The method getInt is recommended for retrieving only SQL INTEGER types, however, and it cannot be used for the SQL types BINARY, VARBINARY, LONGVARBINARY, DATE , TIME, or TIMESTAMP.
But be careful, different JDBC driver may yield different result.
java.lang.String is a final class - it cannot, ever, have a subclass. So any method that returns String will either return an instance of the class java.lang.String, or a null, or throw an exception.
As for conversion, it is up to the JDBC driver if it will allow you to convert from non-String types. I suspect many will have an issue with it.
I would suggest that you do this instead:
Object item = resultSet.getObject(i);
String strValue = (item == null ? null : item.toString());
That should be more robust, since getObject() will always do the sensible thing.