gama-platform/gama.old

Json File with long int value throw exception of Number Format

hqnghi88 opened this issue · 6 comments

Working with json_file, i cant access the file content as the processing of content throw an exception. For example, with the Json Import data in library, change the input data (cityIO.json) to content a long int, ie: 85685870492000000
Launch the model and get the error message:
java.lang.NumberFormatException: For input string: "85685870492000000"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:668)
at msi.gama.util.file.json.JsonInt.asInt(JsonInt.java:87)
at msi.gama.util.file.json.JsonInt.toGamlValue(JsonInt.java:166)
at msi.gama.util.file.json.JsonInt.toGamlValue(JsonInt.java:1)
at msi.gama.util.file.json.JsonAbstractObject.toMap(JsonAbstractObject.java:638)
at msi.gama.util.file.json.JsonObject.toGamlValue(JsonObject.java:60)
at msi.gama.util.file.json.JsonObject.toGamlValue(JsonObject.java:1)
at msi.gama.util.file.json.JsonArray.toGamlValue(JsonArray.java:447)
at msi.gama.util.file.json.JsonArray.toGamlValue(JsonArray.java:1)
at msi.gama.util.file.json.JsonAbstractObject.toMap(JsonAbstractObject.java:638)
at msi.gama.util.file.json.JsonObject.toGamlValue(JsonObject.java:60)
at msi.gama.util.file.json.JsonObject.toGamlValue(JsonObject.java:1)
at msi.gama.util.file.GamaJsonFile.fillBuffer(GamaJsonFile.java:109)
at msi.gama.util.file.GamaFile.getContents(GamaFile.java:473)
at msi.gama.util.file.GamaFile.getContents(GamaFile.java:1)
at gaml.additions.core.GamlAdditions.lambda$249(GamlAdditions.java:318)
at msi.gaml.expressions.operators.UnaryOperator._value(UnaryOperator.java:106)
at msi.gaml.expressions.AbstractExpression.value(AbstractExpression.java:81)
at msi.gama.runtime.ExecutionScope.evaluate(ExecutionScope.java:623)
at msi.gaml.variables.Variable.initializeWith(Variable.java:678)
at msi.gama.metamodel.population.GamaPopulation.createVariablesFor(GamaPopulation.java:613)
at msi.gama.kernel.simulation.SimulationPopulation.initSimulation(SimulationPopulation.java:190)
at msi.gama.kernel.simulation.SimulationPopulation.createAgents(SimulationPopulation.java:150)
at msi.gama.metamodel.population.IPopulation.createAgents(IPopulation.java:231)
at msi.gama.kernel.experiment.ExperimentAgent.createSimulation(ExperimentAgent.java:489)
at msi.gama.kernel.experiment.ExperimentAgent.init(ExperimentAgent.java:383)
at msi.gama.metamodel.agent.MinimalAgent.init(MinimalAgent.java:242)
at msi.gama.kernel.experiment.ExperimentAgent.init(ExperimentAgent.java:445)
at msi.gama.runtime.ExecutionScope.init(ExecutionScope.java:602)
at msi.gama.kernel.experiment.DefaultExperimentController.schedule(DefaultExperimentController.java:190)
at msi.gama.kernel.experiment.ExperimentAgent.schedule(ExperimentAgent.java:519)
at msi.gama.kernel.experiment.ExperimentPlan.open(ExperimentPlan.java:718)
at msi.gama.kernel.experiment.ExperimentPlan.open(ExperimentPlan.java:776)
at msi.gama.kernel.experiment.DefaultExperimentController.processUserCommand(DefaultExperimentController.java:72)
at msi.gama.kernel.experiment.AbstractExperimentController.lambda$0(AbstractExperimentController.java:63)
at java.base/java.lang.Thread.run(Thread.java:833)
Seems the parseInt here cant handle the long int value.
Screenshot 2023-12-16 at 08 38 23
I make a trick to replace Integer.parseInt by Long.parseLong

So can you commit your changes if it works ? Or do you think it might break something else ?

The solution proposed is removing the exception, but not solving the problem, which is that we do not have long values in GAMA. So, either

  1. we truncate to int, somewhat arbitrarily, the value obtained using either Double.parseDouble() or Long.parseLong(), knowing that we obtain a totally different number in both cases:
    double to int: 2147483647
    long to int: 1626480384
  2. or we consider this number is a double (and not an int), which is what other parsers are doing (see for instance https://json.nlohmann.me/features/types/number_handling/). In that case, the GAML value will be a float and not an int.

I would be in favor of the second solution, although it requires tweaking the parser a little bit more than doing a "simple" casting.

Or simply keep it as string?
It was introduced after the official release of 1.9.2 (the version downloaded from website works well) so at least we need to overcome the exception on the next release?

I'm also in favour of switching to a float, we might lose some precision but at least it's a number type.
I can understand the need to get the exact data sent though, maybe we can introduce a parameter to pick which behaviour to do in case of overflow ?
In any case I think it must be documented somewhere as both of those behaviours could be really unexpected

Introducing a preference to know what to do in case of int overflow (convert to float or to string) in files / messages is not a bad idea (better than a parameter, as it could also apply to other file types, like csv, etc. and also network messages). We should probably open a new issue for that, listing the contexts in which this preference could apply.

closing as the initial issue has been solved and the second point raised has its own issue (#3956)