Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit2, maven project, Illegal reflective access warning

Tags:

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

like image 947
Janko92 Avatar asked Mar 29 '20 14:03

Janko92


People also ask

What is an illegal reflective access?

The "an illegal reflective access operation has occurred" is merely a warning message and only indicating there is reflective access to JDK internal class without doing anything about it. In the meantime, you can either. You can specify the reflective access explicitly using java's –add-opens parameter.


2 Answers

There is an issue filed about it 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.*
like image 131
sschuberth Avatar answered Sep 20 '22 23:09

sschuberth


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.

like image 44
retodaredevil Avatar answered Sep 19 '22 23:09

retodaredevil