Generator-jhipster: Tomcat: Broken Metrics page in 5.8.1

Created on 5 Feb 2019  Â·  27Comments  Â·  Source: jhipster/generator-jhipster

Overview of the issue

Metrics page display nothing.

Motivation for or Use Case

Because it can be interesting to have metrics.

Reproduce the error

generate the app, change nothing. Launch it by eclipse or just in a tomcat
http://localhost:8080/#/admin/jhi-metrics

We see a stack in console:
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Null key for a Map not allowed in JSON (use a converting NullKeySerializer?); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Null key for a Map not allowed in JSON (use a converting NullKeySerializer?) (through reference chain: java.util.HashMap["cache"]->java.util.HashMap["null"])
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:294)
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:102)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:272)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:180)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:119)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:891)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
...
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Null key for a Map not allowed in JSON (use a converting NullKeySerializer?) (through reference chain: java.util.HashMap["cache"]->java.util.HashMap["null"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:285)
at com.fasterxml.jackson.databind.SerializerProvider.mappingException(SerializerProvider.java:1251)
...
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:913)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:285)
... 101 common frames omitted

Related issues

No see, it's since jhipster migrate to micrometer

Suggest a Fix

the metric tomcat.cache.hit have no key because it have no tag name but have a name
So i suggest to change
JHipsterMetricsEndpoint.cacheMetrics() from:
String name = counter.getId().getTag("name");
to

String name = counter.getId().getTag("name");
if(name ==null) {
name = counter.getId().getName(); //maybe we can substring before the first dot found
}
##### **JHipster Version(s)** 5.8.1 ##### **JHipster configuration** See above ##### **JHipster Version(s)**
[email protected] H:\git\mcp\com.trululu.mcp.requirement.product.server\plugins\com.trululu.mcp.server\com.trululu.metax.requirement.server.webapp
`-- [email protected]

##### **JHipster configuration, a `.yo-rc.json` file generated in the root folder**
.yo-rc.json file
{
    "generator-jhipster": {
        "promptValues": {
            "packageName": "com.trululu.metax.requirement.server.webapp",
            "nativeLanguage": "en"
        },
        "jhipsterVersion": "5.8.1",
        "applicationType": "monolith",
        "baseName": "reqhub",
        "packageName": "com.trululu.metax.requirement.server.webapp",
        "packageFolder": "com/trululu/metax/requirement/server/webapp",
        "serverPort": "8080",
        "authenticationType": "session",
        "cacheProvider": "ehcache",
        "enableHibernateCache": true,
        "websocket": false,
        "databaseType": "sql",
        "devDatabaseType": "h2Disk",
        "prodDatabaseType": "mariadb",
        "searchEngine": false,
        "messageBroker": false,
        "serviceDiscoveryType": false,
        "buildTool": "maven",
        "enableSwaggerCodegen": false,
        "rememberMeKey": "YourJWTSecretKeyWasReplacedByThisMeaninglessTextByTheJHipsterInfoCommandForObviousSecurityReasons",
        "clientFramework": "angularX",
        "useSass": false,
        "clientPackageManager": "npm",
        "testFrameworks": ["gatling", "protractor"],
        "jhiPrefix": "jhi",
        "otherModules": [],
        "enableTranslation": true,
        "nativeLanguage": "en",
        "languages": ["en"],
        "entitySuffix": "",
        "dtoSuffix": "DTO"
    }
}

JDL for the Entity configuration(s) entityName.json files generated in the .jhipster directory


JDL entity definitions


Environment and Tools

java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

git version 2.19.0.windows.1

node: v8.12.0

npm: 6.7.0

yeoman: 2.0.5

INFO! Congratulations, JHipster execution is complete!

Entity configuration(s) entityName.json files generated in the .jhipster directory

no entity

Browsers and Operating System
  • [X] Checking this box is mandatory (this is just to show you read everything)
area server-side libraries

All 27 comments

another possible fix is to exclude tomcat cache, or to tag tomcat cache just like TomcatMetricsAutoConfiguration but add a tag:

        @Bean
    @ConditionalOnMissingBean
    public TomcatMetrics tomcatMetrics() {
        return new TomcatMetrics(
                (this.context != null) ? this.context.getManager() : null,
                Arrays.asList(Tag.of("name","tomcat"));
    }

Hi ! Thank you for reporting the issue !

Considering first option, I fear that the format of the response would be different as the one expected by the front end part.

"cache" : {
    "usersByEmail" : {
      "cache.gets.miss" : 0.0,
      "cache.puts" : 0.0,
      "cache.gets.hit" : 0.0,
      "cache.removals" : 0.0,
      "cache.evictions" : 0.0
    },
    "com.trululu.metax.requirement.server.webapp.domain.PersistentToken" : {
      "cache.gets.miss" : 0.0,
      "cache.puts" : 0.0,
      "cache.gets.hit" : 0.0,
      "cache.removals" : 0.0,
      "cache.evictions" : 0.0
    }
    ...
}

But would be something like :

"cache" : {
    "cache.gets" : {
      "cache.gets.miss" : 0.0,
      "cache.gets.hit" : 0.0,
    },
    ...
}

It would also be less meaningful, IMO. So there is maybe a better way to do it.

Concerning the second option, some infos would be lost, so it is also something that bother me...

I missed something in your last comment ! Tagging tomcat cache could be the best option. WDYT @PierreBesson ?

@clement26695, sorry I don't understand the issue so I'm counting on you to reproduce and fix it...

My first proposale is just like a seat belt. In case of missing tag name. it was orthogonal to my other proposale, so we can implement the first and tag the tomcat too.

To be more clear, my json response is:

"cache" : {
    "usersByEmail" : {
      "cache.gets.miss" : 0.0,
      "cache.puts" : 0.0,
      "cache.gets.hit" : 0.0,
      "cache.removals" : 0.0,
      "cache.evictions" : 0.0
    },
    "com.trululu.metax.requirement.server.webapp.domain.PersistentToken" : {
      "cache.gets.miss" : 0.0,
      "cache.puts" : 0.0,
      "cache.gets.hit" : 0.0,
      "cache.removals" : 0.0,
      "cache.evictions" : 0.0
    },
    null : {
      "tomcat.cache.hit" : 0.0,
       ...
    },
...

Just tested this configuration, and I don't have this "tomcat.cache.hit".
I started the application, using ./mvnw

I have it when i launch from STS and run as Spring Boot Application
this one use tomcat instead of undertow

You said:

Launch it by eclipse or maven

Because I tested with maven, there is no problem. So the issue comes from Eclipse, and I think it is not related to JHipster.

yes it's a mistake, i update the description. But I test all fix list above and it's work. So it's a tomcat spring boot metric bug not an eclipse bug.

Or at least an documentation / integration issue : all metric must have a tag name, if not, jhipster crash. In my opinion, we must ignore or log something. But do nothing and crash a wall end point is really enoying

Yes, I manage to reproduce the bug when launching the app on tomcat. I didn't had the time to test your fixes yet

Ok guys, don't hesitate to apply the fix, if you have one!

Would you be ok to make a PR to apply the fix, @Dufgui ?

So wich PR do you want ?

  • [ ] Tomcat init (in jhispter)
  • [ ] Tomcat init (propose a PR in spring-boot)
  • [ ] JHipsterMetricsEndpoint.cacheMetrics() get start of full name in all case (not a good idea i think)
  • [x] JHipsterMetricsEndpoint.cacheMetrics() log and ignore when tag name missing
  • [ ] JHipsterMetricsEndpoint.cacheMetrics() get start of full name when tag name missing
  • [ ] any other fix i don't think ?

In retrospect, I would go with the 4th option, as we won't display these metrics correctly on the Metrics page anyway.

ok for me, if there is no reply wich suggest other choice since this evening, i will do my PR this night ;o)

Looks fine for me !

@Dufgui @clement26695 PR in jhipster lib has been merged.
Please confirm if it can be closed?
Thanks

yes it can

On Sat, Feb 9, 2019 at 1:58 AM Daniel Franco notifications@github.com
wrote:

@Dufgui https://github.com/Dufgui @clement26695
https://github.com/clement26695 PR in jhipster lib has been merged.
Please confirm if it can be closed?
Thanks

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/jhipster/generator-jhipster/issues/9195#issuecomment-461996301,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAOemxDJfUCt5pEVi40jEkNi_XpLkgcZks5vLh0cgaJpZM4ajUcv
.

Hi @Dufgui @clement26695 @PierreBesson , if i don't want to upgrade my project, how can I do to fix this issue?

@Bean
@ConditionalOnMissingBean
public TomcatMetrics tomcatMetrics() {
return new TomcatMetrics(
(this.context != null) ? this.context.getManager() : null,
Arrays.asList(Tag.of("name","tomcat"));
}

Cf my previous comment

Is this released? I'm getting the same error in 5.8.2.

I think it was just included in the 6.0.0 version, unfortunately, but the fix provided by @Dufgui should work

@bean
@ConditionalOnMissingBean
public TomcatMetrics tomcatMetrics() {
return new TomcatMetrics(
(this.context != null) ? this.context.getManager() : null,
Arrays.asList(Tag.of("name","tomcat"));
}

Cf my previous comment

How implement this solution, please be more specific, need help

create a @Configuration wich expose this bean.
The @Configuration class must be scanned by spring boot.

But It's an old bug, maybe it's another metrics wich block you today. You must debug to find which one, if my fix does n t work for you

create a @configuration wich expose this bean.
The @configuration class must be scanned by spring boot.

But It's an old bug, maybe it's another metrics wich block you today. You must debug to find which one, if my fix does n t work for you

sorry for the inconvenience but what is the import of context

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lsadehaan picture lsadehaan  Â·  3Comments

frantzynicolas picture frantzynicolas  Â·  3Comments

pascalgrimaud picture pascalgrimaud  Â·  3Comments

kaidohallik picture kaidohallik  Â·  3Comments

dronavallisaikrishna picture dronavallisaikrishna  Â·  3Comments