12

How to figure out what causes this IllegalAccessError issue? Any help is appreciated.

I already followed some of the fixes/workaround and use Gson 2.8 from maven. Here is the partial Maven configuration:

<dependency>
    <groupId>com.squareup.retrofit2</groupId>
    <artifactId>converter-gson</artifactId>
    <version>2.2.0</version>
    <exclusions>
        <exclusion>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.0</version>
</dependency>

and full stack trace:

java.lang.IllegalAccessError: tried to access method com.google.gson.Gson.newJsonWriter(Ljava/io/Writer;)Lcom/google/gson/stream/JsonWriter; from class retrofit2.converter.gson.GsonRequestBodyConverter
    at retrofit2.converter.gson.GsonRequestBodyConverter.convert(GsonRequestBodyConverter.java:45)
    at retrofit2.converter.gson.GsonRequestBodyConverter.convert(GsonRequestBodyConverter.java:30)
    at retrofit2.ParameterHandler$Body.apply(ParameterHandler.java:312)
    at retrofit2.ServiceMethod.toRequest(ServiceMethod.java:110)
    at retrofit2.OkHttpCall.createRawCall(OkHttpCall.java:178)
    at retrofit2.OkHttpCall.execute(OkHttpCall.java:162)
    at com.xxxxxx.web.controller.UserController.exchangeAccessToken(UserController.java:2551)
    at com.xxxxxx.web.controller.UserController.plaidtoken(UserController.java:2645)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:685)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:919)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:851)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Lyubomyr Shaydariv
  • 20,327
  • 12
  • 64
  • 105
Billhatsv
  • 167
  • 1
  • 7
  • You seem to have something wrong with the dependencies. `GsonRequestBodyConverter.java:45` works for me if I run it at least from a "vanilla" Java program (and there is no reflection stuff, so probably there's a binary incompatibility). By the way, would you consider migrating to [Spring REST Templates](https://spring.io/guides/gs/consuming-rest/)? It is something that fits the Spring Framework stack better. Or did you choose Retrofit rejecting that Spring component? – Lyubomyr Shaydariv Apr 05 '17 at 06:28
  • @LyubomyrShaydariv Thanks for the reply. The Retrofit is not my choice, it is used by a third party package: plaid-java, which we use. Yes, I know the issue is probably within some dependency conflict, but as the project uses many many third party libs, do you know anyway to figure out which one causes the issue? – Billhatsv Apr 05 '17 at 08:47
  • @LyubomyrShaydariv thanks for the formatting too. – Billhatsv Apr 05 '17 at 08:49
  • I can't answer your question because it's really out of my knowledge, sorry. It's strange because https://github.com/square/retrofit/blob/parent-2.2.0/retrofit-converters/gson/src/main/java/retrofit2/converter/gson/GsonRequestBodyConverter.java#L45 should work without any flaws. What Retrofit 2 version are you using, 2.2.0? What if you try to autowire your `Gson` bean so that trying to invoke its `newJsonWriter()`? – Lyubomyr Shaydariv Apr 05 '17 at 09:18
  • 1
    @LyubomyrShaydariv understand, the issue is caused by change in the Gson, which in previous version, newJsonWriter() is not public and I suspect one of our third party jar may include a older version of Gson and causes this error. Would like to hear from the community if there is any good way to identify which package causes this. – Billhatsv Apr 05 '17 at 20:51
  • If I'm not mistaken, you could try to inspect the dependency graph with `mvn dependency:tree` and analyze it to exclude the older Gson version. – Lyubomyr Shaydariv Apr 05 '17 at 21:05
  • @LyubomyrShaydariv It is solved now. Here is how I did, for anyone else also looking for similar problem: I used the 'jar -tf filename.jar ' to list/dump the content of each package we use, and searched the result for 'gson'. I was able to identify one of the third party package that includes gson with it. Once this jar file is isolated, the problem went away. Thanks! – Billhatsv Apr 06 '17 at 00:47

2 Answers2

5

According to IllegalAccessError documentation:

Thrown if an application attempts to access or modify a field, or to call a method that it does not have access to.

...this error can only occur at run time if the definition of a class has incompatibly changed.

In your case the exception is throw at runtime which means that at compilation time the classpath was different from the classpath at runtime.

In general case such problem can be solved by analysing transitive dependencies, you can use maven dependency plugin:

mvn dependency:tree

Most likely you'll find transitive dependency in some of your libs with gson version different from the one you declared.

Note: there is hight chance of braking something else if you replace one of transitive dependencies. Be careful with this and make sure you're using compatible libs.

Community
  • 1
  • 1
Sasha Shpota
  • 9,436
  • 14
  • 75
  • 148
3

it is solved now. Here is how I did, for anyone else also looking for similar problem:

I used the 'jar -tf filename.jar' to list or dump the content of each package we use, and searched the result for 'gson'.

I was able to identify one of the third party package that includes gson with it. Once this jar file is isolated, the problem went away.

Thanks for reading.

elin
  • 538
  • 4
  • 6
Billhatsv
  • 167
  • 1
  • 7