Maven Shading Issue

Discussion in 'Spigot Plugin Development' started by Mcmogaming, Aug 11, 2018.

  1. Alright so I am kind of new to maven but I have been playing around with it for about a day now. Started yesterday and continued to today morning. Nevertheless the issue that I am having is Jsoup an API is not being included in compiled plugin jar. In Maven I have already changed the scope for the jsoup dependency to compile according to some form that I found regarding shading in Maven. Not completely sure what shading is yet but I do understand that it included the necessary class files for an api to work when compiled.

    Everytime I try to run the command from commandmanager i get this error provided below. It points to the line which is ws.start that uses the Jsoup API. From what I understand the necessary api classes for jsoup to work are not included as the error says NoClassDefFoundError : org/jsoup/Jsoup.

    This is the maven pom.xml file notice that I have included compile in the scope

    Code (Text):
    <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>com.gmail.mcmogaming</groupId>
      <artifactId>advertisementquietdayz</artifactId>
      <version>0.0.1-SNAPSHOT</version>
     
        <repositories>
        <repository>
            <id>spigot-repo</id>
            <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
        </repository>
      </repositories>
     
     
      <dependencies>
        <!--Spigot API-->
        <dependency>
               <groupId>org.spigotmc</groupId>
               <artifactId>spigot-api</artifactId>
               <version>1.13-R0.1-SNAPSHOT</version>
               <scope>provided</scope>
        </dependency>
        <!--Bukkit API-->
        <dependency>
                <groupId>org.bukkit</groupId>
                <artifactId>bukkit</artifactId>
                <version>1.13-R0.1-SNAPSHOT</version>
                <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
        <dependency>
                <groupId>org.jsoup</groupId>
                <artifactId>jsoup</artifactId>
                <version>1.8.3</version>
                <scope>compile</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.cedarsoftware/java-util -->
        <dependency>
                <groupId>com.cedarsoftware</groupId>
                <artifactId>java-util</artifactId>
                <version>1.5.0</version>
        </dependency>
      </dependencies>
     
      <profiles>
        <profile>
            <id>otherOutputDir</id>
            <build>
                <directory>C:\Users\Mohammad Rahman\Desktop\Minecraft Plugin Development\Debug Server 1.13\plugins</directory>
            </build>
        </profile>
      </profiles>
    </project>
    This is the commandmanager plugin which uses the webscrapper class that requires jsoup.

    Code (Text):
    package com.gmai.mcmogaming.advertisementquietdayz;

    import java.io.IOException;
    import java.util.ArrayList;

    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;

    public class CommandManager implements CommandExecutor{
     
        public boolean onCommand(CommandSender sender, Command cmd, String arg2, String[] arg3) {

            if(sender instanceof Player) {
           
                Player p = (Player)sender;
                Webscrapper ws = new Webscrapper();
           
                try {
                    ws.start();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
           
                ArrayList<ArrayList<String>> serverips = ws.getIPs();
           
           
                for(int i = 0; i < serverips.size(); i++) {
                    for(int j = 0; j < serverips.get(i).size(); j++) {
                        p.sendMessage(serverips.get(i).get(j));
                    }
                }
           
           
           
            }
       
       
       
            return false;
        }
     
     
     

    }
     
    Webscrapper code, this is the class that uses the JSoup API which is the API I am trying to get Maven to compile.

    Code (Text):
    package com.gmai.mcmogaming.advertisementquietdayz;
    import java.io.IOException;
    import java.util.ArrayList;

    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;

    public class Webscrapper {

        Document docMinecraftServers;
     
        Document docMinecraftServersPageTemp;
     
        Elements elMinecraftServers;
        Elements elMinecraftServersPageTemp;  // 0-9 where 9 is the last page.
     
        ArrayList<ArrayList<String>> ServerIPMinecraftServersOuter;
        ArrayList<String> ServerIPMinecraftServersInner;
     
        int lastPageIndex;
     
     
        public void start() throws IOException {
       
            ServerIPMinecraftServersOuter = new ArrayList<ArrayList<String>>();
            ServerIPMinecraftServersInner = new ArrayList<String>();
       
            System.out.println("Connecting to minecraftservers.org");
            docMinecraftServers = Jsoup.connect("https://minecraftservers.org/").get();
            System.out.println("Done connecting to minecraftservers.org");
       
            elMinecraftServers = docMinecraftServers.select("a");
       
            lastPageIndex = Integer.parseInt(elMinecraftServers.get(73).attr("href").substring(7));
            System.out.println("Last Page Index: " + lastPageIndex);
     
            for(int i = 0; i < 500; i++) {
       
            docMinecraftServersPageTemp = Jsoup.connect("https://minecraftservers.org/index/" + Integer.toString(lastPageIndex-i)).get();
            elMinecraftServersPageTemp = docMinecraftServersPageTemp.select("div.server-ip:has(p)");
       
       
       
       
                for(int j = 0; j < elMinecraftServersPageTemp.size(); j++) {
                    String strTemp = elMinecraftServersPageTemp.get(j).text();
                    ServerIPMinecraftServersInner.add(strTemp.substring(0, strTemp.indexOf(" ")));
                }
       
            ServerIPMinecraftServersOuter.add(ServerIPMinecraftServersInner);
            ServerIPMinecraftServersInner = new ArrayList<String>();
            System.out.println("Page " + i + " Processed");
            }
     
        }
     
        public void print() {

           
           
           
           
            }
       
     
        public void printServerIPs() {
            for(int i = 0; i < ServerIPMinecraftServersOuter.size(); i++) {
                System.out.println("==============================================" + i);
                for(int j = 0; j < ServerIPMinecraftServersOuter.get(i).size(); j++) {
                System.out.println(ServerIPMinecraftServersOuter.get(i).get(j));
                }
            }
        }
     
        public ArrayList<ArrayList<String>> getIPs(){
            return ServerIPMinecraftServersOuter;
        }
     
        public int getposition(String websiteName) {
       
            int position = 0;
       
            return position;
        }
     
     
     
    }
     
    Server side error output:

    Code (Text):
    [07:52:09 ERROR]: null
    org.bukkit.command.CommandException: Unhandled exception executing command 'adv' in plugin AdvertismentPluginQ v0.0.1
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot.jar:git-Spigot-1503de9-53d3ac0]
            at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot.jar:git-Spigot-1503de9-53d3ac0]
            at org.bukkit.craftbukkit.v1_13_R1.CraftServer.dispatchCommand(CraftServer.java:693) ~[spigot.jar:git-Spigot-1503de9-53d3ac0]
            at net.minecraft.server.v1_13_R1.PlayerConnection.handleCommand(PlayerConnection.java:1634) ~[spigot.jar:git-Spigot-1503de9-53d3ac0]
            at net.minecraft.server.v1_13_R1.PlayerConnection.a(PlayerConnection.java:1469) ~[spigot.jar:git-Spigot-1503de9-53d3ac0]
            at net.minecraft.server.v1_13_R1.PacketPlayInChat.a(PacketPlayInChat.java:45) ~[spigot.jar:git-Spigot-1503de9-53d3ac0]
            at net.minecraft.server.v1_13_R1.PacketPlayInChat.a(PacketPlayInChat.java:1) ~[spigot.jar:git-Spigot-1503de9-53d3ac0]
            at net.minecraft.server.v1_13_R1.PlayerConnectionUtils.a(SourceFile:10) ~[spigot.jar:git-Spigot-1503de9-53d3ac0]
            at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_181]
            at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_181]
            at net.minecraft.server.v1_13_R1.SystemUtils.a(SourceFile:198) [spigot.jar:git-Spigot-1503de9-53d3ac0]
            at net.minecraft.server.v1_13_R1.MinecraftServer.w(MinecraftServer.java:884) [spigot.jar:git-Spigot-1503de9-53d3ac0]
            at net.minecraft.server.v1_13_R1.DedicatedServer.w(DedicatedServer.java:411) [spigot.jar:git-Spigot-1503de9-53d3ac0]
            at net.minecraft.server.v1_13_R1.MinecraftServer.v(MinecraftServer.java:819) [spigot.jar:git-Spigot-1503de9-53d3ac0]
            at net.minecraft.server.v1_13_R1.MinecraftServer.run(MinecraftServer.java:717) [spigot.jar:git-Spigot-1503de9-53d3ac0]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_181]
    Caused by: java.lang.NoClassDefFoundError: org/jsoup/Jsoup
            at com.gmai.mcmogaming.advertisementquietdayz.Webscrapper.start(Webscrapper.java:31) ~[?:?]
            at com.gmai.mcmogaming.advertisementquietdayz.CommandManager.onCommand(CommandManager.java:21) ~[?:?]
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot.jar:git-Spigot-1503de9-53d3ac0]
            ... 15 more
    Caused by: java.lang.ClassNotFoundException: org.jsoup.Jsoup
            at java.net.URLClassLoader.findClass(Unknown Source) ~[?:1.8.0_181]
            at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:154) ~[spigot.jar:git-Spigot-1503de9-53d3ac0]
            at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:100) ~[spigot.jar:git-Spigot-1503de9-53d3ac0]
            at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_181]
            at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_181]
            at com.gmai.mcmogaming.advertisementquietdayz.Webscrapper.start(Webscrapper.java:31) ~[?:?]
            at com.gmai.mcmogaming.advertisementquietdayz.CommandManager.onCommand(CommandManager.java:21) ~[?:?]
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot.jar:git-Spigot-1503de9-53d3ac0]
            ... 15 more
    Thank you for reading this boring question. I appreciate any help or guidance that I can get.
     
    #1 Mcmogaming, Aug 11, 2018
    Last edited: Aug 11, 2018
  2. I'm not that experienced with maven myself
    but I always got it working for my projects somehow.

    Try adding the following to your poom.xml
    (before </project> ):

    Code (Text):
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>1.6</version>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>shade</goal>
                </goals>
                <configuration>
                  <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                      <mainClass>com.group.id.Launcher1</mainClass>
                    </transformer>
                  </transformers>
                </configuration>
              </execution>
            </executions>
          </plugin>    
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
          </plugin>
        </plugins>
      </build>
    For me this always did the job, hope it helps you aswell.
     
  3. Mas

    Mas

    You don't need the majority of that, this would work fine:
    Code (XML):
    <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.1.1</version>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>shade</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
    </plugins>
    Also you were using a way outdated version of the shade plugin in that snippet.
     
    • Agree Agree x 1
  4. You should also consider relocating jsoup so that other plugins using the same library don't have collisions
    Code (Text):
    <plugin>
        <configuration>
            <relocations>
                 <relocation>
                      <pattern>org.jsoup</pattern>
                      <shadedPattern>mcmogaming.org.jsoup</shadedPattern>
                </relocation>
            </relocations>
        </configuration>
    </plugin>
     
    #4 AuroraLS3, Aug 11, 2018
    Last edited: Aug 11, 2018
    • Like Like x 2