1.15.2 Problem about importation of external libraries

Discussion in 'Spigot Plugin Development' started by Liouss, Mar 28, 2020.

  1. Hello,

    I'm learning the spigot plugin dev and I've got a problem. First you need to know I'm using Eclipse on Windows, without Maeven or anything else.

    Me and a friend created a library with many functionalities that we would like to use in our plugins. So we exported it as a .jar and we created a new project where we tryied to import it.
    The problem is that when I start my server and I use a static function from my library in the onEnable() I get a noClassDefFounfException (I uploaded a screen).

    What I already tryied :
    - I created a "lib" folder in my project where I put my library and then I try to add it to the classpath with Properties>Java Build Path>Add Jars... and check the checkbox of my library in order and exports by this way the functions I use from my library are recognized by Eclipse's autocompletion but it's apparently not by spigot when I export the project.
    - I just add external jar from somewhere on my computer

    In both situations I checked the .classpath file and it had the good path to find the library.


    Me and my friend are really stuck on this so it would be really nice if you give us a solution (I pref to not use Maeven if possible because we already built the projet on github etc.. if possible
     

    Attached Files:

  2. And sorry for my poor english, it's not my native language and I'm doing what I can ^^
     
  3. Choco

    Moderator

    Of course there will be a NCDFE. The class won't exist at runtime. You have two options:
    1. Download the dependency from some server at runtime (asynchronously) and load the classes with your plugin's class loader (more complicated)
    2. Shade your dependency and relocate it using Maven's Shade plugin
    I guess technically if you want a third option, have your dependency be a plugin and run it on the server to have it loaded by Bukkit instead but that's obviously not ideal.
     
  4. Oh thanks. I'll try the third option as it seems to be the simpliest at the moment. But may I ask why the class won't exist at runtime ? (I'm new to Java so I tryo to understand)
     
  5. Choco

    Moderator

    The way a CraftBukkit server works is it filters through the plugins folder to find any .jar files. It goes through all the compiled Java code (class files) in said jars and loads them up into the same environment running the server. The JVM (Java Virtual Machine). These classes are loaded by a class loader (all Java programs are) and all plugins are loaded using Bukkit's classloader - and this is the reason why plugins can use one another's code if loaded on the server; because they're in the same environment. The reason why the classes YOU'RE trying to use are not present is because the server does not recognize it as a plugin and has no reason to load it (or perhaps it's just not present at all). Unfortunately, Java isn't magic and doesn't understand when we try to use things that aren't there. It won't download dependencies for us, we have to do that :)

    In fact, if you look at the %appdata%/.minecraft folder (where Minecraft is installed), you'll see a libraries folder. Minecraft uses libraries such as Guava, Apache Commons, LWJGL, etc. and these all have to be present when you run the game. So they download the dependencies when the game is installed and load the dependencies on the Minecraft classpath. If, for instance, "Guava" was not present in the client dependencies, the game would crash because its classes were never loaded. This same ideology is applied on the server.

    Massive oversimplification but I hope that makes some sort of sense.

    TL;DR: Classes aren't on the server, server can't load what doesn't exist, your plugin go boom because Java doesn't know what you're trying to do.
     
  6. ok, thank you very much for the explaination ! Have a nice day
     
    • Friendly Friendly x 1