You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm not 100% sure if this is a "bug", however I think its something worth pointing out.
Short Description:
I encountered an issue with ConfigSpec when working with Long values. If a Long value within a Long range is defined in a ConfigSpec, and the value is small (e.g., 500), ConfigSpec#correct(config) seems to detect an error in the config. I suspect this occurs because the value is stored as an Integer internally, resulting in a type mismatch when checked against the Long range.
Detailed Description:
This issue surfaced while implementing an auto-reloading config that includes an onAutoReload listener. This listener verifies the config’s validity using the ConfigSpec. If the config is not correct, the listener attempts to correct and save it. However, after each correction, the listener re-triggers due to the save, leading to an expected re-check. The issue is that ConfigSpec consistently finds the Long value invalid, attempts to "correct" it again to the same Long value, and saves it again. This cycle repeats indefinitely.
Below is a minimal example of the setup:
// Basic FileConfig setup with auto-reload and listener; the format used is TOML.FileConfigconfig = FileConfig.builder(configFilePath).autoreload().onAutoReload(this.autoReloadListener()).build();
config.load(); // Assuming the file is initially empty, values are null until corrected.
// ConfigSpec with a defined Long entry.ConfigSpecconfigSpec = newConfigSpec();
LongdefaultValue = this.getValue(); // Assume this returns a Long with the value 500.LongminValue = Long.MIN_VALUE;
LongmaxValue = Long.MAX_VALUE;
configSpec.defineInRange("someLongValue", defaultValue, minValue, maxValue);
// The auto-reload listener for config correction.privateRunnableautoReloadListener() {
returnthis::correctIfNeeded;
}
privatevoidcorrectIfNeeded() {
ConfigSpecconfigSpec = this.getConfigSpec();
booleanisConfigCorrect = configSpec.isCorrect(this.config);
// Handle config correction if needed.if (!isConfigCorrect) {
ConfigSpec.CorrectionListenerlistener = (action, path, incorrectValue, correctedValue) -> {
StringpathString = String.join(".", path);
System.out.println("Correction: " + pathString + " Invalid: " + incorrectValue + " Corrected: " + correctedValue);
};
intcorrectionCount = configSpec.correct(this.config, listener);
System.out.println("Adjusted " + correctionCount + " values");
// Save the corrected config to the file to apply the corrections permanently.this.config.save();
}
}
The expected behavior is:
ConfigSpec detects a null value in the config.
ConfigSpec corrects it to 500 (the default Long specified).
The corrected config is saved, triggering the listener.
On re-checking, the config should now be valid and not require further correction.
Instead, what seems to happen is that ConfigSpec interprets the small Long value (500) as an Integer, then tries to re-correct it on each check. This results in an infinite loop of corrections.
Workaround:
A workaround that I found effective is to define a custom predicate, allowing ConfigSpec to accept either Integer or Long values, and manually check if the value is within the Long range:
LongdefaultValue = this.getValue(); // Assume this returns a Long with the value 500.LongminValue = Long.MIN_VALUE;
LongmaxValue = Long.MAX_VALUE;
configSpec.define("someLongValue", defaultValue, o -> {
if (oinstanceofInteger || oinstanceofLong) {
longlongValue = ((Number) o).longValue();
returnlongValue >= minVal && longValue <= maxVal;
}
returnfalse;
});
Conclusion:
This workaround has resolved the issue, but it would be ideal if ConfigSpec could natively handle Long values correctly, regardless of the value size. This enhancement would remove the need for custom predicates when specifying ranges that span the entire Long type.
The text was updated successfully, but these errors were encountered:
I'm not 100% sure if this is a "bug", however I think its something worth pointing out.
Short Description:
I encountered an issue with
ConfigSpec
when working withLong
values. If aLong
value within aLong
range is defined in aConfigSpec
, and the value is small (e.g., 500),ConfigSpec#correct(config)
seems to detect an error in the config. I suspect this occurs because the value is stored as anInteger
internally, resulting in a type mismatch when checked against theLong
range.Detailed Description:
This issue surfaced while implementing an auto-reloading config that includes an
onAutoReload
listener. This listener verifies the config’s validity using theConfigSpec
. If the config is not correct, the listener attempts to correct and save it. However, after each correction, the listener re-triggers due to the save, leading to an expected re-check. The issue is thatConfigSpec
consistently finds theLong
value invalid, attempts to "correct" it again to the sameLong
value, and saves it again. This cycle repeats indefinitely.Below is a minimal example of the setup:
The expected behavior is:
ConfigSpec
detects anull
value in the config.ConfigSpec
corrects it to500
(the defaultLong
specified).Instead, what seems to happen is that
ConfigSpec
interprets the smallLong
value (500
) as anInteger
, then tries to re-correct it on each check. This results in an infinite loop of corrections.Workaround:
A workaround that I found effective is to define a custom predicate, allowing
ConfigSpec
to accept eitherInteger
orLong
values, and manually check if the value is within theLong
range:Conclusion:
This workaround has resolved the issue, but it would be ideal if
ConfigSpec
could natively handleLong
values correctly, regardless of the value size. This enhancement would remove the need for custom predicates when specifying ranges that span the entireLong
type.The text was updated successfully, but these errors were encountered: