Håller på och bygger ett system för plugins och har stött på lite problem. Hittade tips på nätet att jag behövde en egen classloader och byggde denna: Om jag tar bort konstruktorn från TestPlugin klassen funkar allt klockrent! Tycker dock inte att det är en bra lösning, pluginen ska ju kunna köras också som egen application i vissa fall! Nåja, det får lösasej senare. det är inte så att du har en privat konstruktor som inte tar några parametrar alternativt bara såna konstruktorer som tar parametrar? Så var det, min konstruktor tog paramateren PluginHost. Men kom på att pluginen kasnke inte behöver en konstruktor.. Satte till en metoden setPluginHost istället som gör samma som konstruktorn. Om jag vill ladda min plugin från en anna katalog, hur gör jag det? Det om dom ligger i classpathen men man ska kunna ställa in i programmet vilken katalog dom laddas från. En kanske inte så bra lösning, men den enklaste. kopiera bara in dem i classpathen och ladda de sen... Löste det, på ett annat sätt. Klassen TestPlugin laddas mha PluginLoader och det fungerar bra. När jag i TestPlugin försöker ladda en lyckas det inte. Bilden finns i samma jar-fil som pluginen och hämtas enligt Egen ClassLoader
<code:java>
package homestudio.plugin;
import java.io.*;
public class PluginLoader extends ClassLoader {
private static PluginLoader loader = new PluginLoader();
public static Plugin loadPlugin( String name )
throws ClassNotFoundException,
InstantiationException,
IllegalAccessException{
// här blir det fel, se nedan.
Plugin plugin = (Plugin) ( loader.loadClass( name, true ) ).newInstance();
return plugin;
}
}
</code>
Plugin är ett interface som min testplugin implementerar
<code:java>
/**
* Defines the interface for a plugin to HomeStudio.
*
* @version 0.1 07/13/05
* @author Tom Granqvist
*/
public interface Plugin {
// Returns the plugins UI-component.
public JPanel getPluginUI( );
// Returns all info about the plugin
public String getPluginInfo( );
}
</code>
I huvudkoden försöker jag kalla på koden: Plugin p = PluginLoader.loadPlugin( "TestPlugin" ); men får ett InstantiationException på rad 15 i PluginLoader klassen. Vad gör jag för fel?Sv: Egen ClassLoader
Sv:Egen ClassLoader
Sv: Egen ClassLoader
Egen ClassLoader, följdfråga
Sv: Egen ClassLoader, följdfråga
Sv:Egen ClassLoader, följdfråga
public class PluginLoader{
/**
* Loads a plugin from a JAR-file.
*
* Extracts the Plugin-Class entry from the specified JAR file and
* loads the associated class.
*
* @param file the JAR-file to get plugin from.
*
* @return the loaded plugin.
*/
public Plugin loadPluginFromFile( String file )
throws PluginLoadingException{
Plugin plugin = null;
String cls = "";
try{
URL url = new URL( "file:" + file );
String jar = "jar:file:" + file + "!/";
JarURLConnection uc =
(JarURLConnection) new URL( jar ).openConnection();
cls = uc.getMainAttributes().getValue( "Plugin-Class");
URLClassLoader ucl = new URLClassLoader( new URL[]{ url } );
plugin = (Plugin)ucl.loadClass( cls ).newInstance();
} catch ( MalformedURLException mux ) {
throw new PluginLoadingException( "Error finding file "+file, mux );
} catch ( IOException iox ) {
throw new PluginLoadingException( "Error accessing manifest", iox );
} catch ( ClassNotFoundException cfx) {
throw new PluginLoadingException( "Class "+ cls +" not found", cfx );
} catch( InstantiationException ix ) {
throw new PluginLoadingException( "Class "+ cls +" not a plugin!", ix );
} catch ( IllegalAccessException iax ) {
throw new PluginLoadingException( "Access not allowed", iax );
}
return plugin;
}
}
Skickar in namnet på en jar-fil och använder en URLClassLoader för att ladda klassen som jar:ens attribut Plugin-Class pekar på. Funkar med sökväg och allt :)
Problem med getResource()
//anna kod här...
Icon i = createImageIcon( "bild.gif" );
JButton button = new JButton( "Test", i );
// ...och här.
private ImageIcon createImageIcon( String file ){
URL url = getClass().getClassLoader().getResource( "images/" + file );
if( url == null )
return null;
return new ImageIcon( url );
}
Om bild.gif finns i pluginens jar-fil hittas den inte, men om den finns i huvudprogrammets jar så fungerar det!
Jag har på känn att det har något med classpathen att göra, rätta mej om jag har fel. Lite skumt om man inte ha egna "resurser" i pluginens jar.