jersey
  1. jersey
  2. JERSEY-2053

JMX Monitor Feature Bugs in ApplicationMXBeanImpl

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.2
    • Fix Version/s: 2.5
    • Component/s: core
    • Labels:
      None
    • Environment:

      java 1.7

      Description

      when i enable the MonitoringFeature by adding following configuration code:

      property(ServerProperties.MONITORING_STATISTICS_ENABLED, true);
      property(ServerProperties.MONITORING_STATISTICS_MBEANS_ENABLED, true);

      and running the application in jetty container(jetty-9.0.5.v20130815 & java 1.7.0_15). the following exception will always be thrown.

      10:14:01.761 [jersey-background-task-scheduler-0] ERROR o.g.j.s.i.m.MonitoringStatisticsProcessor - Exception thrown when provider class org.glassfish.jersey.server.internal.monitoring.jmx.MBeanExposer was processing MonitoringStatistics. Removing provider from further processing.
      java.util.ConcurrentModificationException: null
      at java.util.HashMap$HashIterator.nextEntry(HashMap.java:894) ~[na:1.7.0_15]
      at java.util.HashMap$EntryIterator.next(HashMap.java:934) ~[na:1.7.0_15]
      at java.util.HashMap$EntryIterator.next(HashMap.java:932) ~[na:1.7.0_15]
      at org.eclipse.jetty.util.MultiMap.toString(MultiMap.java:310) ~[na:na]
      at org.glassfish.jersey.server.internal.monitoring.jmx.ApplicationMXBeanImpl.<init>(ApplicationMXBeanImpl.java:96) ~[jersey-server-2.2.jar:na]
      at org.glassfish.jersey.server.internal.monitoring.jmx.MBeanExposer.onStatistics(MBeanExposer.java:161) ~[jersey-server-2.2.jar:na]
      at org.glassfish.jersey.server.internal.monitoring.MonitoringStatisticsProcessor$1.run(MonitoringStatisticsProcessor.java:122) ~[jersey-server-2.2.jar:na]
      at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_15]
      at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351) [na:1.7.0_15]
      at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178) [na:1.7.0_15]
      at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178) [na:1.7.0_15]
      at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.7.0_15]
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_15]
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_15]
      at java.lang.Thread.run(Thread.java:722) [na:1.7.0_15]

      after debug it quite awhile, i see it was caused by the iteration logical of ApplicationMXBeanImpl when it want to get all properties from ResourceConfig(applicationStatistics.getResourceConfig(). because the properties entry contains some value that outside of jersey kernel, so directly call the value's toString method will throwing the exception.

      so it may be reasonable to check whether the entry key is the string begin with "org.glassfish.jersey.*".

      BTW: i remember the Gzip Filter modules in jersey 1.x are exist. but in 2.x, there is only a client side EncodingFilter. where is Gzip Filter in server side?(eg, it will encoding the server output when client request's http header contains Accept-Encoding:gzip)

        Activity

        Hide
        wenbois2000 added a comment - - edited

        it may be reasonable to check whether the entry key is the string begin with "org.glassfish.jersey.*" or"jersey.config":

        ApplicationMXBeanImpl.java
        for (Map.Entry<String, Object> entry : resourceConfig.getProperties().entrySet()) {
                    String key = entry.getKey();
                    if(key.startsWith("org.glassfish.jersey") || key.startsWith("jersey.config")){
                        configurationProperties.put(key, entry.getValue().toString());
                    }
        }
        
        Show
        wenbois2000 added a comment - - edited it may be reasonable to check whether the entry key is the string begin with "org.glassfish.jersey.*" or"jersey.config": ApplicationMXBeanImpl.java for (Map.Entry< String , Object > entry : resourceConfig.getProperties().entrySet()) { String key = entry.getKey(); if (key.startsWith( "org.glassfish.jersey" ) || key.startsWith( "jersey.config" )){ configurationProperties.put(key, entry.getValue().toString()); } }
        Hide
        Miroslav Fuksa added a comment -

        Hi,

        Thanks for creating this bug. I think this is a bug of Jetty that they provide the attribute which throws ConcurrencyException on toString() method. On Jersey side I think we should expose all properties of ResourceConfig (not only jersey properties). We can add a exception handling and ignore values that throws exception in toString() method. This is more flexible solution from my point of view.

        I move this issue to backlog and the the proposed fix is to only skip properties that throw an exception. As an workaround you can remove this property for example in a custom Feature that will register the same property name as key with empty String value.

        The question about GZIP filter should be asked on Jersey user mailing list. Yes, when EncodingFrature is registered, then it checks the header Content-Encoding and when value of this header is "gzip" or "x-gzip", then the Gzip encoding will be used.

        Thanks
        Mira

        Show
        Miroslav Fuksa added a comment - Hi, Thanks for creating this bug. I think this is a bug of Jetty that they provide the attribute which throws ConcurrencyException on toString() method. On Jersey side I think we should expose all properties of ResourceConfig (not only jersey properties). We can add a exception handling and ignore values that throws exception in toString() method. This is more flexible solution from my point of view. I move this issue to backlog and the the proposed fix is to only skip properties that throw an exception. As an workaround you can remove this property for example in a custom Feature that will register the same property name as key with empty String value. The question about GZIP filter should be asked on Jersey user mailing list. Yes, when EncodingFrature is registered, then it checks the header Content-Encoding and when value of this header is "gzip" or "x-gzip", then the Gzip encoding will be used. Thanks Mira
        Hide
        wenbois2000 added a comment -

        please also say the bug:JERSEY-2054.
        and anyone known how to join jersey mail list? i subscribe it many times, but still don't receive any replies.

        Show
        wenbois2000 added a comment - please also say the bug: JERSEY-2054 . and anyone known how to join jersey mail list? i subscribe it many times, but still don't receive any replies.

          People

          • Assignee:
            Marek Potociar
            Reporter:
            wenbois2000
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Time Tracking

              Estimated:
              Original Estimate - 1 hour
              1h
              Remaining:
              Remaining Estimate - 0 minutes
              0m
              Logged:
              Time Spent - 1 minute Time Not Required
              1m