【问题标题】:java.lang.NoSuchMethodError when it is clearly therejava.lang.NoSuchMethodError 明显存在时
【发布时间】:2015-10-08 01:12:03
【问题描述】:

一般信息:我正在使用版本 git-Spigot-1d14d5f-ba32592 (MC: 1.8.3) 中的 Bukkit/Spigot API(实现 API 版本 1.8.3-R0.1-SNAPSHOT )、IntelliJ IDEA 14.1.3 并使用其默认编译器进行编译。 java jdk版本为1.8.0_25。

所以当我尝试调用这个类的构造函数时,它会从标题中抛出运行时异常。

库存菜单类

package me.lakan.util.inventory;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.HashMap;
import java.util.Map;

@SuppressWarnings("unused") // Util functionality is not always used
public class InventoryMenu implements Listener {

    private InventoryType type;
    private String title;

    private Map<Integer, MenuOption> options;

    // Constructors
    public InventoryMenu(InventoryType type, String title, JavaPlugin plugin) {

        this.options = new HashMap<Integer, MenuOption>();
        this.type = type;
        this.title = title;

        plugin.getServer().getPluginManager().registerEvents(this, plugin);
    }

    public boolean addOption(int position, MenuOption option) {
        boolean res = isPosEmpty(position);
        this.options.put(position, option);

        return res;
    }

    public void addOption(String name, int position, ItemStack icon) {
        addOption(position, new MenuOption(icon, name));
    }

    public boolean isPosEmpty(int position) {
        return !this.options.containsKey(position);
    }

    public void openFor(Player p) {
        // Create a new inventory
        Inventory inv = Bukkit.createInventory(p, this.type, this.title);

        // Fill all icons at their positions
        for (Map.Entry<Integer, MenuOption> key : this.options.entrySet()) {
            inv.setItem(key.getKey(), key.getValue().getIcon());
        }

        // If the inventory is a player inventory, update the player's
        if (inv.getType() == InventoryType.PLAYER) {
            p.getInventory().setContents(inv.getContents());
        }
        // For any openable inventory, just open it up
        else {
            p.openInventory(inv);
        }
    }

    /**
     * Listens for inventory clicks
     * If the inventory is a menu:
     * - Cancel movement
     * - Push event
     * - Close inventory if it should
     * @param e The actual event
     */
    @EventHandler(priority = EventPriority.HIGHEST)
    public void onInventoryClick(InventoryClickEvent e) {

        // Prevent clicking if this inventory was clicked
        if (e.getClickedInventory().getName().equals(this.title)) {
            e.setCancelled(true);

            // Check for option
            if (this.options.containsKey(e.getRawSlot())) {
                // Get the option for this slot
                MenuOption option = this.options.get(e.getRawSlot());

                // Fill out an event and push it
                MenuClickEvent event = new MenuClickEvent((Player) e.getWhoClicked(), true, option.getName(), e.getRawSlot());
                Bukkit.getServer().getPluginManager().callEvent(event);

                // Now close inventory if not cancelled
                if (event.willCLose()) {
                    e.getWhoClicked().closeInventory();
                }
            }
        }
    }

    @SuppressWarnings("unused")
    public interface OptionClickEventHandler {
        public void onOptionClick(MenuClickEvent event);
    }
}

项目菜单类

package me.lakan.test;

import me.lakan.util.inventory.InventoryMenu;
import me.lakan.util.inventory.MenuClickEvent;
import me.lakan.util.inventory.MenuOption;
import me.lakan.util.item.ItemBuilder;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryType;

public class ItemMenu implements Listener {
    private PluginEntry plugin;
    private InventoryMenu menu;

    // Commands
    private TestCommand testCmd;

    public ItemMenu(PluginEntry plugin) {

        Validate.notNull(this.plugin, "The plugin reference may not be null");
        this.plugin = plugin;

        this.menu = new InventoryMenu(InventoryType.CHEST, "" + ChatColor.DARK_GRAY + "Abilities", this.plugin);

        // Test
        this.menu.addOption(1,
                new MenuOption(
                        new ItemBuilder()
                                .amount(1)
                                .material(Material.RAW_FISH)
                                .name(ChatColor.LIGHT_PURPLE + "Test")
                                .lore(ChatColor.WHITE + "Click me")
                                .build(),
                        "TestIdentifier"));
        this.testCmd= new TestCmd(this.plugin);
}

    public void openFor(Player p) {
        this.menu.openFor(p);
    }



    @EventHandler(priority = EventPriority.NORMAL)
    public void onOptionClick(MenuClickEvent e) {
        // Test
        if (e.getName().equals("TestIdentifier")) {
            this.testCmd.executeFor(e.getWhoClicked());
        }
    }
}

异常堆栈跟踪

[12:48:25] [服务器线程/错误]:启用 Test v1.0 时出错(它是最新的吗?) java.lang.NoSuchMethodError: me.lakan.util.inventory.InventoryMenu.(Lorg/bukkit/event/inventory/InventoryType;Ljava/lang/String;Lorg/bukkit/plugin/java/JavaPlugin;)V

在 me.lakan.test.ItemMenu.(ItemMenu.java:33) ~[?:?] 在 me.lakan.test.CommandParser.(CommandParser.java:20) ~[?:?] 在 me.lakan.test.PluginEntry.onEnable(PluginEntry.java:21) ~[?:?] 在 org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:321) ~[spigot_server.jar:git-Spigot-1d14d5f-ba32592] 在 org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:335) [spigot_server.jar:git-Spigot-1d14d5f-ba32592] 在 org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:405) [spigot_server.jar:git-Spigot-1d14d5f-ba32592] 在 org.bukkit.craftbukkit.v1_8_R2.CraftServer.loadPlugin(CraftServer.java:356) [spigot_server.jar:git-Spigot-1d14d5f-ba32592] 在 org.bukkit.craftbukkit.v1_8_R2.CraftServer.enablePlugins(CraftServer.java:316) [spigot_server.jar:git-Spigot-1d14d5f-ba32592] 在 net.minecraft.server.v1_8_R2.MinecraftServer.r(MinecraftServer.java:416) [spigot_server.jar:git-Spigot-1d14d5f-ba32592] 在 net.minecraft.server.v1_8_R2.MinecraftServer.k(MinecraftServer.java:382) [spigot_server.jar:git-Spigot-1d14d5f-ba32592] 在 net.minecraft.server.v1_8_R2.MinecraftServer.a(MinecraftServer.java:337) [spigot_server.jar:git-Spigot-1d14d5f-ba32592] 在 net.minecraft.server.v1_8_R2.DedicatedServer.init(DedicatedServer.java:257) [spigot_server.jar:git-Spigot-1d14d5f-ba32592] 在 net.minecraft.server.v1_8_R2.MinecraftServer.run(MinecraftServer.java:522) [spigot_server.jar:git-Spigot-1d14d5f-ba32592] 在 java.lang.Thread.run(Unknown Source) [?:1.8.0_31]

如您所见,构造函数就在那里,据我所知,它被正确调用了。那么这个错误是我的项目设置错误、API 问题还是完全不同的错误?

实用程序类位于一个单独的模块中,如果我将它们粘贴到我的测试插件模块中,一切正常,但不在另一个模块中。然而,me.lakan.util.inventory 内任何其他类中的任何其他构造函数都可以正常调用。

【问题讨论】:

  • 你在编译和运行时有不同的 jar 吗?如果构造函数不匹配,它不应该首先编译
  • 进行干净的构建并重新部署。
  • 没有。它在编译时将 util 插件的模块输出用于测试插件,并将所有相关类放入输出 jar。所以在运行时每个类和方法都应该可用...
  • 没有用。它再次做同样的事情
  • @EJP 是的,我也是这么想的。然而,我一直在围绕项目结构(尤其是依赖处理)转移几个小时并一遍又一遍地重建它......

标签: java exception constructor bukkit


【解决方案1】:

问题出在项目结构中。

对于测试神器,我选择了util模块的module output。 将其更改为 util 模块的 工件输出 修复了它。

【讨论】:

  • (将您的答案标记为“正确答案”,使问题消失在队列中)
  • @earizon: 你需要wait two days to self-accept :-(
  • 换句话说,这是一个“确保您编译的所有 JAR 都与 webapp 一起部署”的情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-05
  • 2020-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
相关资源
最近更新 更多