0

I am getting following exception when trying to access my localhost service.

2019-01-22 13:57:27 ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
    at org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping.exposeEffectiveLookupPathKey(RepositoryRestHandlerMapping.java:264) ~[spring-data-rest-webmvc-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping.lookupHandlerMethod(RepositoryRestHandlerMapping.java:165) ~[spring-data-rest-webmvc-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:347) ~[spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:62) ~[spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:401) ~[spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping$HandlerSelectionResult.from(DelegatingHandlerMapping.java:108) ~[spring-data-rest-webmvc-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping.getHandler(DelegatingHandlerMapping.java:74) ~[spring-data-rest-webmvc-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1231) ~[spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1014) ~[spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998) ~[spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doOptions(FrameworkServlet.java:937) ~[spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:669) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875) ~[spring-webmvc-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.12.jar:9.0.12]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770) [tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) [tomcat-embed-core-9.0.12.jar:9.0.12]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.12.jar:9.0.12]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.12.jar:9.0.12]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]

My RestConfiguration class is :

@Configuration
@EnableWebMvc
public class RestConfiguration implements RepositoryRestConfigurer, WebMvcConfigurer {

    @Autowired
    private EntityManager entityManager;

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration repositoryRestConfiguration){
        repositoryRestConfiguration.exposeIdsFor(entityManager.getMetamodel().getEntities().stream().map
                (Type::getJavaType).toArray(Class[]::new));
    }

    @Override
    public void addCorsMappings(CorsRegistry registry){
        registry.addMapping("/**");
    }

}

Angular it throwing following error:

Access to XMLHttpRequest at 'http://localhost:8080/getPositions' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

while I can load the URL : http://localhost:8080/getPositions fine in the browser and see the output.

My Angular code is

getAllPositions(): Observable<Position[]> {
    const httpOptions  = {
      headers: new HttpHeaders(
        {'Content-Type': 'application/x-www-form-urlencoded',
          'Access-Control-Allow-Origin': 'http://localhost:4200',
          'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE,OPTION',
          'Access-Control-Allow-Headers': '*'})
    };
    return this.httpClient.get<Position[]>(this.positionUrl, httpOptions)
      .pipe(
        tap(() => this.log('fetching all Positions')),
        catchError(this.handleError('getAllPositions', []))
      );
  }

Please help.

Ashish
  • 14,295
  • 21
  • 82
  • 127
  • Have you tried simply putting `@CrossOrigin` on the controller you're calling? – Chris Jan 22 '19 at 19:34
  • I don't have controller I am extending spring-jpa-repository – Ashish Jan 22 '19 at 19:36
  • This is NOT a CORS problem at all. Spring Data-Rest API cannot map the request to a valid controller-method. Your configuration is also weird. Could you insert the entity class you try to load via that request? And also its repository interface. – Selindek Jan 26 '19 at 14:46

2 Answers2

1

As of version 3.1.4.RELEASE, it's a bug in RepositoryRestHandlerMapping. The issue has been resolved on Github though, so hopefully it'll be in the next release.

Check out this post if you want for more info.

UPDATE This was fixed in 3.1.5.RELEASE

NatFar
  • 2,090
  • 1
  • 12
  • 29
0

The issue is server side as CORS is enforced by the server, not the client, so the Angular code doesn't play a part there, and adding CORS headers in Angular won't help.

My assumptions are you're running the backend on port 8080, and the Angular code from port 4200

Maybe try this:

getAllPositions(): Observable<Position[]> {
    const httpOptions  = {
      headers: new HttpHeaders(
        {'Content-Type': 'application/x-www-form-urlencoded'})
    };
    return this.httpClient.get<Position[]>(this.positionUrl, httpOptions)
      .pipe(
        tap(() => this.log('fetching all Positions')),
        catchError(this.handleError('getAllPositions', []))
      );
  }

And

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/getPositions")
        .allowedOrigins("http://localhost:4200")
        .allowedMethods("GET")
}

You need to configure the backend service on port 8080 to allow requests from port 4200 - even though both are running on localhost, the different ports trigger the CORS policy violation, so you have to explicitly allow that.

Edit: Maybe set the policy to "*" first, and maybe ideally globally until it's working, and then narrow the scope to the specific URL for security.

    .allowedOrigins("*")
Stephen R. Smith
  • 3,310
  • 1
  • 25
  • 41
  • I don't believe i have /api/** anywhere in the URL. thanks for your help – Ashish Jan 22 '19 at 19:38
  • tried that as well but did not work. thanks for your help. – Ashish Jan 22 '19 at 19:48
  • The base problem is that you need to configure the server to allow requests specifically from port 4200, either by setting a global CORS policy, or a route specific one. I would suggest setting a global CORS policy maybe for "*" first until you get it working, then narrow the scope to the specific domain. – Stephen R. Smith Jan 22 '19 at 19:59