4

I was trying to package a spring boot application as a war. But when i try to deploy the war in tomcat it and try to start it, it throws the an Exception saying Exception starting filter java.lang.AbstractMethodError. My Spring boot version is 2.2.6 and Tomcat version is 8.5

08-May-2020 09:16:39.995 INFO [http-nio-8080-exec-27] org.apache.catalina.core.ApplicationContext.log 2 Spring WebApplicationInitializers detected on classpath
08-May-2020 09:16:48.472 INFO [http-nio-8080-exec-27] org.apache.catalina.core.ApplicationContext.log Initializing Spring embedded WebApplicationContext
08-May-2020 09:17:04.638 SEVERE [http-nio-8080-exec-27] org.apache.catalina.core.StandardContext.filterStart Exception starting filter [APIAuthorizationFilter]
    java.lang.AbstractMethodError
        at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:281)
        at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:110)
        at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4548)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5193)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at org.apache.catalina.manager.ManagerServlet.start(ManagerServlet.java:1383)
        at org.apache.catalina.manager.HTMLManagerServlet.start(HTMLManagerServlet.java:694)
        at org.apache.catalina.manager.HTMLManagerServlet.doPost(HTMLManagerServlet.java:218)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.filters.CsrfPreventionFilter.doFilter(CsrfPreventionFilter.java:211)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:109)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:668)
        at org.apache.catalina.valves.RequestFilterValve.process(RequestFilterValve.java:348)
        at org.apache.catalina.valves.RemoteAddrValve.invoke(RemoteAddrValve.java:52)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:615)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:818)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1627)
        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)
08-May-2020 09:17:04.646 INFO [http-nio-8080-exec-27] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext

My APIAuthorizationFilter class is

@Component
public class APIAuthorizationFilter implements Filter{

    @Value("${hmac.secret.key}")
    private String secretKey;

    @Autowired
    private UnauthorizedExceptionController exceptionController;

    @Override
    public void doFilter(ServletRequest sr, ServletResponse sr1, FilterChain fc) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) sr;
        HttpServletResponse httpServletResponse = (HttpServletResponse) sr1;
        try {
            MultiReadHttpServletRequest multiReadRequest = new MultiReadHttpServletRequest(httpServletRequest);

            String authorizationHeader = HmacUtil.getHeaderValue(httpServletRequest, "Authorization");
            String username = HmacUtil.getUsernameFromDecodeBasicAuth(authorizationHeader);
            String password = HmacUtil.getPasswordFromDecodeBasicAuth(authorizationHeader);
            String passwordSecretKey = secretKey;
            if (passwordSecretKey != null && !passwordSecretKey.isEmpty() && passwordSecretKey.length() > 0) {
                if (password.equals(passwordSecretKey.split(",")[0])) {

                    final SignatureBuilder signatureBuilder = new SignatureBuilder()
                            .algorithm(HmacUtil.getAlgorithm())
                            .accessUser(username)
                            .accessPassword(password)
                            .method(httpServletRequest.getMethod())
                            .contentType(MediaType.APPLICATION_JSON)
                            .resource(HmacUtil.getPath(httpServletRequest))
                            .apiSecret(AESEncryption.decryptText(passwordSecretKey.split(",")[1]).getBytes())
                            .body(HmacUtil.getRequestBody(multiReadRequest));

                    String hmac = HmacUtil.getHeaderValue(httpServletRequest, "auth");
                    Logger.getLogger(SignatureBuilder.class.getName()).log(Level.INFO, "Signature " + hmac);
                    if (!signatureBuilder.isHashEquals(hmac.getBytes())) {
                        throw new UnauthorizedException("Cannot access this resource");
                    }
                    fc.doFilter(multiReadRequest, sr1);
                } else {
                    throw new UnauthorizedException("Cannot access this resource");
                }
            } else {
                throw new UnauthorizedException("Cannot access this resource");
            }
        } catch (Exception e) {
            Logger.getLogger(APIAuthorizationFilter.class.getName()).log(Level.SEVERE, "Exception:: " + e.getMessage(), e);
            httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
            httpServletResponse.setContentType("application/json");
            httpServletResponse.getWriter().write(exceptionController.unauthorizedStringRes(new UnauthorizedException("Cannot access this resource")));
        }
    }

My FilterBean class to register is

@Configuration
public class FilterBean {

    @Bean
    public FilterRegistrationBean registerFilter(APIAuthorizationFilter aPIAuthorizationFilter) {
        FilterRegistrationBean<APIAuthorizationFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(aPIAuthorizationFilter);
        filterRegistrationBean.addUrlPatterns("/api/*");
        return filterRegistrationBean;
    }

}
Sudan Shrestha
  • 97
  • 1
  • 10

2 Answers2

5

I got same error when deploying in tomcat 8.Try deploying in tomcat 9. I think spring boot 2.2 requires tomcat 9.

Also Default embed tomcat of Spring boot 2.2.6 is org.apache.tomcat.embed 9.0.33

Mukesh M
  • 2,242
  • 6
  • 28
  • 41
3

Old question, but I had this issue today and I fixed it in a different way from the answer given.

The error is because the Filter interface on tomcat has no default methods for:

 public default void init(FilterConfig filterConfig) throws ServletException {}
 public default void destroy() {}

just implement both on your filter, like that should solve.

@Override
public void init(FilterConfig filterConfig) throws ServletException {
  log.debug("init");
}
@Override
  public void destroy() {
  log.debug("destroy");
}
Guilherme
  • 877
  • 9
  • 16