public static void setMOTD(final String motd) throws Exception {
final Field field = MinecraftServer.class.getDeclaredField("motd");
final Field server = CraftServer.class.getDeclaredField("console");
field.setAccessible(true);
server.setAccessible(true);
MinecraftServer instance = (MinecraftServer) server.get(CraftServer.class);
field.set(instance, motd);
}
我的目标是在Minecraft服务器上更改当天的消息(运行craftbukkit)。为此,我需要更改非静态字段motd。我正在使用插件执行所有这些操作,因此我无法获取MinecraftServer的实例。最后一行是我尝试使用反射做到这一点,但失败了。我没有权限更改MinecraftServer类或CraftServer,因为它们位于外部库中。
motd和console都是非静态字段。
motd是一个带有修饰符public final的字符串。
console是MinecraftServer的一个实例,修饰符是最终保护的。
这是我得到的错误(在setMOTD的倒数第二行):
2012-07-22 22:16:31 [SEVERE] java.lang.IllegalArgumentException: Can not set final net.minecraft.server.MinecraftServer field org.bukkit.craftbukkit.CraftServer.console to java.lang.Class
答案 0 :(得分:2)
重新阅读错误消息,似乎与您的代码不一致。错误消息似乎暗示您正在尝试将<{1}}成员变量设置为无效的对象类型。请确认您实际测试的代码。
答案 1 :(得分:2)
通过获取扩展CraftServer
的bukkit实例来解决 public static void setServerMOTD(final String motd) throws Exception {
final Field field = MinecraftServer.class.getDeclaredField("motd");
final Field server = CraftServer.class.getDeclaredField("console");
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
field.setAccessible(true);
server.setAccessible(true);
modifiersField.setInt(server, server.getModifiers() & ~Modifier.FINAL);
MinecraftServer instance = (MinecraftServer) server.get(Bukkit.getServer());
field.set(instance, motd);
}
答案 2 :(得分:0)
根据错误消息,CraftServer类中的字段控制台看起来像'final'。
这意味着一旦设置,你将无法改变它,在镜像有机会修改它之前会发生这种情况。
如果CraftServer是库的一部分,您可能无法更改此行为