Коротко: у тебя два слоя проблемы.
Корень 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}}
Коротко: у тебя два слоя проблемы.
Корень NPE
В setDestinationField(...) при обработке List ты пытаешься вычислить класс элемента так:
Загрузка класса падает ClassNotFoundException: ...MetricLabel, из-за чего destinationFieldGenericClass == null, а затем вызывается parse(obj, null) → NPE в parse() на логировании destinationClass.getCanonicalName().
Почему ClassNotFoundException? Потому что Class.forName(...) идёт через AppClassLoader, который не видит классы твоего плагина/модуля (у тебя модульная загрузка: sharedresources + services). Класс MetricLabel реально есть, но загружен другим ClassLoader’ом.
Ещё два бага в CustomConverter
REASON