Hiho,
also ich habe mich sehr für pluginartige Programme interessiert und dank einiger Beiträge hier im Forum bereits folgendes auf die Beine gestellt und bin dabei auf ein Problem gestoßen, welches ich weiter unten erläutere:
Eclipse-Projekt: SimplePluginLoader
Class: de.d4rkY89.plugin.exception.LoadPluginException
Interface: de.d4rkY89.plugin.interfaces.IPlugin
Class: de.d4rky89.plugin.loader.PluginLoader
Class: de.d4rky89.plugin.tools.JarFileFilter
So das waren die Klassen soweit zum "Hauptprogramm"
Jetzt habe ich noch 2 Projekte, die als Plugins dienen:
Eclipse-Projekt: HelloWorldPlugin
Class: de.d4rky89.plugin.HelloWorld
Eclipse-Projekt TestPlugin
Class: de.d4rky89.plugin.TestPlugin
So. Und im TestPlugin liegt mein Problem. Ich kann mir zwar das Objekt von der HelloWorld-Instanz mit "PluginLoader.PLUGIN_LOADER.getPluginForClassName("de.d4rky89.plugin.HelloWorld");" holen, allerdings scheitert der darauf folgende TypeCast. Das Problem liegt wohl daran, dass sich die HelloWorld-Klasse nicht im Classpath befindet. Ich habe schon versucht das Programm mit folgenden Parametern zu starten, allerdings ohne Erfolg:
-cp "./plugins"
-cp "./plugins/*"
-cp "<absoluter Pfad zum Plugin-Ordner>"
-cp "<absoluter Pfad zum Plugin-Ordner>/*"
-cp "<absoluter Pfad zur HelloWorldPlugin.jar>"
Ich habe den kompletten SourceCode mal im Anhang hochgeladen.
Der Grund, wieso ich auf andere Plugins zugreifen möchte ist, dass ich später ein Hauptfenster habe, welches allerdings selber ein Plugin sein wird. Und dieses Fenster möchte ich später durch andere Plugins erweitern können. Vielleicht habt ihr ja hinsichtlich dessen, was ich eben erklärt habe ja sogar eine alternative, bessere Lösung um von Plugin auf Plugin zugreifen zu können.
MfG d4rkY89
Edit:
Die 2 Plugins befinden sich übrigens schon im Plugin-Order vom SimplePluginLoader-Projekt. Ihr müsst sie also nicht selber noch als Jar packen und im Ordner ablegen.
also ich habe mich sehr für pluginartige Programme interessiert und dank einiger Beiträge hier im Forum bereits folgendes auf die Beine gestellt und bin dabei auf ein Problem gestoßen, welches ich weiter unten erläutere:
Eclipse-Projekt: SimplePluginLoader
Class: de.d4rkY89.plugin.exception.LoadPluginException
Java:
package de.d4rky89.plugin.exception;
@SuppressWarnings("serial")
public class LoadPluginException extends Exception {
public LoadPluginException (String message) {
super(message);
}
public LoadPluginException() {
super();
}
}
Interface: de.d4rkY89.plugin.interfaces.IPlugin
Java:
package de.d4rky89.plugin.interfaces;
public interface IPlugin {
void start();
void stop();
}
Class: de.d4rky89.plugin.loader.PluginLoader
Java:
package de.d4rky89.plugin.loader;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.LinkedList;
import java.util.List;
import de.d4rky89.plugin.exception.LoadPluginException;
import de.d4rky89.plugin.interfaces.IPlugin;
import de.d4rky89.plugin.tools.JarFileFilter;
public class PluginLoader {
public static PluginLoader PLUGIN_LOADER;
static {
PLUGIN_LOADER = new PluginLoader();
}
public static void main(String[] args) {
PLUGIN_LOADER.loadPlugins();
PLUGIN_LOADER.startPlugins();
PLUGIN_LOADER.stopPlugins();
}
private List<IPlugin> plugins = null;
private PluginLoader() {
plugins = new LinkedList<IPlugin>();
}
public IPlugin getPluginForClassName(String className) {
for (IPlugin item : plugins) {
if (item.getClass().getName().equals(className))
return item;
}
return null;
}
private void loadPlugins() {
File pluginDir = new File("plugins");
if (!pluginDir.exists())
return;
File[] pluginJars = pluginDir.listFiles(new JarFileFilter());
System.out.println("Start loading plugins.");
for (File item : pluginJars) {
System.out.printf("Loading Plugins from %s.\n", item.getAbsolutePath());
try {
URL pluginURL = item.toURI().toURL();
URLClassLoader loader = new URLClassLoader(
new URL[] { pluginURL });
loadPlugin(loader);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LoadPluginException e) {
e.printStackTrace();
}
}
System.out.println("Finished loading plugins.");
}
private void loadPlugin(URLClassLoader loader) throws IOException, LoadPluginException {
String urlPath = "META-INF/services/" + IPlugin.class.getPackage().getName() + ".IPlugin";
URL serviceURL = loader.findResource(urlPath);
if (serviceURL == null)
throw new LoadPluginException(String.format("Missing \"%s\"", urlPath));
BufferedReader br = new BufferedReader(new InputStreamReader(
serviceURL.openStream()));
List<IPlugin> containingPlugins = new LinkedList<IPlugin>();
String pluginClassName = null;
try {
while ((pluginClassName = br.readLine()) != null) {
System.out.println("Loading Plugin Class " + pluginClassName);
Class<?> plugin = loader.loadClass(pluginClassName);
IPlugin iPlugin = (IPlugin) plugin.newInstance();
containingPlugins.add(iPlugin);
}
plugins.addAll(containingPlugins);
} catch (ClassNotFoundException e) {
throw new LoadPluginException("Plugin class not found: " + pluginClassName);
} catch (InstantiationException e) {
throw new LoadPluginException("Failed to create a new instance of class " + pluginClassName);
} catch (IllegalAccessException e) {
throw new LoadPluginException("Failed to create a new instance of class " + pluginClassName);
}
}
private void startPlugins() {
System.out.println("Starting plugins");
for (IPlugin item : plugins)
item.start();
}
private void stopPlugins() {
System.out.println("Stopping plugins");
for (IPlugin item : plugins)
item.stop();
}
}
Class: de.d4rky89.plugin.tools.JarFileFilter
Java:
package de.d4rky89.plugin.tools;
import java.io.File;
import java.io.FileFilter;
public class JarFileFilter implements FileFilter {
@Override
public boolean accept(File path) {
if (!path.getName().endsWith(".jar") || path.isDirectory())
return false;
return true;
}
}
So das waren die Klassen soweit zum "Hauptprogramm"
Jetzt habe ich noch 2 Projekte, die als Plugins dienen:
Eclipse-Projekt: HelloWorldPlugin
Class: de.d4rky89.plugin.HelloWorld
Java:
package de.d4rky89.plugin;
import de.d4rky89.plugin.interfaces.IPlugin;
public class HelloWorld implements IPlugin {
@Override
public void start() {
println("Hello World!");
}
@Override
public void stop() {
println("See Ya World!");
}
public void println(String str) {
System.out.println(str);
}
}
Eclipse-Projekt TestPlugin
Class: de.d4rky89.plugin.TestPlugin
Java:
package de.d4rky89.plugin;
import de.d4rky89.plugin.HelloWorld;
import de.d4rky89.plugin.interfaces.IPlugin;
import de.d4rky89.plugin.loader.PluginLoader;
public class TestPlugin implements IPlugin {
@Override
public void start() {
System.out.println("TestPlugin starting");
IPlugin plugin = PluginLoader.PLUGIN_LOADER.getPluginForClassName("de.d4rky89.plugin.HelloWorld");
HelloWorld helloWorld = (HelloWorld) plugin;
helloWorld.println("This is SPARTA******");
}
@Override
public void stop() {
}
}
So. Und im TestPlugin liegt mein Problem. Ich kann mir zwar das Objekt von der HelloWorld-Instanz mit "PluginLoader.PLUGIN_LOADER.getPluginForClassName("de.d4rky89.plugin.HelloWorld");" holen, allerdings scheitert der darauf folgende TypeCast. Das Problem liegt wohl daran, dass sich die HelloWorld-Klasse nicht im Classpath befindet. Ich habe schon versucht das Programm mit folgenden Parametern zu starten, allerdings ohne Erfolg:
-cp "./plugins"
-cp "./plugins/*"
-cp "<absoluter Pfad zum Plugin-Ordner>"
-cp "<absoluter Pfad zum Plugin-Ordner>/*"
-cp "<absoluter Pfad zur HelloWorldPlugin.jar>"
Ich habe den kompletten SourceCode mal im Anhang hochgeladen.
Der Grund, wieso ich auf andere Plugins zugreifen möchte ist, dass ich später ein Hauptfenster habe, welches allerdings selber ein Plugin sein wird. Und dieses Fenster möchte ich später durch andere Plugins erweitern können. Vielleicht habt ihr ja hinsichtlich dessen, was ich eben erklärt habe ja sogar eine alternative, bessere Lösung um von Plugin auf Plugin zugreifen zu können.
MfG d4rkY89
Edit:
Die 2 Plugins befinden sich übrigens schon im Plugin-Order vom SimplePluginLoader-Projekt. Ihr müsst sie also nicht selber noch als Jar packen und im Ordner ablegen.
Anhänge
Zuletzt bearbeitet: