SparklingComet / java-mojang-api

Full Mojang API Wrapper
http://wiki.vg/Mojang_API
Apache License 2.0
44 stars 11 forks source link

Help! java.lang.NoClassDefFoundError from java.lang.ClassNotFoundException #13

Closed Stonley890 closed 1 year ago

Stonley890 commented 1 year ago

I'm trying to use this in a Spigot plugin but at runtime, it fails with java.lang.NoClassDefFoundError: org/shanerx/mojang/Mojang from Caused by: java.lang.ClassNotFoundException: org.shanerx.mojang.Mojang. I'm not super familiar with all this but I think this is an issue with Maven not bundling the Mojang class? There are no errors or problems in my IDE (VS Code). The file (from mvn -s settings.xml install -f pom.xml) is zipped below.

eyeofonyx-1.0.0.jar.zip

Here is the error when run:

java.lang.NoClassDefFoundError: org/shanerx/mojang/Mojang
        at io.github.stonley890.commands.CmdRoyalty.<init>(CmdRoyalty.java:25) ~[eyeofonyx-1.0.0.jar:?]
        at io.github.stonley890.Main.onEnable(Main.java:38) ~[eyeofonyx-1.0.0.jar:?]
        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:279) ~[paper-api-1.19.4-R0.1-SNAPSHOT.jar:?]
        at io.papermc.paper.plugin.manager.PaperPluginInstanceManager.enablePlugin(PaperPluginInstanceManager.java:189) ~[paper-1.19.4.jar:git-Paper-524]
        at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.enablePlugin(PaperPluginManagerImpl.java:104) ~[paper-1.19.4.jar:git-Paper-524]
        at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:507) ~[paper-api-1.19.4-R0.1-SNAPSHOT.jar:?]
        at org.bukkit.craftbukkit.v1_19_R3.CraftServer.enablePlugin(CraftServer.java:555) ~[paper-1.19.4.jar:git-Paper-524]
        at org.bukkit.craftbukkit.v1_19_R3.CraftServer.enablePlugins(CraftServer.java:466) ~[paper-1.19.4.jar:git-Paper-524]
        at net.minecraft.server.MinecraftServer.loadWorld0(MinecraftServer.java:638) ~[paper-1.19.4.jar:git-Paper-524]
        at net.minecraft.server.MinecraftServer.loadLevel(MinecraftServer.java:437) ~[paper-1.19.4.jar:git-Paper-524]
        at net.minecraft.server.dedicated.DedicatedServer.initServer(DedicatedServer.java:308) ~[paper-1.19.4.jar:git-Paper-524]
        at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1104) ~[paper-1.19.4.jar:git-Paper-524]
        at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:320) ~[paper-1.19.4.jar:git-Paper-524]
        at java.lang.Thread.run(Thread.java:833) ~[?:?]
Caused by: java.lang.ClassNotFoundException: org.shanerx.mojang.Mojang
        at org.bukkit.plugin.java.PluginClassLoader.loadClass0(PluginClassLoader.java:183) ~[paper-api-1.19.4-R0.1-SNAPSHOT.jar:?]
        at org.bukkit.plugin.java.PluginClassLoader.loadClass(PluginClassLoader.java:150) ~[paper-api-1.19.4-R0.1-SNAPSHOT.jar:?]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[?:?]
        ... 14 more

Here is my pom.xml:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>io.github.stonley890</groupId>
  <artifactId>eyeofonyx</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>

  <name>Eye of Onyx</name>
  <url>http://www.github.com/Stonley890/Eye-Of-Onyx</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
  </properties>

  <repositories>
    <repository>
      <id>spigot-repo</id>
      <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
    </repository>
    <repository>
      <id>jitpack.io</id>
      <url>https://jitpack.io</url>
    </repository>
  </repositories>

  <dependencies>
    <dependency>
      <groupId>org.spigotmc</groupId>
      <artifactId>spigot-api</artifactId>
      <version>1.19.4-R0.1-SNAPSHOT</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.github.SparklingComet</groupId>
      <artifactId>java-mojang-api</artifactId>
      <version>-SNAPSHOT</version>
    </dependency>
  </dependencies>

  <build>
    <defaultGoal>clean package</defaultGoal>
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <resources>
      <resource>
        <directory>src/resources</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-shade-plugin</artifactId>
          <version>3.4.1</version>
          <executions>
            <execution>
              <phase>package</phase>
              <goals>
                <goal>shade</goal>
              </goals>
              <configuration>
                <createDependencyReducedPom>false</createDependencyReducedPom>
                <finalName>Eye Of Onyx</finalName>
                <outputFile>${project.basedir}/target</outputFile>
              </configuration>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

</project>

Main.java

package io.github.stonley890;

import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;

import io.github.stonley890.commands.CmdEyeOfOnyx;
import io.github.stonley890.commands.CmdRoyalty;
import io.github.stonley890.files.RoyaltyBoard;
import io.github.stonley890.listeners.ListenJoin;

/*
 * The main ticking thread.
*/

public class Main extends JavaPlugin {

    private static Main plugin;

    public static String version;

    @Override
    public void onEnable() {
        // Register variables
        plugin = this;
        version = getDescription().getVersion();

        // Create config if needed
        getConfig().options().copyDefaults();
        saveDefaultConfig();

        // Set up royalty board file
        RoyaltyBoard.setup();
        // RoyaltyBoard.get().options().copyDefaults();
        RoyaltyBoard.save();

        // Initialize command executors
        getCommand("eyeofonyx").setExecutor(new CmdEyeOfOnyx());
        getCommand("royalty").setExecutor(new CmdRoyalty());

        // Initialize listeners
        getServer().getPluginManager().registerEvents(new ListenJoin(), plugin);

        // Start message
        Bukkit.getLogger().info(
                "Eye of Onyx " + version + ": A plugin that manages the royalty board on Wings of Fire: The New World");
    }

    // Allow other classes to access plugin instance
    public static Main getPlugin() {
        return plugin;
    }
}

And here is commands/CmdRoyalty.java

package io.github.stonley890.commands;

import java.util.Arrays;
import java.util.UUID;

import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scoreboard.Scoreboard;
import org.shanerx.mojang.Mojang;

import io.github.stonley890.Main;
import io.github.stonley890.files.RoyaltyBoard;
import net.md_5.bungee.api.ChatColor;

public class CmdRoyalty implements CommandExecutor {

    // Get plugin instance (main thread)
    Plugin plugin = Main.getPlugin();
    // Get Mojang services
    Mojang mojang = new Mojang().connect();
    // Get server scoreboard service (for teams)
    Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard();
    // Easy access royalty board
    FileConfiguration board = RoyaltyBoard.get();
    // Team names
    String[] teamNames = {
            "HiveWing", "IceWing", "LeafWing", "MudWing", "NightWing", "RainWing", "SandWing", "SeaWing", "SilkWing",
            "SkyWing"
    };
    // Tribe IDs
    String[] tribes = {
        "hive", "ice", "leaf", "mud", "night", "rain", "sand", "sea", "silk", "sky"
    };
    // Valid positions
    String validPositions[] = {
        "ruler", "heir_apparent", "heir_presumptive", "noble_apparent", "noble_presumptive"
    };

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {

        // Fail if not enough arguements
        if (args.length < 1) {
            return false;
        } // If arg[0] is "set"
        else if (args[0].equalsIgnoreCase("set") && args.length > 2) {

            // Try to get online Player, otherwise lookup OfflinePlayer
            Player targetPlayer;
            if (Bukkit.getPlayerExact(args[1]) == null) {
                targetPlayer = (Player) Bukkit.getOfflinePlayer(UUID.fromString(mojang.getUUIDOfUsername(args[1])));
            } else {
                targetPlayer = Bukkit.getPlayerExact(args[1]);
            }

            // Get tribe from scoreboard team
            String playerTribe = null;
            try {

                // Get team of player by iterating through list
                for (int i = 0; i < teamNames.length; i++) {
                    if (scoreboard.getTeam(teamNames[i]).hasEntry(targetPlayer.getName()))
                        playerTribe = tribes[i];
                }

                // If target has no associated tribe team, fail
                if (playerTribe == null) {
                    sender.sendMessage(ChatColor.RED + "Target does not have a tribe tag!");
                    return false;
                }

                // Check if third arguement contains a valid position
                if (Arrays.stream(validPositions).anyMatch(args[2]::contains)) {

                    // Set value in board.yml
                    board.set(playerTribe + "." + args[2] + ".uuid", targetPlayer.getUniqueId());
                    RoyaltyBoard.save();
                    sender.sendMessage(ChatColor.YELLOW + "" + targetPlayer.getName() + " is now " + args[2]);

                } else {
                    sender.sendMessage(
                            ChatColor.RED + "Invalid position. Valid positions: " + Arrays.toString(validPositions));
                }
            } catch (IllegalArgumentException e) {
                // getTeam() throws IllegalArgumentException if teams do not exist
                sender.sendMessage(ChatColor.RED + "Required teams do not exist!");
            }

        } else if (args[0].equalsIgnoreCase("list")) {
            if (args[1] == null) {
                StringBuilder strBuild = new StringBuilder();

                for (int i = 0; i < teamNames.length; i++) {
                    strBuild.append("\n" + ChatColor.GOLD + teamNames[i] + "---" + ChatColor.RESET + "\n[ RULER: " + mojang.getPlayerProfile((String) board.get(tribes[i] + ".ruler.uuid")).getUsername()
                    + "\n[ HEIR APPARENT: " + mojang.getPlayerProfile((String) board.get(tribes[i] + ".heir_apparent.uuid")).getUsername()
                    + "\n[ HEIR PRESUMPTIVE: " + mojang.getPlayerProfile((String) board.get(tribes[i] + ".heir_presumptive.uuid")).getUsername()
                    + "\n[ NOBLE APPARENT: " + mojang.getPlayerProfile((String) board.get(tribes[i] + ".noble_apparent.uuid")).getUsername()
                    + "\n[ NOBLE PRESUMPTIVE: " + mojang.getPlayerProfile((String) board.get(tribes[i] + ".noble_presumptive.uuid")).getUsername());
                }

                sender.sendMessage(ChatColor.YELLOW + "ROYALTY BOARD" + strBuild.toString());
            }
        }

        RoyaltyBoard.save();
        return true;
    }
}
Stonley890 commented 1 year ago

Solved. The maven shade plugin was inside pluginConfiguration.