Skip to content

Commit e7a87ab

Browse files
committed
ClassUtils: avoid overflow when injecting params
When Context.inject(Object) is called to inject parameters, it uses ClassUtils.setValue, which calls the deprecated ConversionUtils.convert, which leans on the statically linked ConvertService, which needs to lazily load its Converter singleton plugins, which needs to inject those singleton plugins with a context, which calls Context.inject(Object)... To avoid this loop, this commit makes ClassUtils.setValue only call the ConversionUtils.convert method as needed, rather than always. And in the case of parameter injection, the types will always be compatible and hence conversion will never be needed. The cross-dependency between ClassUtils and ConversionUtils was always suboptimal and now it finally bit us. In the near future, we will need to deprecate ClassUtils.setValue in favor of a setFieldValue method of the ConvertService.
1 parent 4687d10 commit e7a87ab

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

src/main/java/org/scijava/util/ClassUtils.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,14 +424,24 @@ public static Object getValue(final Field field, final Object instance) {
424424
*
425425
* @throws IllegalArgumentException if the value cannot be set.
426426
*/
427+
// FIXME: Move to ConvertService and deprecate this signature.
427428
public static void setValue(final Field field, final Object instance,
428429
final Object value)
429430
{
430431
try {
431432
field.setAccessible(true);
432-
final Type fieldType =
433-
GenericUtils.getFieldType(field, instance.getClass());
434-
field.set(instance, ConversionUtils.convert(value, fieldType));
433+
final Object compatibleValue;
434+
if (field.getType().isInstance(value)) {
435+
// the given value is compatible with the field
436+
compatibleValue = value;
437+
}
438+
else {
439+
// the given value needs to be converted to a compatible type
440+
final Type fieldType =
441+
GenericUtils.getFieldType(field, instance.getClass());
442+
compatibleValue = ConversionUtils.convert(value, fieldType);
443+
}
444+
field.set(instance, compatibleValue);
435445
}
436446
catch (final IllegalAccessException e) {
437447
throw new IllegalArgumentException("No access to field: " +

0 commit comments

Comments
 (0)