Skip to content

CustomConverter refactoring #3

Description

@byzatic

Коротко: у тебя два слоя проблемы.

Корень NPE
В setDestinationField(...) при обработке List ты пытаешься вычислить класс элемента так:

destinationFieldGenericClass = Class.forName(
    destinationField.getGenericType().getTypeName()
        .replace("java.util.List<","").replace(">","")
);

Загрузка класса падает ClassNotFoundException: ...MetricLabel, из-за чего destinationFieldGenericClass == null, а затем вызывается parse(obj, null) → NPE в parse() на логировании destinationClass.getCanonicalName().

Почему ClassNotFoundException? Потому что Class.forName(...) идёт через AppClassLoader, который не видит классы твоего плагина/модуля (у тебя модульная загрузка: sharedresources + services). Класс MetricLabel реально есть, но загружен другим ClassLoader’ом.

Ещё два бага в CustomConverter

  • Логирование в самом начале parse() обращается к destinationClass до проверок на null. Это и создаёт NPE вместо внятной ошибки.
  • Ветка if (destination instanceof String) никогда не сработает (у String нет no-arg конструктора; ты уже пытался создать destination).

REASON

2025-09-01 16:11:22.015 10399 [Thread-52] WARN  i.g.b.c.c.CustomConverter [type=Service PrometheusExportService] - 
java.lang.ClassNotFoundException: io.github.byzatic.tessera.mcg3.sharedresources.project_common.dto.MetricLabel
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:375)
	at io.github.byzatic.commons.custom_converter.CustomConverter.setDestinationField(CustomConverter.java:122)
	at io.github.byzatic.commons.custom_converter.CustomConverter.setEqualField(CustomConverter.java:101)
	at io.github.byzatic.commons.custom_converter.CustomConverter.parse(CustomConverter.java:85)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.MetricsUpdateManager.updateMetrics(MetricsUpdateManager.java:48)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.PrometheusExporter$Process.run(PrometheusExporter.java:87)
	at java.base/java.lang.Thread.run(Thread.java:842)
2025-09-01 16:11:22.016 10400 [Thread-52] ERROR i.g.b.t.m.s.s.p.PrometheusExporter [] - Error updating metrics
io.github.byzatic.commons.base_exceptions.OperationIncompleteException: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.MetricsUpdateManager.updateMetrics(MetricsUpdateManager.java:53)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.PrometheusExporter$Process.run(PrometheusExporter.java:87)
	at java.base/java.lang.Thread.run(Thread.java:842)
Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.commons.custom_converter.CustomConverter.parse(CustomConverter.java:38)
	at io.github.byzatic.commons.custom_converter.CustomConverter.setDestinationField(CustomConverter.java:134)
	at io.github.byzatic.commons.custom_converter.CustomConverter.setEqualField(CustomConverter.java:101)
	at io.github.byzatic.commons.custom_converter.CustomConverter.parse(CustomConverter.java:85)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.MetricsUpdateManager.updateMetrics(MetricsUpdateManager.java:48)
	... 2 common frames omitted
2025-09-01 16:11:22.016 10400 [Thread-1] ERROR i.g.b.t.m.s.s.p.PrometheusExporter [type=Service PrometheusExportService] - Update metrics process finished with error
io.github.byzatic.commons.base_exceptions.OperationIncompleteException: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.MetricsUpdateManager.updateMetrics(MetricsUpdateManager.java:53)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.PrometheusExporter$Process.run(PrometheusExporter.java:87)
	at java.base/java.lang.Thread.run(Thread.java:842)
Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.commons.custom_converter.CustomConverter.parse(CustomConverter.java:38)
	at io.github.byzatic.commons.custom_converter.CustomConverter.setDestinationField(CustomConverter.java:134)
	at io.github.byzatic.commons.custom_converter.CustomConverter.setEqualField(CustomConverter.java:101)
	at io.github.byzatic.commons.custom_converter.CustomConverter.parse(CustomConverter.java:85)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.MetricsUpdateManager.updateMetrics(MetricsUpdateManager.java:48)
	... 2 common frames omitted
2025-09-01 16:11:22.018 10402 [Thread-1] ERROR i.g.b.t.m.s.s.d.DomainLogic [type=Service PrometheusExportService] - Domain logic error
io.github.byzatic.commons.base_exceptions.OperationIncompleteException: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.PrometheusExporter.run(PrometheusExporter.java:55)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.domain_logic.DomainLogic.process(DomainLogic.java:19)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.PrometheusExportService.run(PrometheusExportService.java:80)
	at java.base/java.lang.Thread.run(Thread.java:842)
Caused by: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.PrometheusExporter.run(PrometheusExporter.java:49)
	... 3 common frames omitted
Caused by: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.MetricsUpdateManager.updateMetrics(MetricsUpdateManager.java:53)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.PrometheusExporter$Process.run(PrometheusExporter.java:87)
	... 1 common frames omitted
Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.commons.custom_converter.CustomConverter.parse(CustomConverter.java:38)
	at io.github.byzatic.commons.custom_converter.CustomConverter.setDestinationField(CustomConverter.java:134)
	at io.github.byzatic.commons.custom_converter.CustomConverter.setEqualField(CustomConverter.java:101)
	at io.github.byzatic.commons.custom_converter.CustomConverter.parse(CustomConverter.java:85)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.MetricsUpdateManager.updateMetrics(MetricsUpdateManager.java:48)
	... 2 common frames omitted
2025-09-01 16:11:22.018 10402 [Thread-1] ERROR i.g.b.t.m.s.s.PrometheusExportService [] - Service critical error
io.github.byzatic.tessera.storageapi.exceptions.MCg3ApiOperationIncompleteException: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.domain_logic.DomainLogic.process(DomainLogic.java:22)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.PrometheusExportService.run(PrometheusExportService.java:80)
	at java.base/java.lang.Thread.run(Thread.java:842)
Caused by: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.PrometheusExporter.run(PrometheusExporter.java:55)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.domain_logic.DomainLogic.process(DomainLogic.java:19)
	... 2 common frames omitted
Caused by: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.PrometheusExporter.run(PrometheusExporter.java:49)
	... 3 common frames omitted
Caused by: io.github.byzatic.commons.base_exceptions.OperationIncompleteException: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.MetricsUpdateManager.updateMetrics(MetricsUpdateManager.java:53)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.PrometheusExporter$Process.run(PrometheusExporter.java:87)
	... 1 common frames omitted
Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.Class.getCanonicalName()" because "destinationClass" is null
	at io.github.byzatic.commons.custom_converter.CustomConverter.parse(CustomConverter.java:38)
	at io.github.byzatic.commons.custom_converter.CustomConverter.setDestinationField(CustomConverter.java:134)
	at io.github.byzatic.commons.custom_converter.CustomConverter.setEqualField(CustomConverter.java:101)
	at io.github.byzatic.commons.custom_converter.CustomConverter.parse(CustomConverter.java:85)
	at io.github.byzatic.tessera.mcg3.services.service_prometheus_export.prometheus_exporter.MetricsUpdateManager.updateMetrics(MetricsUpdateManager.java:48)
	... 2 common frames omitted
2025-09-01 16:11:22.018 10402 [Thread-1] DEBUG i.g.b.t.m.s.s.PrometheusExportService [] - healthFlagProxy FATAL -> HealthFlag{healthFlagState=HealthFlagState{code=-1}}

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions