3

I'm having this weird issue where even though (I think) I'm setting everything to be accessible correctly, I'm still getting IllegalAccessException.

java.lang.IllegalAccessException: class com.sasha.eventsys.SimpleEventManager can not access a member of class com.sasha.proxy.discord.DiscordMain with modifiers "private"

public void invokeEvent(SimpleEvent e){
    registeredMethods.forEach(method -> {
        if (method.getParameterTypes()[0] == e.getClass()){
            try {
                Class clasz = method.getDeclaringClass();
                for (Field field : clasz.getFields()) {
                    field.setAccessible(true);
                }
                for (Method meth : clasz.getMethods()) {
                    meth.setAccessible(true);
                }
                for (Constructor<?> constructor : clasz.getConstructors()) {
                    constructor.setAccessible(true);
                }
                method.setAccessible(true);
                method.invoke(clasz.newInstance(), e);
            }
            catch (Exception ex){
                System.out.println("FATAL EXCEPTION DURING " + e.getClass().getName() + "'s EXECUTION");
                ex.printStackTrace();
            }
        }
    });
}

This is the code that's invoking the method. In theory those for loops should be setting everything to be accessible, r-right?

@SimpleEventHandler
public void onMcMsgRecieved(MinecraftMessageRecievedEvent e){
    if(Config.doDiscord) {
        DiscordMain.theChannel = DiscordMain.findTheServer(jda.getTextChannelsByName(Config.channelName,false));
        if (Config.aestheticDiscord) {
            DiscordMain.renderViewport(e.getPlainText(), DiscordMain.theChannel, Caches.messagesRecieved==0);
            Caches.messagesRecieved++;
        }
        else {
            DiscordMain.theChannel.sendMessage("```html\n" + e.getPlainText().replace("discord.gg", "zozzle.gg").replace("`", "'").replaceAll("\247[^z]", "") + "\n```").submit();
        }
        Webhooks.pushToHook("```html\n" + e.getPlainText().replace("discord.gg", "zozzle.gg").replace("`", "'").replaceAll("\247[^z]", "") + "\n```");
    }
}

And here's where it's supposedly not able to access something. For reference all of the fields and methods called in this block are public or public static, so like, I don't get why it's having problems.

The Impaler
  • 45,731
  • 9
  • 39
  • 76
Sasha
  • 33
  • 4

1 Answers1

5

Reflection instances of Field, methods, constructors etc are only a copy and .setAccessible only affects that copy, so code like

            for (Field field : clasz.getFields()) {
                field.setAccessible(true);
            }

does nothing.

In your case I would guess that .newInstance is throwing that error as no-args constructor is private? If that is true then you need to fetch constructor manually via .getDeclaredConstructor() method and set it to accessible and use it to create new instance.

GotoFinal
  • 3,585
  • 2
  • 18
  • 33
  • True, but OP sets accessible true before the invocation, so your answer doesn't explain the exception – Bohemian Aug 06 '18 at 00:53
  • @Bohemian OP also didn't explain where he got that error. but see my edit, maybe it is about .newInstance – GotoFinal Aug 06 '18 at 01:39
  • Thanks for your comment, so it seems that most likely, your answer is correct. – GhostCat Aug 06 '18 at 10:47
  • Then accept it too, about issue, isn't it that this field you want to change is static too? As I see many static usages in your code, then just pass null: `field.set(null, newValue)` (but such amount of static code looks pretty bad) – GotoFinal Aug 06 '18 at 10:50