1.16.5 InaccessibleObjectException: Unable to make protected void java.net.URLClassLoader.addURL...

Discussion in 'Spigot Plugin Development' started by Demeng, Jul 7, 2021.

  1. Hello,

    Not sure if StackOverflow would be more appropriate for this question, but I am currently experiencing this error while running Java 16; the issue does not occur on Java 8.

    java.lang.reflect.InaccessibleObjectException: Unable to make protected void java.net.URLClassLoader.addURL(java.net.URL) accessible: module java.base does not "opens java.net" to unnamed module @66a2fd43

    Full Stack Trace: https://paste.demeng.dev/navamecoco.cs

    After tracing the stack trace, it appears that this is the line causing the error:
    Code (Java):
    method.setAccessible(true);
    Context:
    Code (Java):
          final Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
          AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
            method.setAccessible(true);
            return null;
          });

    The error was promptly resolved by adding the following startup flag to the server:
    --add-opens java.base/java.net=ALL-UNNAMED

    Now, the issue is that, not only is adding this startup flag (that I've never heard of until now) annoying for both myself and my plugin users, some shared hosting forbid users from modifying such flags, even via support ticket.

    I am wondering if there is something I could do from my side to resolve this issue. The error comes from my runtime dependency loader, so my last resort would be to disable it and distribute its dependencies as a separate download, but I am hoping to be able to resolve this directly in my plugin. I've looked into 1.17's library loading feature a little bit, but it doesn't seem to have any relocation feature.

    Thanks in advance.
     
  2. I've seen some other posts referencing similar issues and I believe that setAccessible() works differently on java 16 than java 8, im not sure what the work-around would be, but I am pretty sure that it has to do with illegal accessing on java 16. md5 explains it better so I would check here for a better explanation :/
     
  3. Here is a post that also helps to give understanding to the new usage of deep reflections.
    https://softwaregarden.dev/en/posts/new-java/illegal-access-in-java-16/
     
  4. After a lot of digging I found that rather than using the jvm argument (
    Code (Java):
    --illegal-access=permit
    ) that you can directly enable this using
    Code (Java):
    System.setProperty("illegal-access", "permit");
    now, I have not tested if this will work, I just found it while searching through java 16 reflection articles and it seemed like it might work, so worth a shot right?
     
  5. It needs no relocation features as the library is only loaded once in that version for whole server.
    There could be one thing that fails but I need to look into the code there.