Skip to content

Instantly share code, notes, and snippets.

@TW2
Last active April 28, 2020 04:41
Show Gist options
  • Save TW2/13dcd44bc8bdd6784032986a307bdc59 to your computer and use it in GitHub Desktop.
Save TW2/13dcd44bc8bdd6784032986a307bdc59 to your computer and use it in GitHub Desktop.
A plugin system with maven and Java 14
package org.wingate.demomodel;
public interface IDemoModel {
public String getName();
}
<?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>org.wingate</groupId>
<artifactId>DemoModel</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>14</maven.compiler.source>
<maven.compiler.target>14</maven.compiler.target>
</properties>
</project>
package org.wingate.demoapp;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.wingate.demomodel.IDemoModel;
public class Main {
public static void main(String[] args) {
List<IDemoModel> pluginsAB = new ArrayList<>();
// On crée une instance du gestionnaire
PluginsHandler ph = new PluginsHandler();
// On charge les fichiers par l'intermédiare d'un dossier
ph.load(new File("D:\\Dev\\Java\\NB-Demo\\Plugins"));
// On récupère les plugins de tous les sortes, dans ce dossier
Map<Object, String> map = ph.getPlugins();
// On cherche et on affiche les noms de plugin ayant pour modèle 'IDemoModel'
for(Map.Entry<Object, String> entry : map.entrySet()){
System.out.println("ENTRY : " + entry.getKey() + "; " + entry.getValue());
if(entry.getValue().contains(IDemoModel.class.getName())){
IDemoModel test = IDemoModel.class.cast(entry.getKey());
System.out.println("TEST (1) " + (test == null ? "fail" : "OK"));
System.out.println("TEST (2) " + (test == null ? "fail" : test.getName()));
pluginsAB.add(test);
System.out.println("NB TESTS : " + pluginsAB.size());
}
}
}
package org.wingate.demoplugina;
import org.wingate.demomodel.IDemoModel;
public class PluginA implements IDemoModel {
public PluginA() {
}
@Override
public String getName() {
return "I am the plugin A!";
}
}
<?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>org.wingate</groupId>
<artifactId>DemoPluginA</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>14</maven.compiler.source>
<maven.compiler.target>14</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.wingate</groupId>
<artifactId>DemoModel</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
package org.wingate.demopluginb;
import org.wingate.demomodel.IDemoModel;
public class PluginB implements IDemoModel {
public PluginB() {
}
@Override
public String getName() {
return "I am the plugin B!";
}
}
package org.wingate.demoapp;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
public class PluginsHandler {
private final Map<Object, String> plugins = new HashMap<>();
public PluginsHandler() {
}
/**
* Load one or more plugins
* @param file a file or a folder
*/
public void load(File file){
File[] files = file.isDirectory() == true ? file.listFiles() : new File[]{ file };
URLClassLoader loader; // Pour charger le .jar en mémoire
String tmp; // Pour la comparaison de chaines
Enumeration enumeration; // Pour le contenu de l'archive jar
Class tmpClass; // Pour déterminer quelles sont les interfaces implémentées
for(File f : files){
try{
URL u = f.toURI().toURL();
//On crée un nouveau URLClassLoader pour charger
// le jar qui se trouve en dehors du CLASSPATH
loader = new URLClassLoader(new URL[] {u});
// On charge le jar en mémoire
JarFile jar = new JarFile(f.getAbsolutePath());
// On récupère le contenu du jar
enumeration = jar.entries();
while(enumeration.hasMoreElements()){
tmp = enumeration.nextElement().toString();
// On vérifie que le fichier courant est un .class
// (et pas un fichier d'informations du jar )
if(tmp.length() > 6 && tmp.substring(tmp.length()-6).compareTo(".class") == 0) {
tmp = tmp.substring(0,tmp.length()-6);
tmp = tmp.replaceAll("/",".");
tmpClass = Class.forName(tmp ,true, loader);
for(int i = 0; i < tmpClass.getInterfaces().length; i++){
try{
Constructor ct = tmpClass.getDeclaredConstructor();
Object obj = ct.newInstance();
plugins.put(obj, tmpClass.getInterfaces()[i].toString());
}catch(NoSuchMethodException | SecurityException | InstantiationException |
IllegalAccessException | IllegalArgumentException | InvocationTargetException ex){
Logger.getLogger(PluginsHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}catch(IOException | ClassNotFoundException ex){
}
}
}
public Map<Object, String> getPlugins() {
return plugins;
}
}
<?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>org.wingate</groupId>
<artifactId>DemoApp</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>14</maven.compiler.source>
<maven.compiler.target>14</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.wingate</groupId>
<artifactId>DemoModel</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
<?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>org.wingate</groupId>
<artifactId>DemoPluginB</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>14</maven.compiler.source>
<maven.compiler.target>14</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.wingate</groupId>
<artifactId>DemoModel</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment