Search code examples
javajersey-2.0

Java jersey monitoring statistics


I am trying to activate the monitoring statistics for a web service. But i get null pointer exception. How is it activated properly? I do not understand the documentation from jersey. Here is my code:

package com.app.rest;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.server.monitoring.MonitoringStatistics;
import org.glassfish.jersey.server.monitoring.TimeWindowStatistics;
@Path("/")
public class TestingEvents extends ResourceConfig {
public TestingEvents()
{
    ResourceConfig cnf =   new ResourceConfig(TestingEvents.class);
     cnf.property(ServerProperties.MONITORING_ENABLED, true);
}



@Inject
 Provider<MonitoringStatistics> monitoringStatisticsProvider;

@Path("/test")
@GET
public void test()
{
    System.out.println("Invoked.........");
    final MonitoringStatistics snapshot = monitoringStatisticsProvider.get();

    System.out.println(snapshot.getRequestStatistics().toString());
 //  final TimeWindowStatistics timeWindowStatistics = snapshot.getRequestStatistics().getTimeWindowStatistics().get(0);
    //System.out.println("request count: " + timeWindowStatistics.getRequestCount()+", average request processing [ms]: " + timeWindowStatistics.getAverageDuration());
}}

and my web xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee       http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>RestCounter</display-name>
<servlet>
    <servlet-name>MyApplication</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.app.rest</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>MyApplication</servlet-name>
    <url-pattern>/myApp/*</url-pattern>
</servlet-mapping>

And the exception:

SEVERE: Servlet.service() for servlet [MyApplication] in context with path     [/RestCounter] threw exception [java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at com.app.rest.TestingEvents.test(TestingEvents.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:143)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:160)
at org.glassfish.jersey.server.model.internal.VoidVoidDispatcherProvider$VoidToVoidDispatcher.doDispatch(VoidVoidDispatcherProvider.java:78)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:97)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:303)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:286)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1072)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:399)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

Invoked is shown at the console but then the program crushes. help please.


Solution

  • First get some configuration aspects out the way...

    ResourceConfig is kind of a replacement for a web.xml. They can be used together, as you can configure the web.xml to use your ResourceConfig subclass, but I rarely see the need to. If you want to go with no web.xml, you could do something like

    @ApplicationPath("/myApp")
    public class AppConfig extends ResourceConfig {
        public AppConfig() {
            packages("com.app.rest");
        }
    }
    

    This is the equivalent to you declaring the ServletContainer, setting the package(s) to scan, and setting the url-mapping to /myApp/*. With the above configuration, you can completely get rid of the web.xml (assuming you have the jersey-container-servlet dependency, and you are in a Servlet 3.x environment; in a Servlet 2.x environment, you need to use the web.xml).

    One thing you do not do, is have your resource classes extending ResourceConfig. So get rid of the sub-classing (in your TestingEvents class), and definitely get rid of what you have in the constructor.

    As far as setting the monitoring property...

    If you decide to go with the ResourceConfig subclass...

    you can simple do

    @ApplicationPath("/myApp")
    public class AppConfig extends ResourceConfig {
        public AppConfig() {
            packages("com.app.rest");
            property(ServerProperties.MONITORING_STATISTICS_ENABLED, true);
        }
    }
    

    If you decide to go with the web.xml...

    You should keep the javadoc of the ServerProperties handy. Each of the static fields, have String values, which for the most part can be configured in the web.xml as an <init-param> of the Jersey Servlet. If you look at the ServerProperties.MONITORING_STATISTICS_ENABLED, you will see that String value is

    jersey.config.server.monitoring.statistics.enabled
    

    So to set it as an init-param, do this

    <servlet>
        <servlet-name>MyApplication</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.app.rest</param-value>
        </init-param>
        <init-param>
            <param-name>jersey.config.server.monitoring.statistics.enabled</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>