Solved NoClassDefFoundError using external API

Discussion in 'Plugin Development' started by mysterypotatoguy, Mar 14, 2016.

Thread Status:
Not open for further replies.
  1. Hi, I'm trying to use an external API in my plugin and I keep throwing this error, I've tried adding the .jar to a lib folder and also shading the classes but I can't get it to work, any ideas on where I went wrong?
     
  2. Offline

    Zombie_Striker

    @mysterypotatoguy
    1. Treat the external API the same way you treat the Bukkit.jar (since the bukkit.jar is an api.)
    2. Can you post the error? Can you post your current class?
     
  3. Stacktrace:
    Code:
    [21:33:39 ERROR]: Error occurred while enabling DiscordBridge v1.0 (Is it up to date?)
    java.lang.NoClassDefFoundError: sx/blah/discord/api/DiscordException
            at me.mysterypotatoguy.bukkithandler.BukkitHandler.onEnable(BukkitHandler.java:22) ~[?:?]
            at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:291) ~[craftbukkit-1.9.jar:git-Bukkit-73eff0d]
            at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:332) [craftbukkit-1.9.jar:git-Bukkit-73eff0d]
            at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:404) [craftbukkit-1.9.jar:git-Bukkit-73eff0d]
            at org.bukkit.craftbukkit.v1_9_R1.CraftServer.loadPlugin(CraftServer.java:346) [craftbukkit-1.9.jar:git-Bukkit-73eff0d]
            at org.bukkit.craftbukkit.v1_9_R1.CraftServer.enablePlugins(CraftServer.java:318) [craftbukkit-1.9.jar:git-Bukkit-73eff0d]
            at net.minecraft.server.v1_9_R1.MinecraftServer.t(MinecraftServer.java:403) [craftbukkit-1.9.jar:git-Bukkit-73eff0d]
            at net.minecraft.server.v1_9_R1.MinecraftServer.l(MinecraftServer.java:368) [craftbukkit-1.9.jar:git-Bukkit-73eff0d]
            at net.minecraft.server.v1_9_R1.MinecraftServer.a(MinecraftServer.java:323) [craftbukkit-1.9.jar:git-Bukkit-73eff0d]
            at net.minecraft.server.v1_9_R1.DedicatedServer.init(DedicatedServer.java:241) [craftbukkit-1.9.jar:git-Bukkit-73eff0d]
            at net.minecraft.server.v1_9_R1.MinecraftServer.run(MinecraftServer.java:506) [craftbukkit-1.9.jar:git-Bukkit-73eff0d]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_73]
    Caused by: java.lang.ClassNotFoundException: sx.blah.discord.api.DiscordException
            at java.net.URLClassLoader.findClass(Unknown Source) ~[?:1.8.0_73]
            at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:77) ~[craftbukkit-1.9.jar:git-Bukkit-73eff0d]
            at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:62) ~[craftbukkit-1.9.jar:git-Bukkit-73eff0d]
            at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_73]
            at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_73]
            ... 12 more
    Classes:
    BukkitHandler.java
    Code:
    package me.mysterypotatoguy.bukkithandler;
    
    import me.mysterypotatoguy.discordhandler.DiscordHandler;
    import me.mysterypotatoguy.discordhandler.PotatoBot;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Color;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.AsyncPlayerChatEvent;
    import org.bukkit.plugin.java.JavaPlugin;
    
    import sx.blah.discord.api.DiscordException;
    import sx.blah.discord.api.MissingPermissionsException;
    import sx.blah.discord.util.HTTP429Exception;
    
    public class BukkitHandler extends JavaPlugin implements Listener {
       
        @Override
        public void onEnable() {
            PotatoBot.login("redacted", "redacted");
        }
        @EventHandler
        public void onPlayerChat(AsyncPlayerChatEvent event) throws HTTP429Exception, DiscordException, MissingPermissionsException {
            Player player = event.getPlayer();
            String playername = player.getDisplayName();
            String message = event.getMessage();
            if (message.startsWith("!")) {
                message = message.replaceFirst("!", null);
                DiscordHandler.sendToDiscord(message, playername);
            }
        }
        public static void sendToMinecraft(String userB, String messageB) {
            for(Player player : Bukkit.getOnlinePlayers()) {
                player.sendMessage(Color.AQUA + "[Discord] " + userB + ":" + messageB);       
            }
        }
    }
    DiscordHandler.java
    Code:
    package me.mysterypotatoguy.discordhandler;
    
    import me.mysterypotatoguy.bukkithandler.BukkitHandler;
    import sx.blah.discord.api.DiscordException;
    import sx.blah.discord.api.MissingPermissionsException;
    import sx.blah.discord.handle.EventSubscriber;
    import sx.blah.discord.handle.impl.events.MessageReceivedEvent;
    import sx.blah.discord.handle.impl.events.ReadyEvent;
    import sx.blah.discord.handle.obj.IChannel;
    import sx.blah.discord.handle.obj.IMessage;
    import sx.blah.discord.handle.obj.IUser;
    import sx.blah.discord.util.HTTP429Exception;
    import sx.blah.discord.util.MessageBuilder;
    
    public class DiscordHandler {
        @EventSubscriber
        public void onReadyEvent(ReadyEvent event) {
            //Connect to server
        }
        public void onMessageReceive(MessageReceivedEvent event) {
            IMessage message = event.getMessage();
            IChannel channel = message.getChannel();
            IUser user = message.getAuthor();
            String userB = user.getName().toString();
            String messageB = message.toString();
            if(channel.getName() == "Minecraft") {
                BukkitHandler.sendToMinecraft(userB, messageB);
            }
        }
        public static void sendToDiscord(String message, String playername) throws HTTP429Exception, DiscordException, MissingPermissionsException {
                new MessageBuilder(PotatoBot.client).appendContent(playername + ": "  + message).withChannel("Minecraft").build();
        }
    }
    PotatoBot.java:
    Code:
    package me.mysterypotatoguy.discordhandler;
    
    import sx.blah.discord.api.ClientBuilder;
    import sx.blah.discord.api.DiscordException;
    import sx.blah.discord.api.IDiscordClient;
    import sx.blah.discord.handle.EventDispatcher;
    
    public class PotatoBot {
        private String moduleName = "PotatoBot";
        private String moduleVersion = "1.0";
        private String moduleMinimumVersion = "2.3.1";
        private String author = "Mysterypotatoguy";
        public static IDiscordClient client;
       
        @SuppressWarnings("static-access")
        public PotatoBot(IDiscordClient client) {
            this.client = client;
        }
       
        public static PotatoBot login(String email, String password) {
            PotatoBot bot = null;
           
            ClientBuilder builder = new ClientBuilder();
            builder.withLogin(email, password);
            try {
                IDiscordClient client = builder.login();
                bot = new PotatoBot(client);
            } catch (DiscordException e) {
                e.printStackTrace();
            }
            return bot;
        }
    
        public void disable() {
            //Don't need to do anything here
        }
    
        public boolean enable(IDiscordClient client) {
            EventDispatcher dispatcher = client.getDispatcher();
            dispatcher.registerListener(new DiscordHandler());
            return true;
        }
    
        public String getAuthor() {
            return author;
        }
    
        public String getMinimumDiscord4JVersion() {
            return moduleMinimumVersion;
        }
    
        public String getName() {
            return moduleName;
        }
    
        public String getVersion() {
            return moduleVersion;
        }
       
    }
    Also pom.xml:
    Code:
    <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>me.mysterypotatoguy.discordbridge</groupId>
      <artifactId>DiscordBridge</artifactId>
      <version>1.0</version>
      <description>Plugin for bridging Discord and Minecraft</description>
       <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-shade-plugin</artifactId>
                  <executions>
                      <execution>
                          <phase>package</phase>
                          <goals>
                              <goal>shade</goal>
                          </goals>
                          <configuration>
                              <createDependencyReducedPom>false</createDependencyReducedPom>
                              <minimiseJar>true</minimiseJar>
                              <artifact>
                                  <includes>
                                      <include>io.github.austinv11:Discord4J</include>
                                  </includes>
                              </artifact>
                          </configuration>
                      </execution>
                  </executions>
              </plugin>
                <plugin>
                      <artifactId>maven-assembly-plugin</artifactId>
                      <configuration>
                        <archive>
                          <manifest>
                            <mainClass>me.mysterypotatoguy.bukkithandler.BukkitHandler</mainClass>
                          </manifest>
                            </archive>
                        <descriptorRefs>
                             <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                      </configuration>
                </plugin>
          </plugins>
       </build>  
       <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>
         <!--Spigot API-->
         <dependency>
                <groupId>org.spigotmc</groupId>
                <artifactId>spigot-api</artifactId>
                <version>1.9-R0.1-SNAPSHOT</version>
                <scope>provided</scope>
         </dependency>
         <!--Bukkit API-->
         <dependency>
                 <groupId>org.bukkit</groupId>
                 <artifactId>bukkit</artifactId>
                 <version>1.9-R0.1-SNAPSHOT</version>
                 <scope>provided</scope>
         </dependency>
         <dependency>
                <groupId>com.github.austinv11</groupId>
                <artifactId>Discord4J</artifactId>
                <version>dev-SNAPSHOT</version>
                <scope>provided</scope>
         </dependency>
    </dependencies>
    </project>
    Apologies for the poor code, it's a rough draft until I can get something that at least semi-works
     
  4. Offline

    mythbusterma

    @mysterypotatoguy

    You have to actually shade it and say that it is exported. Maven does not include things like that in jars by default.

    If you actually look in your jarfile, you will find it is missing.
     
  5. Have I not shaded it correctly? how would I say it is exported?
    I have also noticed that the jarfile is empty and no matter what I try I cannot get anything to package with the classes
     
  6. Offline

    mythbusterma

  7. Yeah I worded that wrong didn't I...
    the .jar has the classes I wrote, plugin.yml, pom.xml etc but it doesn't have the discord libraries it needs because they aren't exporting
     
  8. Offline

    mythbusterma

  9. I've already tried shading (though I'm not sure how successfully).
    Eclipse lists maven dependencies in the file manager but i think the problem is that they aren't being exported
     
  10. Offline

    mythbusterma

  11. @mythbusterma

    Could you point me to which part of my pom is wrong? I really cannot find a way to get this to work
     
  12. Offline

    mythbusterma

  13. I really cannot find a way to get this to work. Using maven I can create a shaded jar but not one with plugin.yml or pom.xml in...
    The maven dependencies just aren't exporting with the jar and I can't find a way to make it work

    any advice?
     
  14. Offline

    adgdeveloping

    If the API is a plugin on it's own (Like how BKCommonLib is treated as a plugin) make sure to depend your plugin on the API.

    http://wiki.bukkit.org/Plugin_YAML (depend)
     
  15. Offline

    mythbusterma

  16. Offline

    Konato_K

    Call me old-school if you want, but why don't you just add the classes manually to the jar?
    @mysterypotatoguy
     
  17. Pom:
    Code:
    <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>me.mysterypotatoguy.discordbridge</groupId>
      <artifactId>DiscordBridge</artifactId>
      <version>1.0</version>
      <description>Plugin for bridging Discord and Minecraft</description>
      <packaging>jar</packaging>
      <name>DiscordBridge[1.0]</name>
       <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-compiler-plugin</artifactId>
                  <version>3.1</version>
                  <configuration>
                      <source>1.7</source>
                      <target>1.7</target>
                  </configuration>
              </plugin>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-shade-plugin</artifactId>
                  <version>2.4.3</version>
                  <configuration>
                  </configuration>
                  <executions>
                      <execution>
                          <phase>package</phase>
                          <goals>
                              <goal>shade</goal>
                          </goals>
                      </execution>
                  </executions>
              </plugin>
          </plugins>
       </build>
       <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>
         <!--Spigot API-->
         <dependency>
                <groupId>org.spigotmc</groupId>
                <artifactId>spigot-api</artifactId>
                <version>1.9-R0.1-SNAPSHOT</version>
                <scope>provided</scope>
         </dependency>
         <!--Bukkit API-->
         <dependency>
                 <groupId>org.bukkit</groupId>
                 <artifactId>bukkit</artifactId>
                 <version>1.9-R0.1-SNAPSHOT</version>
                 <scope>provided</scope>
         </dependency>
         <dependency>
                <groupId>com.github.austinv11</groupId>
                <artifactId>Discord4J</artifactId>
                <version>dev-SNAPSHOT</version>
                <classifier>shaded</classifier>
                <scope>compile</scope>
         </dependency>
        </dependencies>
    </project>
    @Konato_K surprisingly this worked... makes me question why eclipse won't do this on export
     
  18. Offline

    mcdorli

    Signature 8. point
     
  19. Marked as solved, but if anyone knows how to do this the non-hacky way then it would be appreciated
     
  20. Offline

    ImAFlo

  21. Well, that didn't seem to work
     
  22. Offline

    Konato_K

    @mysterypotatoguy I don't use maven so I don't know what could be wrong with your pom, but try looking into examples and see what the libraries aren't shading, until you figure out I guess placing the classes manually is the way to go.
     
Thread Status:
Not open for further replies.

Share This Page