Ich vermute mal du meinst das generell. Vielleicht zuerst der Hinweis, dass das aus verschiedenen Gründen nicht ganz so sauber ist wie es vielleicht auf den ersten Blick aussieht. Wenn dich die Details dazu interessieren, dann guck dir mal an, wie die JVM Klassen läd und entläd.
Zu deiner Frage: Das ganze geht mit ClassLoader (
https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html) das ist eine Komponente der JVM, die sich um das Laden von Klassen kümmert, du kannst solche ClassLoader selbst zur Laufzeit erzeugen und der JVM bekannt machen. Damit kannst du dann dynamisch zur Laufzeit Code nachladen.
Google hat so viele Ergebnisse dazu, dass ich dir einfach empfehlen würde nach "java load jar at runtime" zu suchen:
https://www.google.de/search?q=java+load+jar+at+runtime
Beispielswiese diese hier:
Je nach dem wie du dein Pluginsystem aufbaust gibt es ein paar Unterschiede in den Details. Bukkit erwartet beispielsweise einfach vom Pluginentwickler, dass dieser den Namen der Pluginklasse angibt, diese suchst du dir dann in deinem Pluginloader raus und bekommst dadurch dann auch die anderen Klassen.
Man sollte auch dazu sagen, dass es für das dynamische Laden von Modulen ein komplettes Ökosystem von verschiedenen Systeme gibt, die so etwas auf einem sehr hohen Level können. Das Ganze wird aber vor allem in Enterpriseanwendungen genutzt und ist unglaublich kompliziert. Stichworte hierfür ist OSGi sowie Jigsaw was in Java 9 Einzug nehmen wird. Sofern du also damit zufrieden bist, dass du Plugin laden aber ohne Neustart nicht entladen kannst, würde ich die oben genannten Links zu rate ziehen
Bau dir auf jeden Fall eine minimale Testumgebung um erstmal mit dem Konzept vertraut zu werden. Im Grunde funktioniert das System dann aber genau wie die Bukkit Plugins. Also Plugininterface definieren und von einzelnen Plugins implementieren lassen.