---
title: Java agent API: Error Grouping with a Custom Callback Implementation
source: https://docs.newrelic.com/docs/apm/agents/java-agent/api-guides/java-agent-api-register-error-group-callback-to-set-fingerprint
---

The New Relic Java agent API allows you to set up custom error grouping using a custom callback implementation in your Java application. This document shows an example of using the custom error grouping with a callback implementation in sample application.

> #### ⚠️ IMPORTANT
>
> For best results when using the API, ensure you have the [latest Java agent release](https://docs.newrelic.com/docs/release-notes/agent-release-notes/java-release-notes).

## Example: Implementing a custom error grouping callback [#example]

Below is an example of a sample application using the Java agent API to implement custom error grouping with a callback and registering the callback.

> #### 💡 TIP
>
> If you copy and paste example code, be sure to use appropriate spacing on your command lines.

```java
package test;
import com.newrelic.api.agent.ErrorGroupCallback;
import com.newrelic.api.agent.NewRelic;
import java.io.IOException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServletContextListener implements ServletContextListener {
  @Override
  public void contextDestroyed(ServletContextEvent arg0) {
    // Do any cleanup if needed
  }

  @Override
  public void contextInitialized(ServletContextEvent arg0) {
    // Register the error grouping callback on application startup
    NewRelic.setErrorGroupCallback(new MyErrorGrouper());
  }
}

public class MyErrorGrouper implements ErrorGroupCallback {
  public String generateGroupingString(ErrorData errorData) {
    String clazz = errorData.getErrorClass();
    String txnName = errorData.getTransactionName();

    return (clazz.isEmpty() || txnName.isEmpty()) ? null : clazz + "_" + txnName;
  }
}

public class TestServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;

  protected void processRequest(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    // Simulate an exception
    throw new ServletException("Simulated ServletException");
  }

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    processRequest(req, resp);
  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    processRequest(req, resp);
  }
}
```
