35

I just started a new maven project and did a simple implementation of the Retrofit client. I'm getting the following warnings:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by retrofit2.Platform (file:/C:/Users/Admin/.m2/repository/com/squareup/retrofit2/retrofit/2.8.1/retrofit-2.8.1.jar) to constructor java.lang.invoke.MethodHandles$Lookup(java.lang.Class,int)
WARNING: Please consider reporting this to the maintainers of retrofit2.Platform
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Process finished with exit code 0

here is the code

import retrofit2.Retrofit;
import retrofit2.SimpleXmlConverterFactory;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

public class RetrofitClient {

    private static Retrofit retrofit = null;
    private RetrofitClient() { }

    public static EndPoints getAPI(String baseUrl) {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(SimpleXmlConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build();
        }
        return retrofit.create(EndPoints.class);
    }
}

Interface is simply

import retrofit2.Call;
import retrofit2.http.GET;

public interface EndPoints {
    @GET("teststatuses")
    Call<String> testStatus();
}

Call looks like this:

EndPoints endPoints = RetrofitClient.getAPI("http://localhost:8080/");
Call<String> repos = endPoints.testStatus();
System.out.println(repos.execute());

The project runs java language level 11 with SDK 11

Janko92
  • 371
  • 1
  • 3
  • 7

5 Answers5

37

There was an issue filed about this, to which one of the Retrofit maintainers responded:

The reflection works around a bug in the JDK which was fixed in 14 but it's only used for default methods. As it's only a warning, it's not preventing your call from working.

So your options are either to

  1. stick with Retrofit 2.8.x, and
    • ignore the warning, or
    • upgrade to Java 14
  2. downgrade to Retrofit 2.7.*
sschuberth
  • 28,386
  • 6
  • 101
  • 146
  • Why is it that Retrofit 2.8.X does not have a hard dependency on JDK >= 14 and this gives you a better error? Is this not possible in Java land? – Peheje Sep 12 '20 at 20:12
  • Just guessing: While that's certainly possible, at least with Maven and the [Enforcer plugin](https://maven.apache.org/enforcer/maven-enforcer-plugin/), the Retrofit makers probably just did not want to lock out < JDK 14 users from Retrofit 2.8. – sschuberth Sep 13 '20 at 07:29
  • Thanks sscuberth. That's nice to know. It's just that how can users not using JDK 14 use Retrofit 2.8 if it doesn't work? – Peheje Sep 14 '20 at 10:30
  • It *does* work. It's "just" a warning after all. – sschuberth Apr 01 '22 at 05:49
5

If you are between Java versions 9 and 13 and want to stick with Retrofit versions at or higher than 2.8, you can run your jar file like this:

java --add-opens=java.base/java.lang.invoke=ALL_UNNAMED my_jar.jar

Note that this won't work on Java 8, so if you really need to, you can hack up a solution like this (works on *nix):

if java --add-opens 2>&1 | grep 'requires modules' >/dev/null; then
  java --add-opens=java.base/java.lang.invoke=ALL-UNNAMED -jar my_jar.jar
else
  java -jar my_jar.jar
fi

If you're interested in looking into this further, you can look at the code that causes this.

I also found that this has some good information: https://blog.codefx.org/java/five-command-line-options-hack-java-module-system/

If you're using Gradle, you might also try adding default jvm args: How do I add default JVM arguments with Gradle. However, that still doesn't get you a plain jar file that just works.

retodaredevil
  • 1,261
  • 1
  • 13
  • 20
3

today I have got the same error. I imported Retrofit 2.8.1 to my project and it appeared. I tried everything, but one thing helped - I changed my Retrofit version to 2.7.2 and now everything works. Good luck!) If you use maven:

<dependency>
    <groupId>com.squareup.retrofit2</groupId>
    <artifactId>retrofit</artifactId>
    <version>2.7.2</version>
</dependency>

Gradle:

compile group: 'com.squareup.retrofit2', name: 'retrofit', version: '2.7.2'
3

I've added this block to my module build.gradle file.

Gradle

tasks.withType(Test) {
  /**
   * fix for retrofit https://github.com/square/retrofit/issues/3341
   */
  jvmArgs = ["--add-opens", "java.base/java.lang.invoke=ALL-UNNAMED"]
}

Kotlin DSL

tasks.withType<Test> {
  /**
   * fix for retrofit https://github.com/square/retrofit/issues/3341
   */
  jvmArgs = listOf("--add-opens", "java.base/java.lang.invoke=ALL-UNNAMED")
}

and the warning is not showing anymore. I think it's safe to remove it in this way because it is affecting test tasks only

MatPag
  • 41,742
  • 14
  • 105
  • 114
0

Be careful when working with versions. downgrading to Retrofit 2.7.* fixed the issue for me