astefanutti / metrics-aspectj

AspectJ integration for Dropwizard Metrics
Apache License 2.0
81 stars 39 forks source link

ClassCastException: com.codahale.metrics.Timer cannot be cast to com.codahale.metrics.Meter #5

Closed gresrun closed 10 years ago

gresrun commented 10 years ago

I'm getting the following bizarre exception at runtime:

java.lang.ClassCastException: com.codahale.metrics.Timer cannot be cast to com.codahale.metrics.Meter
! at org.stefanutti.metrics.aspectj.MeteredAspect.ajc$before$org_stefanutti_metrics_aspectj_MeteredAspect$1$ed31598a(MeteredAspect.aj:28) ~[license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.clarecontrols.licensing.cliq.service.impl.FusionAPIImpl.getProjectNameForUUID_aroundBody4(FusionAPIImpl.java:143) ~[license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.clarecontrols.licensing.cliq.service.impl.FusionAPIImpl$AjcClosure5.run(FusionAPIImpl.java:1) ~[license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.stefanutti.metrics.aspectj.TimedAspect.ajc$around$org_stefanutti_metrics_aspectj_TimedAspect$1$c493a7d9proceed(TimedAspect.aj:26) ~[license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.stefanutti.metrics.aspectj.TimedAspect.ajc$around$org_stefanutti_metrics_aspectj_TimedAspect$1$c493a7d9(TimedAspect.aj:31) ~[license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.clarecontrols.licensing.cliq.service.impl.FusionAPIImpl.getProjectNameForUUID(FusionAPIImpl.java:142) ~[license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.clarecontrols.licensing.cliq.api.LicenseInfoResource.getProjectName(LicenseInfoResource.java:146) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.clarecontrols.licensing.cliq.api.LicenseInfoResource.getLicenseInfoView(LicenseInfoResource.java:125) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_05]
! at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_05]
! at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_05]
! at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_05]
! at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.codahale.metrics.jersey.InstrumentedResourceMethodDispatchProvider$TimedRequestDispatcher.dispatch(InstrumentedResourceMethodDispatchProvider.java:30) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.codahale.metrics.jersey.InstrumentedResourceMethodDispatchProvider$MeteredRequestDispatcher.dispatch(InstrumentedResourceMethodDispatchProvider.java:49) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at io.dropwizard.jersey.guava.OptionalResourceMethodDispatchAdapter$OptionalRequestDispatcher.dispatch(OptionalResourceMethodDispatchAdapter.java:37) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.server.impl.uri.rules.ResourceObjectRule.accept(ResourceObjectRule.java:100) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1542) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1473) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:540) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:715) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at javax.servlet.http.HttpServlet.service(HttpServlet.java:848) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at io.dropwizard.jetty.NonblockingServletHolder.handle(NonblockingServletHolder.java:49) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1515) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.servlets.UserAgentFilter.doFilter(UserAgentFilter.java:83) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.servlets.GzipFilter.doFilter(GzipFilter.java:348) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at io.dropwizard.jetty.BiDiGzipFilter.doFilter(BiDiGzipFilter.java:127) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1486) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at io.dropwizard.servlets.ThreadNameFilter.doFilter(ThreadNameFilter.java:29) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1486) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at io.dropwizard.jersey.filter.AllowedMethodsFilter.handle(AllowedMethodsFilter.java:44) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at io.dropwizard.jersey.filter.AllowedMethodsFilter.doFilter(AllowedMethodsFilter.java:39) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1486) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:519) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1097) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:448) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1031) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:136) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:175) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at io.dropwizard.jetty.RoutingHandler.handle(RoutingHandler.java:51) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:92) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:162) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.server.Server.handle(Server.java:446) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:271) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:246) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:358) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:601) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:532) [license-server-1.0.1-SNAPSHOT.jar:1.0.1-SNAPSHOT]
! at java.lang.Thread.run(Thread.java:745) [na:1.8.0_05]

I'm trying to use this project to provide metrics around API calls that I am making inside of a Dropwizard environment (which handles metrics). Timers work but Meters fail with the above error.

I am building using Maven; below is a cut-down version of of the POM with the relevant parts:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <prerequisites>
        <maven>3.0.0</maven>
    </prerequisites>
    <groupId>com.clarecontrols.licensing.cliq</groupId>
    <artifactId>license-server</artifactId>
    <version>1.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>CLIQ License Server</name>
    <!-- Elided for clarity -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <dropwizard.version>0.7.1</dropwizard.version>
        <mainClass>com.clarecontrols.licensing.cliq.LicenseServerApplication</mainClass>
        <mojo.java.target>1.7</mojo.java.target>
    </properties>
    <!-- Elided for clarity -->
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <createDependencyReducedPom>true</createDependencyReducedPom>
                    <transformers>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>${mainClass}</mainClass>
                        </transformer>
                    </transformers>
                    <!-- Exclude signed Manifests -->
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                            <mainClass>${mainClass}</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.2.1</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>2.9</version>
                <executions>
                    <execution>
                        <id>attach-javadocs</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.7</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.wagon</groupId>
                        <artifactId>wagon-ssh</artifactId>
                        <version>2.6</version>
                    </dependency>
                </dependencies>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.7</version>
                <configuration>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.stefanutti.metrics.aspectj</groupId>
                            <artifactId>metrics-aspectj</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                    <complianceLevel>1.7</complianceLevel>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <!-- Elided for clarity -->
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-assets</artifactId>
            <version>${dropwizard.version}</version>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-auth</artifactId>
            <version>${dropwizard.version}</version>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-core</artifactId>
            <version>${dropwizard.version}</version>
            <exclusions>
                <!-- Provided by org.stefanutti.metrics.aspectj:metrics-aspectj -->
                <exclusion>
                    <groupId>org.glassfish.web</groupId>
                    <artifactId>javax.el</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.codahale.metrics</groupId>
                    <artifactId>metrics-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-jdbi</artifactId>
            <version>${dropwizard.version}</version>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-migrations</artifactId>
            <version>${dropwizard.version}</version>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-views-mustache</artifactId>
            <version>${dropwizard.version}</version>
        </dependency>
        <dependency>
            <groupId>org.stefanutti.metrics.aspectj</groupId>
            <artifactId>metrics-aspectj</artifactId>
            <version>1.0.0-rc.3</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.2</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.el</artifactId>
            <version>3.0.0</version>
        </dependency>
        <!-- Elided for clarity -->
    </dependencies>
</project>

The service implementation that I'm instrumenting:

package com.clarecontrols.licensing.cliq.service.impl;

import org.stefanutti.metrics.aspectj.Metrics;
// Elided for clarity
import com.clarecontrols.licensing.cliq.service.FusionAPI;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.annotation.Metered;
import com.codahale.metrics.annotation.Timed;

/**
 * FusionAPIImpl
 */
@Metrics(registry = "${this.registry}")
public class FusionAPIImpl implements FusionAPI {

    private final MetricRegistry registry;
    // Elided for clarity

    /**
     * Constructor.
     * @param registry the metrics registry
     * // Elided for clarity
     */
    public FusionAPIImpl(final MetricRegistry registry // Elided for clarity) {
        this.registry = registry;
    }

    /**
     * Required for EL to find the metrics registry property for the @Metrics annotation.
     * @return the metric registry
     */
    public MetricRegistry getRegistry() {
        return this.registry;
    }

    /**
     * {@inheritDoc}
     */
    @Timed(name = "updateLicenseType.timer")
    @Metered(name = "updateLicenseType.meter")
    @Override
    public void updateLicenseType(final String uuid, final LicenseType licenseType) {
        // Elided for clarity
    }

    /**
     * {@inheritDoc}
     */
    @Timed(name = "ping.timer")
    @Metered(name = "ping.meter")
    @Override
    public void ping() {
        // Elided for clarity
    }

    /**
     * {@inheritDoc}
     */
    @Timed(name = "getProjectNameForUUID.timer")
    @Metered(name = "getProjectNameForUUID.meter")
    @Override
    public String getProjectNameForUUID(final String uuid) {
        // Elided for clarity
        return null;
    }
}

Any ideas as to the cause of this? Thanks!

astefanutti commented 10 years ago

Hi,

Thanks a lot for the detailed report.

The root cause of the exception that you're facing originates from the improper handling of multiple Metrics annotations for a single method.

I implemented that proper support for multiple Metrics annotation per method in commit 507235c and released version 1.0.0-rc.4 on Maven Central so that you can test the fix.

Let me know if that addresses your error case and if you need further assistance.

gresrun commented 10 years ago

Hmmm. I upgraded to RC4 but now I can't even get the application to start because I get this error:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.clarecontrols.licensing.cliq.FusionAPIFactory.build(FusionAPIFactory.java:85)
    at com.clarecontrols.licensing.cliq.LicenseServerApplication.run(LicenseServerApplication.java:83)
    at com.clarecontrols.licensing.cliq.LicenseServerApplication.run(LicenseServerApplication.java:1)
    at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:42)
    at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:76)
    at io.dropwizard.cli.Cli.run(Cli.java:70)
    at io.dropwizard.Application.run(Application.java:72)
    at com.clarecontrols.licensing.cliq.LicenseServerApplication.main(LicenseServerApplication.java:46)
Caused by: javax.el.PropertyNotFoundException: ELResolver cannot handle a null base Object with identifier 'this'
    at com.sun.el.lang.ELSupport.throwUnhandled(ELSupport.java:68)
    at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:126)
    at com.sun.el.parser.AstValue.getBase(AstValue.java:151)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:200)
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
    at javax.el.ELProcessor.getValue(ELProcessor.java:129)
    at javax.el.ELProcessor.eval(ELProcessor.java:115)
    at org.stefanutti.metrics.aspectj.JavaxElMetricStrategy.resolveMetricRegistry(JavaxElMetricStrategy.java:42)
    at org.stefanutti.metrics.aspectj.MetricStaticAspect.ajc$after$org_stefanutti_metrics_aspectj_MetricStaticAspect$1$be47261c(MetricStaticAspect.aj:47)
    at com.clarecontrols.licensing.cliq.service.impl.FusionAPIImpl.<clinit>(FusionAPIImpl.java:45)
    ... 8 more

Same configuration and code samples as before. :frowning:

astefanutti commented 10 years ago

My mistake :-( I added the evaluation of the Metrics registry EL expression at class level though that leads to throwing that error when the class is having both non-static and static methods.

I've just reverted back to the previous behavior in commit a65d064 and added unit tests for that use case.

Would you mind testing your error case based on the head revision of the master branch before I release a newer version this time? ;-) Let me know otherwise I'll trigger a new release.

gresrun commented 10 years ago

See #6